Subject: bug#76705: 31.0.50; igc: crash

From: Pip Cet <[email-masked]>
Date: Mon, 03 Mar 2025 16:11:03 +0000

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

> Pip Cet <[email-masked]> writes:
>
>> I assume this is a Linux kernel?
>
> Correct.
>
> $ uname -a
> Linux zen 6.12.11-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.11-1 (2025-01-25) x86_64 GNU/Linux
>
>> Can you do an objdump -h on the core file, reporting only the count of
>> "load" sections?  (Over here, I see about 3000 sections, which is a
>> lot).
>
> Tail of objdump -h :
>
> 9260 load8395      15760000  0000556e2e8c0000  0000000000000000  9d20f000  2**12
>                   CONTENTS, ALLOC, LOAD
>
> $ 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?

>> 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 :-)

>> 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...

>    0x0000556e0edcf8b9 <+9>:     push   %rbx
>    0x0000556e0edcf8ba <+10>:    mov    %rsi,%rbx
>    0x0000556e0edcf8bd <+13>:    cmp    %rsi,%rdi
>    0x0000556e0edcf8c0 <+16>:    jae    0x556e0edcf958 <ProtSet+168>
>    0x0000556e0edcf8c6 <+22>:    test   %rbp,%rbp
>    0x0000556e0edcf8c9 <+25>:    je     0x556e0edcf980 <ProtSet+208>
>    0x0000556e0edcf8cf <+31>:    sub    %rbp,%rbx
>    0x0000556e0edcf8d2 <+34>:    cmp    $0x7fffffff,%rbx
>    0x0000556e0edcf8d9 <+41>:    ja     0x556e0edcf9b0 <ProtSet+256>
>    0x0000556e0edcf8df <+47>:    mov    $0x5,%edx
>    0x0000556e0edcf8e4 <+52>:    cmp    $0x2,%r12d
>    0x0000556e0edcf8e8 <+56>:    je     0x556e0edcf8f6 <ProtSet+70>
>    0x0000556e0edcf8ea <+58>:    ja     0x556e0edcf930 <ProtSet+128>
>    0x0000556e0edcf8ec <+60>:    mov    $0x7,%edx
>    0x0000556e0edcf8f1 <+65>:    test   %r12d,%r12d
>    0x0000556e0edcf8f4 <+68>:    jne    0x556e0edcf94f <ProtSet+159>
>    0x0000556e0edcf8f6 <+70>:    mov    %rbx,%rsi
>    0x0000556e0edcf8f9 <+73>:    mov    %rbp,%rdi

>    0x0000556e0edcf8fc <+76>:    call   0x556e0ead23b0 <mprotect@plt>
>    0x0000556e0edcf901 <+81>:    test   %eax,%eax
>    0x0000556e0edcf903 <+83>:    je     0x556e0edcf928 <ProtSet+120>

This calls mprotect, and we only reach it when the return value is nonzero.

>    0x0000556e0edcf905 <+85>:    pop    %rbx
> --Type <RET> for more, q to quit, c to continue without paging--
>    0x0000556e0edcf906 <+86>:    lea    0x3b536(%rip),%rdx        # 0x556e0ee0ae43
>    0x0000556e0edcf90d <+93>:    pop    %rbp
>    0x0000556e0edcf90e <+94>:    mov    $0x75,%esi
>    0x0000556e0edcf913 <+99>:    lea    0x4011b(%rip),%rdi        # 0x556e0ee0fa35
>    0x0000556e0edcf91a <+106>:   pop    %r12
>    0x0000556e0edcf91c <+108>:   jmp    *0xbcf4e(%rip)        # 0x556e0ee8c870 <mps_lib_assert_handler>

And this tail-calls mps_lib_assert_handler, and it's the only place that
does so.  So it's definitely a failed mprotect.

Pip