Subject: bug#22526: 25.0.90; Crash starting gnus

From: Eli Zaretskii <[email-masked]>
Date: Thu, 11 Feb 2016 22:27:23 +0200

> From: Andy Moreton <[email-masked]>
> Date: Thu, 11 Feb 2016 02:06:54 +0000
> 
> Hopefully this is of some use.

It is, thanks.  The plot thickens...  This is one of those cases where
I'd give anything for a way to trace execution in reverse and see what
happened before the problem...

Anyway, is that GDB session still running?  If so, could you please
try the following two GDB commands?

 (gdb) p Z_ADDR
 (gdb) p *(Z_ADDR)

If the last one says something about not being able to access memory
at address such-and-such, then please try a series of commands like
this:

  (gdb) p/x *(Z_ADDR - 1)
  (gdb) p/x *(Z_ADDR - 2)
  (gdb) p/x *(Z_ADDR - 3)

etc., until you find the largest address which GDB succeeds to access
and report its contents.  (If the first few commands still report
failure to access, it might be better to use larger offsets, and then
perform binary search once you find an accessible address.)  The goal
is, assuming that Z_ADDR somehow points to memory outside of the
process address space, to find the last byte that is still inside the
address space.  Then do this:

  (gdb) p/x THAT_ADDRESS - BEG_ADDR

where THAT_ADDRESS is the last address that GDB can access.

I'd also like to ask you to add a couple of lines to make_gap_larger,
to help with debugging this, but I want to see the results of the
above first.

For the record, what seems to have happened here is that some Gnus
command caused Emacs to insert a 4K string into a buffer that was
63493 bytes long.  In response, Emacs enlarged the buffer text to
accommodate those 4K, then moved the existing buffer text towards
higher address to enlarge the gap by 4K, in preparation for inserting
the string into the gap.  Then it crashed when it tried to
null-terminate the enlarged buffer text.  The crash is strange because
the code in gap_left, called just before the crash, should have
already accessed all the addresses up to and including the one
immediately preceding Z_ADDR.  So this seems to imply that there's
some off-by-one error somewhere in the related code, but I don't see
it yet.

Btw, it sounds like it should be easy to reproduce this almost at
will, since the two backtraces are almost identical -- they both show
the same insertion of a 4096 byte string into a buffer by the default
process filter that reads stuff received from the news server.  Could
you perhaps try coming up with such a reproducer, starting from
"emacs -Q"?  That would make the debugging much more efficient.

Thanks.