zsh-workers
 help / color / mirror / code / Atom feed
* _complete_debug crashes in zsh_directory_name
@ 2011-08-03  3:26 Mikael Magnusson
  2011-08-03  9:10 ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Mikael Magnusson @ 2011-08-03  3:26 UTC (permalink / raw)
  To: zsh workers

Any ideas? It doesn't crash if I don't have the zsh_directory_name function.

_complete_debug:9: failed to close file descriptor 3: bad file descriptor
/usr/local/bin/zsh:1: failed to close file descriptor 3: bad file descriptor

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff5b74d8b in comp_wrapper (prog=0x804550, w=0x0,
    name=0x7ffff7f51750 "zsh_directory_name") at complete.c:1434
1434		    if ((m & 1) && ((*pp)->node.flags & PM_UNSET))
(gdb) bt
#0  0x00007ffff5b74d8b in comp_wrapper (prog=0x804550, w=0x0,
    name=0x7ffff7f51750 "zsh_directory_name") at complete.c:1434
#1  0x000000000043025b in runshfunc (prog=0x804550, wrap=0x7ffff5d92da0,
    name=0x7ffff7f51750 "zsh_directory_name") at exec.c:4651
#2  0x000000000042ffd3 in doshfunc (shfunc=0x804590,
doshargs=0x7ffff7f516b8, noreturnval=1)
    at exec.c:4560
#3  0x000000000049294b in subst_string_by_func (func=0x804590,
arg1=0x4a3c3b "d",
    orig=0x6d1970 "/home/mikachu") at utils.c:3233
#4  0x00000000004929ca in subst_string_by_hook (name=0x4a3c3d
"zsh_directory_name",
    arg1=0x4a3c3b "d", orig=0x6d1970 "/home/mikachu") at utils.c:3257
#5  0x000000000048db98 in finddir (s=0x6d0070 "/home/mikachu") at utils.c:931
#6  0x0000000000479a18 in promptpath (p=0x6d0070 "/home/mikachu",
npath=0, tilde=1)
    at prompt.c:124
#7  0x000000000047a518 in putpromptchar (doprint=1, endchar=0,
txtchangep=0x7ffff5fe6de0)
    at prompt.c:409
#8  0x000000000047c815 in prompttrunc (arg=40, truncchar=60,
doprint=1, endchar=0,
    txtchangep=0x7ffff5fe6de0) at prompt.c:1157
#9  0x000000000047b089 in putpromptchar (doprint=1, endchar=0,
txtchangep=0x7ffff5fe6de0)
    at prompt.c:546
#10 0x0000000000479cbf in promptexpand (
    s=0x6fb7c0 "%f%b%u%F{10}{%F{86}%D{%T}%F{2}|%40<...<%F{11}%~%<<%(3V.%F{13}/%3v%(4V.%F{7}%B:%F{9}%4v%b.).)%F{10}}%(2L.%{\033[1;%vm%}%(3L.(%L).).%{\033[0;%vm%})%(9V.(%9v).)%#%f%b
",
    ns=1, rs=0x0, Rs=0x0, txtchangep=0x7ffff5fe6de0) at prompt.c:212
#11 0x00007ffff5db8103 in reexpandprompt () at zle_main.c:1767
#12 0x00007ffff5dc0ca9 in zrefresh () at zle_refresh.c:1122
#13 0x00007ffff5db8637 in zle_main_entry (cmd=5, ap=0x7fffffffc990) at
zle_main.c:1890
#14 0x0000000000445847 in zleentry (cmd=5) at init.c:1374
#15 0x000000000047f901 in dotrapargs (sig=0, sigtr=0x7fffffffcb1c,
sigfn=0x7ddfb0)
    at signals.c:1262
#16 0x000000000047f413 in endtrapscope () at signals.c:1008
#17 0x0000000000430112 in doshfunc (shfunc=0x7d2570, doshargs=0x0,
noreturnval=0)
    at exec.c:4603
#18 0x00007ffff5b77936 in callcompfunc (s=0x7ffff7f6b660 "",
fn=0x79d080 "_complete_debug")
    at compcore.c:838
#19 0x00007ffff5b78211 in makecomplist (s=0x7ffff7f6b660 "", incmd=1, lst=0)
    at compcore.c:989
#20 0x00007ffff5b75e7f in do_completion (dummy=0x7ffff5fe6468,
dat=0x7fffffffced0)
    at compcore.c:349
