Eli Zaretskii | 1 May 2003 05:36
Picon

Re: Asynchronous bug

> From: "Stefan Monnier" <monnier+gnu/emacs/pretest <at> rum.cs.yale.edu>
> Date: Wed, 30 Apr 2003 14:34:35 -0400
> 
> I've been getting random crashes for a while and finally tracked it
> down to something useful.  The way it manifests itself is typically
> by a crash in mark_object, most of the time because the value of
> `nil' is garbage pointing to nowhereland.

Please show the value of `nil' (in hex) in a normal session and its
garbled value when this problem happens.
Lute Kamstra | 1 May 2003 14:13
Picon
Picon
Favicon

Redisplay problems with invisible text at the beginning of a line.

Dear people,

This concerns not only cvs Emacs 21.3.50 but also released Emacs 21.1
and 21.3.  The bugs are slightly different for the released Emacsen,
though.

Currently, I'm writing a major mode that uses an invisible character
at the beginning of each line to store some data.  This results in a
number of redisplay problems.  A good way to reproduce three of them
is as follows:

Create a buffer in a window and make sure that the buffer is
significantly larger that the window.  (Opening the tutorial with C-h
t will do nicely.)

Move point to the first character of a nonempty line in the bottom
half of the window.

Evaluate (put-text-property (point) (+ (point) 1) 'invisible t) to
make the first character of the line invisible.

Type C-u 0 C-l (to invoke recenter).

What I would expect to see now is that the line the point is in would
become the first line of the window and that point would not move.
However, this is not the case.  Bug number 1:

A. For Emacs 21.1 and 21.3 the following happens.  The line point is
   in, that is, the line starting with the invisible character,
   becomes the first line of the window and point moves to the
(Continue reading)

Stefan Monnier | 1 May 2003 17:53
Picon

Re: Asynchronous bug

> > From: "Stefan Monnier" <monnier+gnu/emacs/pretest <at> rum.cs.yale.edu>
> > Date: Wed, 30 Apr 2003 14:34:35 -0400
> > 
> > I've been getting random crashes for a while and finally tracked it
> > down to something useful.  The way it manifests itself is typically
> > by a crash in mark_object, most of the time because the value of
> > `nil' is garbage pointing to nowhereland.
> 
> Please show the value of `nil' (in hex) in a normal session and its
> garbled value when this problem happens.

I don't think this is relevant.
The problem is asynchrony.
The backtrace I showed can also be reproduced where the signal
is caught in the middle of pretty much any random piece of code
(other than the BLOCK_INPUT'ed code of course) so meddling with
global variables such as specpdl_ptr is bound to lead to problems.

Another problem I have seen every once in a while is where I get

	Xlib: unexpected async reply (sequence 0x17d6)!

which indicates that we forgot to BLOCK_INPUT around some Xlib calls.

Another way to look at all of this is that our signal handler does
way too many things.  It would be much better to just set a variable
and return immediately.  We could check this variable in QUIT,
for example.

	Stefan
(Continue reading)

Eli Zaretskii | 1 May 2003 18:26
Picon

Re: Asynchronous bug

> From: "Stefan Monnier" <monnier+gnu/emacs/pretest <at> rum.cs.yale.edu>
> Date: Thu, 01 May 2003 11:53:12 -0400
> > > 
> > > I've been getting random crashes for a while and finally tracked it
> > > down to something useful.  The way it manifests itself is typically
> > > by a crash in mark_object, most of the time because the value of
> > > `nil' is garbage pointing to nowhereland.
> > 
> > Please show the value of `nil' (in hex) in a normal session and its
> > garbled value when this problem happens.
> 
> I don't think this is relevant.
> The problem is asynchrony.

Sorry if I'm being not useful, but I just thought that the value of
`nil' should _never_ change, ever.

I once had to debug a problem where `nil' changed its value, and
naturally thought that you have something similar on your hands, and
that I could help.  But if you are sure my question cannot possibly
lead to useful ideas, by no means don't waste your time on my
suggestion.
Stefan Monnier | 1 May 2003 19:20
Picon

Re: Asynchronous bug

> > From: "Stefan Monnier" <monnier+gnu/emacs/pretest <at> rum.cs.yale.edu>
> > Date: Thu, 01 May 2003 11:53:12 -0400
> > > > 
> > > > I've been getting random crashes for a while and finally tracked it
> > > > down to something useful.  The way it manifests itself is typically
> > > > by a crash in mark_object, most of the time because the value of
> > > > `nil' is garbage pointing to nowhereland.
> > > 
> > > Please show the value of `nil' (in hex) in a normal session and its
> > > garbled value when this problem happens.
> > 
> > I don't think this is relevant.
> > The problem is asynchrony.
> 
> Sorry if I'm being not useful, but I just thought that the value of
> `nil' should _never_ change, ever.

It is changed in unbind_to because unbind_to does not
re-check whether the bound variable is constant or not.
We have code like:

   if (NILP (specpdl_ptr->symbol))
      ...do something...
   else
      set_internal (specpdl_ptr->symbol, ...)

Now, if specpdl_ptr->symbol gets overwritten with Qnil (by an async
signal) just between the if and the call to set_internal we end up
changing the value of `nil'.

(Continue reading)

Richard Stallman | 1 May 2003 19:48
Picon
Picon

Re: Asynchronous bug

    Watchpoints showed that the value of `nil' is modified in `unbind_to'.
    The way it works is that specpdl_ptr->symbol changes from non-nil
    to nil in the time between the nil test and the use of the value.

The problem was evident when I looked at the code of unbind_to.
Does this patch fix it?

*** eval.c.~1.206.~	Mon Apr 28 17:12:08 2003
--- eval.c	Thu May  1 02:15:49 2003
***************
*** 3070,3083 ****

    while (specpdl_ptr != specpdl + count)
      {
!       --specpdl_ptr;

!       if (specpdl_ptr->func != 0)
! 	(*specpdl_ptr->func) (specpdl_ptr->old_value);
        /* Note that a "binding" of nil is really an unwind protect,
  	 so in that case the "old value" is a list of forms to evaluate.  */
!       else if (NILP (specpdl_ptr->symbol))
! 	Fprogn (specpdl_ptr->old_value);
        /* If the symbol is a list, it is really (SYMBOL WHERE
  	 . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
  	 frame.  If WHERE is a buffer or frame, this indicates we
--- 3070,3083 ----

    while (specpdl_ptr != specpdl + count)
      {
!       struct specbinding *this_binding = specpdl_ptr - 1;
(Continue reading)

Stefan Monnier | 1 May 2003 21:19
Picon

Re: Asynchronous bug

>     Watchpoints showed that the value of `nil' is modified in `unbind_to'.
>     The way it works is that specpdl_ptr->symbol changes from non-nil
>     to nil in the time between the nil test and the use of the value.
> 
> The problem was evident when I looked at the code of unbind_to.
> Does this patch fix it?
> 
> *** eval.c.~1.206.~	Mon Apr 28 17:12:08 2003
> --- eval.c	Thu May  1 02:15:49 2003
> ***************
> *** 3070,3083 ****
>   
>     while (specpdl_ptr != specpdl + count)
>       {
> !       --specpdl_ptr;
>   
> !       if (specpdl_ptr->func != 0)
> ! 	(*specpdl_ptr->func) (specpdl_ptr->old_value);
>         /* Note that a "binding" of nil is really an unwind protect,
>   	 so in that case the "old value" is a list of forms to evaluate.  */
> !       else if (NILP (specpdl_ptr->symbol))
> ! 	Fprogn (specpdl_ptr->old_value);
>         /* If the symbol is a list, it is really (SYMBOL WHERE
>   	 . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
>   	 frame.  If WHERE is a buffer or frame, this indicates we
> --- 3070,3083 ----
>   
>     while (specpdl_ptr != specpdl + count)
>       {
> !       struct specbinding *this_binding = specpdl_ptr - 1;
(Continue reading)

Jesper Harder | 2 May 2003 00:29
Picon
Picon
Picon

[Info mode] Bad wrapping of <at> xrefs

Hi!

In Info mode  <at> xrefs are sometimes wrapped incorrectly.  

For an example see the "Other Marks" section in the Gnus manual.  In
CVS Emacs the first  <at> xref is incorrectly aligned at the left margin:

,----
|    There are some marks that have nothing to do with whether the
| article is read or not.
| 
|    * You can set a bookmark in the current article.  Say you are
|      reading a long thesis on cats' urinary tracts, and have to go
|      home for dinner before you've finished reading the thesis.  You
|      can then set a bookmark in the article, and Gnus will jump to
|      this bookmark the next time it encounters the article.  See
| Setting Marks.
| 
`----

The same Info file is displayed correctly in both the stand-alone Info
viewer and Emacs 21.3.

In GNU Emacs 21.3.50.71 (i686-pc-linux-gnu)
 of 2003-05-02 on defun.localdomain
configured using `configure '--with-gtk''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
(Continue reading)

Richard Stallman | 2 May 2003 09:06
Picon
Picon

Re: Asynchronous bug

    Isn't this going to cause the unwind-protect to be re-executed
    if a signal is thrown while executing
    (*specpdl_ptr->func) (specpdl_ptr->old_value);
    now that specpdl_ptr is decremented afterwards ?

Yes, you're right.  How about this version?

Lisp_Object
unbind_to (count, value)
     int count;
     Lisp_Object value;
{
  int quitf = !NILP (Vquit_flag);
  struct gcpro gcpro1;

  GCPRO1 (value);
  Vquit_flag = Qnil;

  while (specpdl_ptr != specpdl + count)
    {
      struct specbinding this_binding = *--specpdl_ptr;

      if (this_binding.func != 0)
	(*this_binding.func) (this_binding.old_value);
      /* If the symbol is a list, it is really (SYMBOL WHERE
	 . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
	 frame.  If WHERE is a buffer or frame, this indicates we
	 bound a variable that had a buffer-local or frame-local
	 binding.  WHERE nil means that the variable had the default
	 value when it was bound.  CURRENT-BUFFER is the buffer that
(Continue reading)

Stefan Monnier | 2 May 2003 15:22
Picon

Re: Asynchronous bug

>     Isn't this going to cause the unwind-protect to be re-executed
>     if a signal is thrown while executing
>     (*specpdl_ptr->func) (specpdl_ptr->old_value);
>     now that specpdl_ptr is decremented afterwards ?
> 
> Yes, you're right.  How about this version?

That's what I've been using for a while and it seems to help in practice,
even though in theory it still has the same problem: specpdl_ptr
and specpdl_ptr->symbol are not aliased (and neither are they marked
as volatile) so the compiler can reorder accesses to those things and
generate the same code as it would have generated for something like:

	specpdl_ptr--;
	this_binding = *(specpdl_ptr+1);

where an async signal between the two statements could lead to an error.

Given the fact that there are already known problems with async
signals (they may access global structures in the middle of their
updating.  E.g. the mouse-face text-properties), the fact that
a previous bug took several months to Gerd and I to track down
(the signal handler was calling Fcons) and the fact that I get
`Xlib: unexpected async reply' messages every once in a while,
I think there's a clear need for the signal handler to be trimmed
down to the bare minimum.

I'm right now experimenting with the simple attached change
that moves all the signal handling code outside of the
signal handler (which now just sets a variable and returns).
(Continue reading)


Gmane