[Please remove xemacs-patches from CC when replying]
Hamish Macdonald <hamishm(a)lucent.com> writes:
Superb bug report...
I discovered that when attempting to do some piping in eshell
(e.g. "ls | head"), my XEmacs was dying. I started to do some
investigation.
I got the following backtrace:
#0 assert_failed (file=0x22bda8 "lstream.h", line=33,
expr=0x22bdb8 "RECORD_TYPEP (obj, lrecord_type_lstream)") at emacs.c:2748
#1 0xdace4 in unix_send_process (proc=5188096, lstream=0x37fc00)
at lstream.h:33
#2 0x167b38 in send_process (proc=5188096, relocatable=5573876,
nonrelocatable=0x0, start=0, len=315) at process.c:988
#3 0x16a2a8 in Fprocess_send_string (process=5188096, string=5573876,
from=-24697440, to=-24697440) at process.c:1118
This backtrace is actually somewhat misleading, since the lstream
passed in to unix_send_process is perfectly valid. The lstream that is
being barfed on in p->pipe_outstream (where p is the process structure
referred to by Lisp_Object argument proc.
[...]
> XLSTREAM(p->pipe_outstream) as an argument. At this point,
p->p->pipe_outstream is no longer an lstream, but is nil;
the assertion fails, BOOM.
I'm not sure what the correct fix is here.
Since it is perfectly normal for a process to die while processing
events we have to guard against after calls that process events..
I think the following simple bailout is the correct solution
2000-04-11 Jan Vroonhof <jan(a)xemacs.org>
* process-unix.c (unix_send_process): Guard against process MIA
after Faccept_process_output.
Index: process-unix.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs-20/src/process-unix.c,v
retrieving revision 1.11.2.18
diff -u -r1.11.2.18 process-unix.c
--- process-unix.c 2000/03/01 18:22:05 1.11.2.18
+++ process-unix.c 2000/04/11 10:31:19
@@ -1139,6 +1139,14 @@
volatile Lisp_Object vol_proc = proc;
Lisp_Process *volatile p = XPROCESS (proc);
+ /* #### JV: layering violation?
+
+ This function knows too much about the relation between the encodingstream
+ (DATA_OUTSTREAM) and te actual output stream p->output_stream.
+
+ If encoding streams properly forwarded all calls, we could simply
+ use DATA_OUTSTREAM everywhere. */
+
if (!SETJMP (send_process_frame))
{
/* use a reasonable-sized buffer (somewhere around the size of the
@@ -1173,6 +1181,9 @@
that may allow the program
to finish doing output and read more. */
Faccept_process_output (Qnil, make_int (1), Qnil);
+ /* It could have *really* finished, deleting the process */
+ if (NILP(p->pipe_outstream))
+ return;
old_sigpipe =
(SIGTYPE (*) (int)) signal (SIGPIPE, send_process_trap);
Lstream_flush (XLSTREAM (p->pipe_outstream));