#21 0x0000000000459593 in runhookdef (h=0x7ffff5fe6468,
d=0x7fffffffced0) at module.c:995
#22 0x00007ffff5dcdcf6 in docompletion (s=0x827ea0 "", lst=0, incmd=1)
at zle_tricky.c:2165
#23 0x00007ffff5dc95bc in docomplete (lst=0) at zle_tricky.c:849
#24 0x00007ffff5dc7ac6 in completeword (args=0x7ffff5fe69f0) at zle_tricky.c:232
#25 0x00007ffff5dc79a7 in completecall (args=0x7ffff5fe69f0) at zle_tricky.c:208
#26 0x00007ffff5db66f7 in execzlefunc (func=0x79d0a0,
args=0x7ffff5fe69f0, set_bindk=0)
    at zle_main.c:1311
#27 0x00007ffff5db5ba1 in zlecore () at zle_main.c:1058
#28 0x00007ffff5db62b5 in zleread (lp=0x6c4ab8, rp=0x6c49f8, flags=7, context=0)
    at zle_main.c:1219
#29 0x00007ffff5db85c2 in zle_main_entry (cmd=1, ap=0x7fffffffd350) at
zle_main.c:1874
#30 0x0000000000445847 in zleentry (cmd=1) at init.c:1374
#31 0x000000000044629f in inputline () at input.c:281
#32 0x0000000000446116 in ingetc () at input.c:217
#33 0x000000000043b912 in ihgetc () at hist.c:279
#34 0x000000000044e2ba in gettok () at lex.c:717
#35 0x000000000044da6b in zshlex () at lex.c:395
#36 0x000000000046b03b in parse_event () at parse.c:451
#37 0x0000000000442bcd in loop (toplevel=1, justonce=0) at init.c:132
#38 0x0000000000445d16 in zsh_main (argc=1, argv=0x7fffffffd738) at init.c:1528
#39 0x0000000000410784 in main (argc=1, argv=0x7fffffffd738) at ./main.c:93


-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: _complete_debug crashes in zsh_directory_name
  2011-08-03  3:26 _complete_debug crashes in zsh_directory_name Mikael Magnusson
@ 2011-08-03  9:10 ` Peter Stephenson
  2011-08-03 14:53   ` Mikael Magnusson
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2011-08-03  9:10 UTC (permalink / raw)
  To: zsh workers

On Wed, 3 Aug 2011 05:26:53 +0200
Mikael Magnusson <mikachu@gmail.com> wrote:
> Any ideas? It doesn't crash if I don't have the zsh_directory_name function.

This seems to depend on your set-up, so there's nothing I can do without
more clues.  I'm wondering if the wrapper function is getting called at
multiple levels in a way that's confusing it, but that's pure guess.
It appears to have something to do with some prompt but simply putting
%~ in all my prompts and letting that call the zsh_directory_name hooks
didn't seem to do anything.

While we're here, however, we can do a lot better with _complete_debug.
For a start, it could use a more standard syntax.  Then it can use the
facility to generate its own file descriptor, so it doesn't need to
trash anyone else's (which is what the new error is from).  Then it can
use the try/always syntax to ensure the fd gets tidied up reliably.

I think this is still working but completion depends on side-effects in
unexpected ways so I may have missed something...

Index: Completion/Base/Widget/_complete_debug
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Base/Widget/_complete_debug,v
retrieving revision 1.6
diff -p -u -r1.6 _complete_debug
--- Completion/Base/Widget/_complete_debug	19 Jun 2007 09:28:07 -0000	1.6
+++ Completion/Base/Widget/_complete_debug	3 Aug 2011 09:07:18 -0000
@@ -6,21 +6,27 @@ eval "$_comp_setup"
 local tmp=${TMPPREFIX}${$}${words[1]:t}$[++_debug_count]
 local pager w="${(qq)words}"
 
