On Thu, Jan 17, 2019 at 8:16 PM Michael Ploujnikov
<michael.ploujni...@oracle.com> wrote:
>
> Hi,
>
> I've been doing some investigations that required using a bitmap to keep 
> track of decl IDs and I ran into segmentation fault after my bitmap has been 
> loaded from a PCH. Attached is a short patch that can reliably reproduce my 
> problem. Looks like head->current is set to point to uninitialized memory for 
> some reason. Could someone with a strong understanding of GGC take a look and 
> let me know what I might be doing wrong and how to fix this?

If you're just doing investigation why do you care about PCH?

In any event I guess that bimaps are not supported by PCH because of
GTY(skip)ing the bitmap_head current member (so that's not saved).
I guess PCH writers/readers need to ignore skipping.

> I can reliably reproduce this with the following command:
>
> gdb --args /gcc/build/./gcc/cc1plus -nostdinc++ -nostdinc++ -I 
> /gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu -I 
> /gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include -I 
> /gcc/src/libstdc++-v3/libsupc++ -I /gcc/src/libstdc++-v3/include/backward -I 
> /gcc/src/libstdc++-v3/testsuite/util -iprefix 
> /gcc/build/gcc/../lib/gcc/x86_64-pc-linux-gnu/9.0.0/ -isystem 
> /gcc/build/./gcc/include -isystem /gcc/build/./gcc/include-fixed 
> -D_GNU_SOURCE -D _GNU_SOURCE -D LOCALEDIR=. -isystem 
> /gcc-install/x86_64-pc-linux-gnu/include -isystem 
> /gcc-install/x86_64-pc-linux-gnu/sys-include 
> /gcc/src/libstdc++-v3/testsuite/17_intro/headers/c++1998/all_c++200x_compatibility.cc
>  -quiet -dumpbase all_c++200x_compatibility.cc -mtune=generic -march=x86-64 
> -auxbase-strip all_c++200x_compatibility.s -g -O2 -Wc++11-compat -Werror 
> -version -fdiagnostics-color=never -fchecking=1 -fmessage-length=0 
> -fno-show-column -ffunction-sections -fdata-sections 
> -fno-diagnostics-show-caret -o all_c++200x_compatibility.s
>
> Here's a sample GDB session:
>
> Breakpoint 2, c_common_read_pch (pfile=0x31eafa0,
>     name=0x31fc950 
> "/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/extc++.h.gch/O2g.gch",
>  fd=9,
>     orig_name=0x31ff0e0 
> "/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/extc++.h")
>  at ../../src/gcc/c-family/c-pch.c:348
> 348       timevar_push (TV_PCH_RESTORE);
> (gdb) enable 1
> (gdb) c
> Continuing.
>
> Breakpoint 1, allocate_decl_uid () at ../../src/gcc/tree.c:1024
> 1024      if (!all_ids)
> (gdb) p *all_ids
> $8 = {static crashme = {elements = 0x0, heads = 0x0, obstack = {chunk_size = 
> 0, chunk = 0x0,
>       object_base = 0x0, next_free = 0x0, chunk_limit = 0x0, temp = {i = 0, p 
> = 0x0},
>       alignment_mask = 0, chunkfun = {plain = 0x0, extra = 0x0}, freefun = 
> {plain = 0x0,
>         extra = 0x0}, extra_arg = 0x0, use_extra_arg = 0, maybe_empty_object 
> = 0,
>       alloc_failed = 0}}, indx = 1790, tree_form = true, first = 0x1002dd9950,
>   current = 0x7fdf0f865370, obstack = 0x0}
> (gdb) n
> 1029      gcc_assert (all_ids->tree_form);
> (gdb) n
> 1030      int new_id = next_decl_uid++;
> (gdb) n
> 1031      gcc_assert (!bitmap_bit_p (all_ids, new_id));
> (gdb) s
> bitmap_bit_p (head=0x10006cc3c0, bit=229123) at ../../src/gcc/bitmap.c:963
> 963       unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
> (gdb) p indx
> $10 = 32767
> (gdb) s
> 968       if (!head->tree_form)
> (gdb) s
> 971         ptr = bitmap_tree_find_element (head, indx);
> (gdb) s
> bitmap_tree_find_element (head=0x10006cc3c0, indx=1790) at 
> ../../src/gcc/bitmap.c:546
> 546       if (head->current == NULL
> (gdb) p head->current
> $11 = (bitmap_element *) 0x7fdf0f865370
> (gdb) p *head->current
> Cannot access memory at address 0x7fdf0f865370
> (gdb) c
> Continuing.
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x0000000000c4866b in bitmap_bit_p (head=0x10006cc3c0, bit=229123) at 
> ../../src/gcc/bitmap.c:978
> 978       return (ptr->bits[word_num] >> bit_num) & 1;
>
>
>
>
> Alternatively I tried using a hash_set to keep track of ids:
>
> typedef int_hash <unsigned, UINT_MAX> unsigned_int_hasher;
> static GTY(()) hash_set<unsigned_int_hasher> *all_ids;
>
> But I couldn't figure out how to write the required gt_ggc_mx and gt_pch_nx 
> methods.
>
>
> Any help would be greatly appreciated!
>
>
> - Michael

Reply via email to