https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120464

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
You didn't say which host was this (nor which target).
I assume it is some host without working mmap.

Anyway, trying to reproduce it on x86_64-linux with
--- gcc/ggc-page.cc.jj  2025-05-27 23:08:37.969726172 +0200
+++ gcc/ggc-page.cc     2025-05-28 21:16:49.545802332 +0200
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3.
 #ifdef HAVE_MMAP_DEV_ZERO
 # define USING_MMAP
 #endif
+#undef USING_MMAP

 #ifndef USING_MMAP
 #define USING_MALLOC_PAGE_GROUPS
@@ -955,7 +956,7 @@ alloc_page (unsigned order)
       /* If we allocated multiple pages, put the rest on the free list.  */
       if (multiple_pages)
        {
-         struct page_entry *e, *f = G.free_pages;
+         struct page_entry *e, *f = free_list->free_pages;
          for (a = enda - G.pagesize; a != page; a -= G.pagesize)
            {
              e = XCNEWVAR (struct page_entry, page_entry_size);
things progress a little bit further but ICE during selftest:
cc1plus: internal compiler error: Segmentation fault
0x26ed16f internal_error(char const*, ...)
        ../../gcc/diagnostic-global-context.cc:517
0x13d5f1f crash_signal
        ../../gcc/toplev.cc:321
0xe25ecf do_release_pages
        ../../gcc/ggc-page.cc:1204
0xe25ecf release_pages
        ../../gcc/ggc-page.cc:1242
0xe27632 ggc_collect(ggc_collect)
        ../../gcc/ggc-page.cc:2316
0x102fdfe test_length
        ../../gcc/ggc-tests.cc:80
0x102fdfe selftest::ggc_tests_cc_tests()
        ../../gcc/ggc-tests.cc:468
0x25dcbe5 selftest::run_tests()
        ../../gcc/selftest-run-tests.cc:71
0x13d761a toplev::run_self_tests()
        ../../gcc/toplev.cc:2266
The segfault line is
  /* Remove all pages from free page groups from the list.  */
  pp = &free_list->free_pages;
  while ((p = *pp) != NULL)
    if (p->group->in_use == 0)
      {
        *pp = p->next;
        free (p);
      }
    else
      pp = &p->next;
the if (p->group->in_use == 0) one.  And p->group in that case refers to
already freed memory.

Reply via email to