Subject: bug#76705: 31.0.50; igc: crash

From: Pip Cet <[email-masked]>
Date: Mon, 03 Mar 2025 19:57:27 +0000

Óscar Fuentes <[email-masked]> writes:

> Pip Cet <[email-masked]> writes:
>
>>> $ objdump -h dump | grep " load" | wc
>>>    9237   64659  747221
>>
>> Hmm. Is it possible that increases by a factor of 6 during a collection?
>> How large is the core file?
>
> $ ls -lh
> total 2.8G
> -rw-rw-r-- 1 oscar oscar 2.8G Mar  3 16:46 dump

That looks potentially large enough for my theory that we ran out into
the max_map_count limit.

    MPS_ARGS_ADD (args, MPS_KEY_ARENA_GRAIN_SIZE, 64 * 1024);

wouldn't fix the problem, but by extrapolation we'd only hit it when the
Emacs session reaches ~20 GB :-)

(I originally added that line to my local tree for performance reasons,
but I'm not sure about the impact on weak objects in particular.)

If you have the time and inclination, you could reduce
/proc/sys/vm/max_map_count and see what kind of Emacs crash you get, but
as it's a system-wide property, that might not be a good idea if other
important stuff is on the machine...

>>>> What is the output of
>>>>
>>>> cat /proc/sys/vm/max_map_count
>>>>
>>>> ?  It is 65530 here,
>>>
>>> Same here.
>>
>> I set it to 4096, and that crashed my MPS Emacs when I started a
>> collection (which is when the mprotect calls happen), so running against
>> this limit during a collection is my current best theory.
>>
>> If this is indeed an issue, we might have to increase ARENA_GRAIN_SIZE,
>> or submit a patch to MPS...
>>
>> However, I would still like to see errno = ENOMEM to be sure :-)
>
> Trying to follow Eli's hint:
>
> (gdb) ptype errno
> type = int
> (gdb) whatis errno
> type = int
> (gdb) p errno
> $1 = 25

That's ENOTTY here, which is unlikely to be what mprotect returned, so
possibly another error (most likely something during the abort tried an
ioctl?)

So if it's the mprotect thing, what do we do?  Is glibc running into the
same problem when it uses mmap for malloc?

>>>> Thanks! This means that it was actually ProtSet which aborted, and since
>>>> it doesn't show up in the backtrace it must have tail-called the
>>>> assertion function.  Can you disassemble ProtSet just to make sure that
>>>> we're looking at an mprotect failure here?
>>>
>>> (gdb) disass/s ProtSet
>>> Dump of assembler code for function ProtSet:
>>>    0x0000556e0edcf8b0 <+0>:     push   %r12
>>>    0x0000556e0edcf8b2 <+2>:     mov    %edx,%r12d
>>>    0x0000556e0edcf8b5 <+5>:     push   %rbp
>>>    0x0000556e0edcf8b6 <+6>:     mov    %rdi,%rbp
>>
>> Hmm.  You've compiled MPS without -fno-omit-frame-pointer.  I think
>> (hope!)  that's safe as only references created outside of MPS can pin
>> objects...
>
> Sorry! Next build will use -fno-omit-frame-pointer.

No reason to apologize, I'm not even sure it's a problem. just something
I noticed in the assembly listing.

Pip