Subject: bug#78824: [igc] segfault in temacs during build => charset-table

From: Pip Cet <[email-masked]>
Date: Wed, 18 Jun 2025 12:09:36 +0000

"Jeff Walsh" <[email-masked]> writes:

> When building the latest of the IGC branch, commit: 887db2ff38ce82bb5f33aa128c76b578caba216d 
>
> I am getting a SEGFAULT during temacs execution.

Thanks for the report.  I'm not sure what is happening, though.

> running under a debugger, this occurs in root_find in igc.c
> `if (r->d.start == start)` (r is null in this case)

This is the code:

static igc_root_list *
root_find (void *start)
{
  for (igc_root_list *r = global_igc->roots; r; r = r->next)
    if (r->d.start == start)
      return r;
  return NULL;
}

Clearly, r cannot be NULL on the second line, because of the check in
the for loop continue condition.

> walking the list of roots:
> p
> *global_igc->roots->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next->next
>
>
> provides:
> (igc_root_list) {
>   next = NULL
>   prev = 0x00000000006d5f00
>   d = {
>     gc = 0x0000000000726e00
>     root = 0x00007fffe80012a8
>     start = 0x00000000006142e0
>     end = 0x0000000000622f20
>     label = 0x0000000000233fb9 "charset-table"
>     ambig = true
>   }
> }

That's the last root in the list; can you walk the list to try to find
the one labelled "lface-id-to-name"?  My guess is there is no such root.

> (lldb) p start
> (void *) 0x0000000000000000
>
> (lldb) bt
> * thread #1, name = 'temacs', stop reason = signal SIGSEGV: address not mapped to object (fault address=0x20)
>     frame #0: 0x000000000051c953 temacs`igc_xpalloc_lisp_objs_exact [inlined] root_find(start=0x0000000000000000) at igc.c:3111:8
>     frame #1: 0x000000000051c940 temacs`igc_xpalloc_lisp_objs_exact [inlined] igc_destroy_root_with_start(start=0x0000000000000000) at
> igc.c:3135:33
>   * frame #2: 0x000000000051c940 temacs`igc_xpalloc_lisp_objs_exact(pa=(struct Lisp_Symbol *) $7 = 0x0000000000685300,
> nitems=0x0000000000628e18, nitems_incr_min=<unavailable>, nitems_max=<unavailable>, item_size=<unavailable>, label="lface-id-to-name") at
> igc.c:3520:3

Hmm.  I think the value of pa is 0.  That would mean lldb's
interpretation of pa as a pointer to struct Lisp_Symbol (which it isn't)
is incorrect.  Can you print the numeric value of lispsym to confirm
it's 0x685300?

My best guess at this point is that clang deduces that start must be
non-NULL because it's used as the source argument of a 0-byte memcpy.
Can you try replacing the memcpy in igc_xpalloc_lisp_objs_exact with

  if (nitems_old) memcpy (new, old, nitems_old * sizeof old[0]);

?

Thanks!

Pip