-exec 3>&-	# Too bad if somebody else is using it ...
-[[ -t 2 ]] && { exec 3>&2 2>| $tmp ; trap 'exec 2>&3 3>&-' EXIT INT }
+integer debug_fd=-1
+{
+  if [[ -t 2 ]]; then
+    exec {debug_fd}>&2 2>| $tmp
+  fi
 
-setopt xtrace
-: $ZSH_NAME $ZSH_VERSION
-${1:-_main_complete}
-integer ret=$?
-unsetopt xtrace
+  setopt xtrace
+  : $ZSH_NAME $ZSH_VERSION
+  ${1:-_main_complete}
+  integer ret=$?
+  unsetopt xtrace
 
-[[ -t 3 ]] && {
+  if (( debug_fd != -1 )); then
     zstyle -s ':completion:complete-debug::::' pager pager
     print -sR "${pager:-${PAGER:-${VISUAL:-${EDITOR:-more}}}} ${(q)tmp} ;: $w"
     _message -r "Trace output left in $tmp (up-history to view)"
-    [[ $compstate[nmatches] -le 1 && $compstate[list] != *force* ]] &&
+    if [[ $compstate[nmatches] -le 1 && $compstate[list] != *force* ]]; then
         compstate[list]='list force messages'
+    fi
+  fi
+} always {
+  (( debug_fd != -1 )) && exec 2>&$debug_fd {debug_fd}>&-
 }
-
 return ret

-- 
Peter Stephenson <pws@csr.com>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: _complete_debug crashes in zsh_directory_name
  2011-08-03  9:10 ` Peter Stephenson
@ 2011-08-03 14:53   ` Mikael Magnusson
  2011-08-03 15:39     ` Peter Stephenson
  2011-08-03 16:00     ` Bart Schaefer
  0 siblings, 2 replies; 5+ messages in thread
From: Mikael Magnusson @ 2011-08-03 14:53 UTC (permalink / raw)
  To: zsh workers

On 3 August 2011 11:10, Peter Stephenson <Peter.Stephenson@csr.com> wrote:
> On Wed, 3 Aug 2011 05:26:53 +0200
> Mikael Magnusson <mikachu@gmail.com> wrote:
>> Any ideas? It doesn't crash if I don't have the zsh_directory_name function.
>
> This seems to depend on your set-up, so there's nothing I can do without
> more clues.  I'm wondering if the wrapper function is getting called at
> multiple levels in a way that's confusing it, but that's pure guess.
> It appears to have something to do with some prompt but simply putting
> %~ in all my prompts and letting that call the zsh_directory_name hooks
> didn't seem to do anything.

This is enough to reproduce the crash for me:
% zsh -f
localhost% PS1=%~
~autoload -U compinit
~compinit -D
~zsh_directory_name() { }
~<press C-x?>
_complete_debug:9: failed to close file descriptor 3: bad file descriptor
zsh:1: failed to close file descriptor 3: bad file descriptor
zsh: segmentation fault  zsh -f

> While we're here, however, we can do a lot better with _complete_debug.

With this patch, the crash is no longer happens here.

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: _complete_debug crashes in zsh_directory_name
  2011-08-03 14:53   ` Mikael Magnusson
@ 2011-08-03 15:39     ` Peter Stephenson
  2011-08-03 16:00     ` Bart Schaefer
  1 sibling, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2011-08-03 15:39 UTC (permalink / raw)
  To: zsh workers

On Wed, 3 Aug 2011 16:53:40 +0200
Mikael Magnusson <mikachu@gmail.com> wrote:
> On 3 August 2011 11:10, Peter Stephenson <Peter.Stephenson@csr.com> wrote:
> > On Wed, 3 Aug 2011 05:26:53 +0200
> > Mikael Magnusson <mikachu@gmail.com> wrote:
> >> Any ideas? It doesn't crash if I don't have the zsh_directory_name function.
> >
> > This seems to depend on your set-up, so there's nothing I can do without
> > more clues.  I'm wondering if the wrapper function is getting called at
> > multiple levels in a way that's confusing it, but that's pure guess.
> > It appears to have something to do with some prompt but simply putting
> > %~ in all my prompts and letting that call the zsh_directory_name hooks
> > didn't seem to do anything.
> 
> This is enough to reproduce the crash for me:
> % zsh -f
> localhost% PS1=%~
> ~autoload -U compinit
> ~compinit -D
> ~zsh_directory_name() { }
> ~<press C-x?>
> _complete_debug:9: failed to close file descriptor 3: bad file descriptor
> zsh:1: failed to close file descriptor 3: bad file descriptor
> zsh: segmentation fault  zsh -f

I did manage to get this, though as it dumps me into the uncommented
completion code with it's well-known attitudes to code encapsulation and
variable modularity it's not very enlightening.

I wonder if we should simply be turning off completion nastiness for
hook functions, which are run isolated from the general function
environment.  This could just be working around a problem rather than
fixing it, but we'll probably never know.

Hmm... the tidied-up function doesn't use a trap, that may be
significant.  So turning it off for traps might be a good idea, too.
Having two nested levels of functions that aren't part of the normal
call sequence might have been the trigger.

I think the wrapper stuff is just to do magic things with completion
parameters on change of function level, isn't it?  I've never really got
my head round it.

Possibly this could be better done with use of sfcontext in the
completion code but, again, I don't suppose anyone's ever going to find
out.

Index: Src/signals.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/signals.c,v
retrieving revision 1.62
diff -p -u -r1.62 signals.c
--- Src/signals.c	15 Jun 2011 15:38:14 -0000	1.62
+++ Src/signals.c	3 Aug 2011 15:31:16 -0000
@@ -1184,7 +1184,7 @@ dotrapargs(int sig, int *sigtr, void *si
     traplocallevel = locallevel;
     runhookdef(BEFORETRAPHOOK, NULL);
     if (*sigtr & ZSIG_FUNC) {
-	int osc = sfcontext;
+	int osc = sfcontext, old_incompfunc = incompfunc;
 	HashNode hn = gettrapnode(sig, 0);
 
 	args = znewlinklist();
@@ -1210,8 +1210,10 @@ dotrapargs(int sig, int *sigtr, void *si
 	trapisfunc = isfunc = 1;
 
 	sfcontext = SFC_SIGNAL;
+	incompfunc = 0;
 	doshfunc((Shfunc)sigfn, args, 1);
 	sfcontext = osc;
+	incompfunc= old_incompfunc;
 	freelinklist(args, (FreeFunc) NULL);
 	zsfree(name);
     } else {
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.260
diff -p -u -r1.260 utils.c
--- Src/utils.c	25 Jul 2011 10:20:09 -0000	1.260
+++ Src/utils.c	3 Aug 2011 15:31:16 -0000
@@ -40,6 +40,11 @@ mod_export char *scriptname;     /* is s
 /**/
 mod_export char *scriptfilename;
 
+/* != 0 if we are in a new style completion function */
+
+/**/
+mod_export int incompfunc;
+
 #ifdef MULTIBYTE_SUPPORT
 struct widechar_array {
     wchar_t *chars;
@@ -1232,8 +1237,10 @@ callhookfunc(char *name, LinkList lnklst
 	 * to a list of jobs generated in a hook.
 	 */
     int osc = sfcontext, osm = stopmsg, stat = 1, ret = 0;
+    int old_incompfunc = incompfunc;
 
     sfcontext = SFC_HOOK;
+    incompfunc = 0;
 
     if ((shfunc = getshfunc(name))) {
 	ret = doshfunc(shfunc, lnklst, 1);
@@ -1262,6 +1269,7 @@ callhookfunc(char *name, LinkList lnklst
 
     sfcontext = osc;
     stopmsg = osm;
+    incompfunc = old_incompfunc;
 
     if (retval)
 	*retval = ret;
@@ -3216,7 +3224,7 @@ getshfunc(char *nam)
 char **
 subst_string_by_func(Shfunc func, char *arg1, char *orig)
 {
-    int osc = sfcontext, osm = stopmsg;
+    int osc = sfcontext, osm = stopmsg, old_incompfunc = incompfunc;
     LinkList l = newlinklist();
     char **ret;
 
@@ -3225,6 +3233,7 @@ subst_string_by_func(Shfunc func, char *
 	addlinknode(l, arg1);
     addlinknode(l, orig);
     sfcontext = SFC_SUBST;
+    incompfunc = 0;
 
     if (doshfunc(func, l, 1))
 	ret = NULL;
@@ -3233,6 +3242,7 @@ subst_string_by_func(Shfunc func, char *
 
     sfcontext = osc;
     stopmsg = osm;
+    incompfunc = old_incompfunc;
     return ret;
 }
 
Index: Src/Zle/zle_main.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_main.c,v
retrieving revision 1.129
diff -p -u -r1.129 zle_main.c
--- Src/Zle/zle_main.c	12 Jul 2011 08:37:11 -0000	1.129
+++ Src/Zle/zle_main.c	3 Aug 2011 15:31:16 -0000
@@ -53,11 +53,6 @@ mod_export int zlecs, zlell;
 /**/
 mod_export int incompctlfunc;
 
-/* != 0 if we are in a new style completion function */
-
-/**/
-mod_export int incompfunc;
-
 /* != 0 if completion module is loaded */
 
 /**/

-- 
Peter Stephenson <pws@csr.com>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: _complete_debug crashes in zsh_directory_name
  2011-08-03 14:53   ` Mikael Magnusson
  2011-08-03 15:39     ` Peter Stephenson
@ 2011-08-03 16:00     ` Bart Schaefer
  1 sibling, 0 replies; 5+ messages in thread
From: Bart Schaefer @ 2011-08-03 16:00 UTC (permalink / raw)
  To: Mikael Magnusson, zsh workers

On Aug 3,  4:53pm, Mikael Magnusson wrote:
} Subject: Re: _complete_debug crashes in zsh_directory_name
}
} This is enough to reproduce the crash for me:
} % zsh -f
} localhost% PS1=%~
} ~autoload -U compinit
} ~compinit -D
} ~zsh_directory_name() { }
} ~<press C-x?>
} _complete_debug:9: failed to close file descriptor 3: bad file descriptor
} zsh:1: failed to close file descriptor 3: bad file descriptor
} zsh: segmentation fault  zsh -f

