Subject: bug#75599: 31.0.50; scratch/igc: crash on commit 92ccf1c after opening file and REPL

From: Oliver Reiter <[email-masked]>
Date: Sat, 18 Jan 2025 12:23:55 +0100

Pip Cet <[email-masked]> writes:

> "Oliver Reiter via \"Bug reports for GNU Emacs, the Swiss army knife of text editors\"" <[email-masked]> writes:
>
>> Dear all,
>>
>> I hit this crash today after opening a .jl (julia-mode) file and
>> starting a REPL. I am using a Doom Emacs configuration.
>
> Thanks for the report!  I'm not familiar with julia-mode or Doom Emacs,
> but I'll have a look to see whether there's any obviously unusual stuff
> they do.
>
>> I built emacs with commit 92ccf1c7539fe00ec04be6bc1603b649db560c37
>> yesterday. I have the gdb session still open, if any further infos are
>> needed.
>
> In cases like this one, it's always a good idea to generate a core dump
> from within GDB.  That way, there's still a chance to debug things if
> the GDB session is closed or you do something irreversible from GDB.
>
> The relevant GDB command is "gcore".  Please also ensure to preserve a
> copy of the "emacs" executable that generated the core file, as the core
> file will be much less useful without that.
>

Thanks for taking the time to respond to my report. Unfortunately, I
accidentally closed the session before saving the core dump...

>> Also, in the gdb session I see quite a lot of messages like this:
>>
>> warning: Corrupted shared library list: 0x5555571e2550 != 0x555557202ed0
>>
>> Should this too be investigated?
>
> That sounds like a GDB bug.  While the GDB bug tracker is currently a
> bit of a graveyard, it's still a good idea to report such bugs.
>

I guess this has something to do with Arch Linux, which pulls in debug
info on the fly. I'll investigate and report elsewhere.

>> Here is the backtrace:
>>
>> Thread 1 "emacs" received signal SIGSEGV, Segmentation fault.
>>
>> buffer.c:579: Emacs fatal error: assertion failed: size > 0
>>
>> Thread 1 "emacs" hit Breakpoint 1, terminate_due_to_signal (sig=6, backtrace_limit=2147483647) at /home/reitero/build/sources/emacs/emacs/src/emacs.c:432
>> 432	{
>> (gdb) bt
>> #0  terminate_due_to_signal (sig=6, backtrace_limit=2147483647) at /home/reitero/build/sources/emacs/emacs/src/emacs.c:432
>> #1  0x000055555579e5df in set_state (state=<optimized out>) at /home/reitero/build/sources/emacs/emacs/src/igc.c:975
>> #2  0x00005555557934a2 in igc_assert_fail (file=<optimized out>, line=<optimized out>, msg=<optimized out>) at /home/reitero/build/sources/emacs/emacs/src/igc.c:276
>> #3  0x00005555558333ec in BufferFill ()
>> #4  0x0000555555868e20 in amcSegFix ()
>> #5  0x0000555555802d6d in _mps_fix2 ()
>> #6  0x000055555579bfda in fix_raw (ss=ss@entry=0x7fffffff5958, p=p@entry=0x7fffffff57d0) at /home/reitero/build/sources/emacs/emacs/src/igc.c:1145
>> #7  0x000055555579c0a3 in fix_string (ss=ss@entry=0x7fffffff5958, s=s@entry=0x7fffb88e48e8) at /home/reitero/build/sources/emacs/emacs/src/igc.c:1738
>> #8  0x00005555557a05e0 in dflt_scan_obj (ss=ss@entry=0x7fffffff5958, base_start=base_start@entry=0x7fffb88e48e8, base_limit=base_limit@entry=0x7fffb88e6000, closure=closure@entry=0x0)
>>     at /home/reitero/build/sources/emacs/emacs/src/igc.c:2005
>> #9  0x00005555557a0793 in dflt_scanx (ss=ss@entry=0x7fffffff5958, base_start=<optimized out>, base_limit=0x7fffb88e6000, closure=closure@entry=0x0)
>>     at /home/reitero/build/sources/emacs/emacs/src/igc.c:2072
>> #10 0x00005555557a07cf in dflt_scan (ss=0x7fffffff5958, base_start=<optimized out>, base_limit=<optimized out>) at /home/reitero/build/sources/emacs/emacs/src/igc.c:2083
>
> This is a common symptom of resurrecting an untraced object whose memory
> has been freed.  In this case, it's a string, but we don't know which
> other object referred to it, and how it managed to slip the reference
> past MPS.
>
> What might help us is to look at that string, but it is the string data
> which was overwritten, which is unfortunate.
>
> I've toyed with the idea of modifying igc.c so it's possible to get an
> explicit view of the heap for debugging for a while.  Maybe it's time to
> do that.
>
> Is this bug at all reproducible?  Further crash reports might help, or I
> could modify the igc.c code and we could gather more information.

I'll try and report back. I just started emacs, opened the file and
started a REPL.

>
> If it isn't, we should try inspecting the core dump.
>
> General GDB question (CCing Eli because he knows much more than I do
> about GDB): is there some way to run "find", but have it search all the
> memory ranges that are present in the relevant core dump?
>
> Or, at least, find out which ranges are present?  I know "objdump -h"
> provides that information, but it's not the most friendly of formats.
>
> I've usually just resorted to inspecting the core dump in hexl mode for
> that, but that's hardly ideal.  It would be helpful in this case because
> I don't have (or want) access to the core dump file produced by someone
> else's Emacs session.
>
> If there isn't, we'll have to use objdump:
>
> After dumping core (but don't quit the GDB session yet, just generate a
> core file and save it somewhere :-) ), please run this in bash:
>
> objdump -h <PATH_TO_COREFILE>  | egrep '^[0-9]' | while read N NAME SIZE START REST; do echo "find 0x$START,0x$START + 0x$SIZE,0x7fffb88e48e8"; done
>
> This produces a number of gdb commands, which you can paste into the
> (live) GDB session.  Most of them will say "Pattern not found.", but
> there's a chance some will also output an address.  For such addresses,
> please run
>
> x/32gx <ADDRESS> - 128
>
> (note the offset -128 is important, because we need to see the object's
> header)
>
> This should allow us to find the object which referred to the string,
> and maybe that helps.
>
> Thanks!
> Pip

Thank you!

Oliver