emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

wait_reading_process_output bug [Was RE: A question on wait_reading_proc


From: Herbert Euler
Subject: wait_reading_process_output bug [Was RE: A question on wait_reading_process_output]
Date: Thu, 29 May 2008 19:30:44 +0800

I think I can reproduce the problem now.  Following the steps I will
introduce later, I see the problem, just as my guess.

I have attatched two files: x.c and x.el.  In the file x.c, the key
logic is very simple, as listed below:

  signal (SIGTERM, handle_interrupt);
  while (keep_looping)
    ;
  printf ("hello, world\n");

We will run this program inside Emacs and send a SIGTERM signal to its
process with "kill PID" at a proper point.  That will make some output
available from the program and change its status to exit, so the code
of the body of the if will be executed, to reproduce the error.

The logic of x.el is also simple:

  (let* ((buf (get-buffer-create "*test*"))
         (proc (start-process "test" buf "/tmp/x")))
    (when (accept-process-output proc 100 nil t)
      (switch-to-buffer buf)))

"/tmp/x" here is the executable file, we will run it as an
asynchronous process, and try to read its output.  We will not read
output from any other processes at the same time, as specified by the
last argument of the calling to `accept-process-output'.  If
`accept-process-output' returns non-nil value, which means it reads
some output from the process according to its docstring, we will
switch to its output buffer.  Otherwise, we stay at the buffer where
we were.

Now I will introduce how to reproduce the bug.

1. Copy the two files, x.el and x.c to /tmp.  Compile x.c:

     address@hidden:/tmp$ pwd
     /tmp
     address@hidden:/tmp$ cc -o x x.c
     address@hidden:/tmp$ ls x*
     x  x.c  x.el
     address@hidden:/tmp$

2. Start Emacs in gdb:

     (gdb) r -Q /tmp/x.el

Goto the end of the file and type C-x C-e to evaluate the let* form.
In another shell, kill the asynchronous process:

     address@hidden:/tmp$ ps aux | grep /tmp/x$ | grep -v grep | awk '{ print 
$2 }'
     690
     address@hidden:/tmp$ kill 690
     address@hidden:/tmp$

The argument to kill is the process ID.  The current buffer becomes
*test*.  This is expected: `accept-process-output' returns non-nil, so
the current buffer is switched.

Now quit from Emacs by typing C-x C-c.

3. This time we will set a breakpoint at Faccept_process_output, so
that we can kill the asynchronous process at a proper point:

     (gdb) b Faccept_process_output
     Breakpoint 3 at 0x8253386: file process.c, line 3907.
     (gdb)

And start Emacs in the same way:

     (gdb) r -Q /tmp/x.el

4. Evaluate the let* form in x.el, gdb will take over the control.
Now set a breakpoint at process.c:4458, and continue the execution to
that point:

     Breakpoint 3, Faccept_process_output (process=143107140, seconds=800, 
millisec=138480921, just_this_one=138480969)
         at process.c:3907
     3907      int secs, usecs = 0;
     (gdb) b process.c:4458
     Breakpoint 4 at 0x8254347: file process.c, line 4458.
     (gdb) c
     Continuing.

     Breakpoint 4, wait_reading_process_output (time_limit=100, microsecs=0, 
read_kbd=0, do_display=0,
         wait_for_cell=138480921, wait_proc=0x887a440, just_wait_proc=1) at 
process.c:4458
     4458          if (wait_proc && wait_proc->raw_status_new)
     (gdb)

5. Kill the asynchronous process again.  This will trigger the
condition reproducing the bug.  In another shell, execute the
following commands:

     address@hidden:/tmp$ ps aux | grep /tmp/x$ | grep -v grep | awk '{ print 
$2 }'
     5727
     address@hidden:/tmp$ kill 5727
     address@hidden:/tmp$

And, after killing the process, in the gdb shell, set another
breakpoint and continue the execution to that point:

     (gdb) b process.c:4472
     Breakpoint 5 at 0x8254591: file process.c, line 4472.
     (gdb) c
     Continuing.

     Breakpoint 5, wait_reading_process_output (time_limit=100, microsecs=0, 
read_kbd=0,
         do_display=0, wait_for_cell=138481385, wait_proc=0x853a788, 
just_wait_proc=1)
         at process.c:4472
     4472                  nread = read_process_output (proc, wait_proc->infd);
     (gdb)

The value of nread will be greater than 0, which means something has
been read from wait_proc's output:

     (gdb) c
     Continuing.

     Breakpoint 5, wait_reading_process_output (time_limit=100, microsecs=0, 
read_kbd=0,
         do_display=0, wait_for_cell=138481385, wait_proc=0x853a788, 
just_wait_proc=1)
         at process.c:4472
     4472                  nread = read_process_output (proc, wait_proc->infd);
     (gdb) n
     4474                  if (nread == 0)
     (gdb) p nread
     $1 = 13
     (gdb)

wait_reading_process_output promises returning non-null value in such
a case.  But the fact is not as described.  Type finish in the gdb
shell to see this:

     (gdb) finish
     Run till exit from #0  wait_reading_process_output (time_limit=100, 
microsecs=0, read_kbd=0,
         do_display=0, wait_for_cell=138481385, wait_proc=0x853a788, 
just_wait_proc=1)
         at process.c:4472
     0x0825375e in Faccept_process_output (process=139700108, seconds=800, 
millisec=138481385,
         just_this_one=138481433) at process.c:3946
     3946      return
     Value returned is $2 = 0
     (gdb)

This $2 (0) becomes the value of evaluating accept-process-output.
Now delete all of the breakpoints and go back to the Emacs process:

     (gdb) d
     Delete all breakpoints? (y or n) y
     (gdb) c
     Continuing.

The current buffer remains #, not *test*.  The behavior
here is not the same as said in step 2, and is not expected.  Because
accept-process-output has read something, it should return a non-nil
value.  But it does not.

Regards,
Guanpeng Xu


Btw, when I verify the steps to reproduce the bug, I find the
possibility it happens is not very small.  I see the unexpected
behavior at least once without the helping of gdb.
_________________________________________________________________
Discover the new Windows Vista
http://search.msn.com/results.aspx?q=windows+vista&mkt=en-US&form=QBRE

Attachment: x.c
Description: Text Data

Attachment: x.el
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]