emacs-pretest-bug
[Top][All Lists]
Advanced

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

Re: Ediff frequently crashes emacs.


From: Peter Seibel
Subject: Re: Ediff frequently crashes emacs.
Date: Fri, 12 Nov 2004 08:45:43 -0800
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3.50 (gnu/linux)

Richard Stallman <address@hidden> writes:

> Please follow the advice in etc/DEBUG for what to do when Emacs is
> looping.

Okay, I tried. My lack of facility with gdb may mean this is still not
quite what you want--I invoked gdb from within another Emacs (i.e. M-x
gdb) to attach to the hung Emacs process (gdb -pid=xxxxx). Which
seemed to work fine. Then I used `finish' as suggested to find the
frame which did not return. From there it was not entirely clear how
to get back to the gdb prompt so I could step. I flailed around and
managed to get back to the prompt but may have dorked something up in
the meantime. Anyway, once I got the prompt back stepping with C-c C-n
seemed to indicate that the loop hopped between the three lines marked
with >>> in wait_reading_process_output as shown below:

-Peter

wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
                             wait_for_cell, wait_proc, just_wait_proc)
     int time_limit, microsecs, read_kbd, do_display;
     Lisp_Object wait_for_cell;
     struct Lisp_Process *wait_proc;
     int just_wait_proc;
{


[... code elided ...]

      for (channel = 0; channel <= max_process_desc; channel++)
        {
>>>>      if (FD_ISSET (channel, &Available)
              && FD_ISSET (channel, &non_keyboard_wait_mask))
            {
              int nread;

              /* If waiting for this channel, arrange to return as
                 soon as no more input to be processed.  No more
                 waiting.  */
              if (wait_channel == channel)
                {
                  wait_channel = -1;
                  time_limit = -1;
                  got_some_input = 1;
                }
              proc = chan_process[channel];
              if (NILP (proc))
                continue;

              /* If this is a server stream socket, accept connection.  */
              if (EQ (XPROCESS (proc)->status, Qlisten))
                {
                  server_accept_connection (proc, channel);
                  continue;
                }

              /* Read data from the process, starting with our
                 buffered-ahead character if we have one.  */

              nread = read_process_output (proc, channel);
              if (nread > 0)
                {
                  /* Since read_process_output can run a filter,
                     which can call accept-process-output,
                     don't try to read from any other processes
                     before doing the select again.  */
                  FD_ZERO (&Available);

                  if (do_display)
                    redisplay_preserve_echo_area (12);
                }
#ifdef EWOULDBLOCK
              else if (nread == -1 && errno == EWOULDBLOCK)
                ;
#endif
              /* ISC 4.1 defines both EWOULDBLOCK and O_NONBLOCK,
                 and Emacs uses O_NONBLOCK, so what we get is EAGAIN.  */
#ifdef O_NONBLOCK
              else if (nread == -1 && errno == EAGAIN)
                ;
#else
#ifdef O_NDELAY
              else if (nread == -1 && errno == EAGAIN)
                ;
              /* Note that we cannot distinguish between no input
                 available now and a closed pipe.
                 With luck, a closed pipe will be accompanied by
                 subprocess termination and SIGCHLD.  */
              else if (nread == 0 && !NETCONN_P (proc))
                ;
#endif                          /* O_NDELAY */
#endif                          /* O_NONBLOCK */
#ifdef HAVE_PTYS
              /* On some OSs with ptys, when the process on one end of
                 a pty exits, the other end gets an error reading with
                 errno = EIO instead of getting an EOF (0 bytes read).
                 Therefore, if we get an error reading and errno =
                 EIO, just continue, because the child process has
                 exited and should clean itself up soon (e.g. when we
                 get a SIGCHLD).

                 However, it has been known to happen that the SIGCHLD
                 got lost.  So raise the signl again just in case.
                 It can't hurt.  */
              else if (nread == -1 && errno == EIO)
                kill (getpid (), SIGCHLD);
#endif                          /* HAVE_PTYS */
              /* If we can detect process termination, don't consider the 
process
                 gone just because its pipe is closed.  */
#ifdef SIGCHLD
              else if (nread == 0 && !NETCONN_P (proc))
                ;
#endif
              else
                {
                  /* Preserve status of processes already terminated.  */
                  XSETINT (XPROCESS (proc)->tick, ++process_tick);
                  deactivate_process (proc);
                  if (!NILP (XPROCESS (proc)->raw_status_low))
                    update_status (XPROCESS (proc));
                  if (EQ (XPROCESS (proc)->status, Qrun))
                    XPROCESS (proc)->status
                      = Fcons (Qexit, Fcons (make_number (256), Qnil));
                }
            }
#ifdef NON_BLOCKING_CONNECT
>>>>      if (check_connect && FD_ISSET (channel, &Connecting)
              && FD_ISSET (channel, &connect_wait_mask))
            {
              struct Lisp_Process *p;

              FD_CLR (channel, &connect_wait_mask);
              if (--num_pending_connects < 0)
                abort ();

              proc = chan_process[channel];
              if (NILP (proc))
                continue;

              p = XPROCESS (proc);

#ifdef GNU_LINUX
              /* getsockopt(,,SO_ERROR,,) is said to hang on some systems.
                 So only use it on systems where it is known to work.  */
              {
                int xlen = sizeof(xerrno);
                if (getsockopt(channel, SOL_SOCKET, SO_ERROR, &xerrno, &xlen))
                  xerrno = errno;
              }
#else
              {
                struct sockaddr pname;
                int pnamelen = sizeof(pname);

                /* If connection failed, getpeername will fail.  */
                xerrno = 0;
                if (getpeername(channel, &pname, &pnamelen) < 0)
                  {
                    /* Obtain connect failure code through error slippage.  */
                    char dummy;
                    xerrno = errno;
                    if (errno == ENOTCONN && read(channel, &dummy, 1) < 0)
                      xerrno = errno;
                  }
              }
#endif
              if (xerrno)
                {
                  XSETINT (p->tick, ++process_tick);
                  p->status = Fcons (Qfailed, Fcons (make_number (xerrno), 
Qnil));
                  deactivate_process (proc);
                }
              else
                {
                  p->status = Qrun;
                  /* Execute the sentinel here.  If we had relied on
                     status_notify to do it later, it will read input
                     from the process before calling the sentinel.  */
                  exec_sentinel (proc, build_string ("open\n"));
                  if (!EQ (p->filter, Qt) && !EQ (p->command, Qt))
                    {
                      FD_SET (XINT (p->infd), &input_wait_mask);
                      FD_SET (XINT (p->infd), &non_keyboard_wait_mask);
                    }
                }
>>>         }
#endif /* NON_BLOCKING_CONNECT */
        }                       /* end for each file descriptor */


-- 
Peter Seibel                                      address@hidden

         Lisp is the red pill. -- John Fraser, comp.lang.lisp




reply via email to

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