Program received signal SIGSEGV, Segmentation fault.
0x080e32ee in comp_wrapper (prog=0x8673ec0, w=0x0, 
    name=0xb7ceb5a8 "zsh_directory_name")
    at ../../../zsh-4.0/Src/Zle/complete.c:1434
1434                if ((m & 1) && ((*pp)->node.flags & PM_UNSET))
(gdb) p m
$1 = 511
(gdb) p pp
$2 = (Param *) 0x8617a90
(gdb) p *pp
$3 = 0x0
(gdb) where
#0  0x080e32ee in comp_wrapper (prog=0x8673ec0, w=0x0, 
    name=0xb7ceb5a8 "zsh_directory_name")
    at ../../../zsh-4.0/Src/Zle/complete.c:1434
#1  0x08069848 in runshfunc (prog=0x8673ec0, wrap=0x8149e40, 
    name=0xb7ceb5a8 "zsh_directory_name") at ../../zsh-4.0/Src/exec.c:4648
#2  0x08069612 in doshfunc (shfunc=0x866f870, doshargs=0xb7ceb530, 
    noreturnval=1) at ../../zsh-4.0/Src/exec.c:4557
#3  0x080c3c85 in subst_string_by_func (func=0x866f870, arg1=0x813c39c "d", 
    orig=0x85f7e58 "/usr/src/local/zsh/zsh-4.0-build")
    at ../../zsh-4.0/Src/utils.c:3229
#4  0x080c3cf3 in subst_string_by_hook (name=0x813c39e "zsh_directory_name", 
    arg1=0x813c39c "d", orig=0x85f7e58 "/usr/src/local/zsh/zsh-4.0-build")
    at ../../zsh-4.0/Src/utils.c:3253
#5  0x080bf6bd in finddir (s=0x85f6638 "/usr/src/local/zsh/zsh-4.0-build")
    at ../../zsh-4.0/Src/utils.c:931
#6  0x080adb2d in promptpath (p=0x85f6638 "/usr/src/local/zsh/zsh-4.0-build", 
    npath=0, tilde=1) at ../../zsh-4.0/Src/prompt.c:124
#7  0x080ae56b in putpromptchar (doprint=1, endchar=0, txtchangep=0x81627c0)
    at ../../zsh-4.0/Src/prompt.c:409
#8  0x080add83 in promptexpand (s=0x863e5f0 "%~ ", ns=1, rs=0x0, Rs=0x0, 
    txtchangep=0x81627c0) at ../../zsh-4.0/Src/prompt.c:212
#9  0x08115f1d in reexpandprompt () at ../../../zsh-4.0/Src/Zle/zle_main.c:1767
#10 0x0811ca29 in zrefresh () at ../../../zsh-4.0/Src/Zle/zle_refresh.c:1109
#11 0x081161e6 in zle_main_entry (cmd=5, 
    ap=0xbfede644 "\bæy\b\210æí¿$2\v\b\232,x")
    at ../../../zsh-4.0/Src/Zle/zle_main.c:1890
#12 0x0807d78b in zleentry (cmd=5) at ../../zsh-4.0/Src/init.c:1374
#13 0x080b32ee in dotrapargs (sig=0, sigtr=0xbfede6ac, sigfn=0x87716d0)
    at ../../zsh-4.0/Src/signals.c:1262
#14 0x080b2de6 in endtrapscope () at ../../zsh-4.0/Src/signals.c:1008
#15 0x0806973d in doshfunc (shfunc=0x8795898, doshargs=0x0, noreturnval=0)
    at ../../zsh-4.0/Src/exec.c:4600
#16 0x080e5678 in callcompfunc (s=0xb7ca7400 "", 
    fn=0x8796fc0 "_complete_debug") at ../../../zsh-4.0/Src/Zle/compcore.c:838

So it's attempting to redraw the prompt during the SIGEXIT trap at
at the end of calling _complete_debug, which causes an improper entry
into comp_wrapper while the global incompfunc == 1.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-08-03 16:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-03  3:26 _complete_debug crashes in zsh_directory_name Mikael Magnusson
2011-08-03  9:10 ` Peter Stephenson
2011-08-03 14:53   ` Mikael Magnusson
2011-08-03 15:39     ` Peter Stephenson
2011-08-03 16:00     ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).