On 4/20/21 4:15 PM, Martin Sebor wrote:
On 4/20/21 2:36 PM, Martin Sebor wrote:
On 4/20/21 2:13 PM, Marek Polacek wrote:
On Tue, Apr 20, 2021 at 02:03:00PM -0600, Martin Sebor via Gcc wrote:
I have a static hash_map object that needs to persist across passes:

   static GTY(()) hash_map<tree, bitmap> *map;

I initialize the map like so:

   map = hash_map<tree, bitmap>::create_ggc (4);

But I see crashes when accessing the map after adding and removing
some number of entries in a few passes.  The crashes are due to
the map having been garbage-collected and the memory allocated to
it poisoned (it has the 0xa5a5a5a5a5a5a5a5 bit pattern that I see
in GDD being written into the map by poison_pages()).

I assumed marking the map pointer GTY(()) would keep the garbage
collector from touching the map.  Is there something else I need
to do to keep it from doing that?

Thanks
Martin

PS Just in case it matters, the bitmap in the table is allocated
via BITMAP_ALLOC() with a bitmap_obstack variable defined alongside
the map.

My sense is that this is the problem.  What happens if you use
BITMAP_GGC_ALLOC?

Same thing :(

I reduced the problem to the following patch/test case no involving
a bitmap or other pointers.  With it applied, GCC reliably crashes.
An example of a stack trace is below the patch.  What am I missing?

It seems that assigning the address of an object allocated by
ggc_alloc() (which presumably includes BITMAP_GGC_ALLOC()) to
a GTY-marked pointer "defeats" the purpose of the marker and
allows it to be garbage collected.  I suppose it's the spirit
of "garbage in, garbage out" (pun intended).  Since (if?)
the combination makes no sense I shouldn't be too surprised
that it results in a crash.

If it really doesn't make sense, it would be really nice if
the compiler warned about it.  I suppose expanding the GTY marker
to some GCC-internal attribute would make it possible to detect.

Alternatively, it would be helpful if this "gotcha" was at
least documented, both in the code and in the manual.  That
would have saved me a day's worth of frustrating debugging.
Let me put something together.


diff --git a/gcc/gimple.c b/gcc/gimple.c
index 87864f3d0dd..0e6cded166e 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -2749,11 +2749,21 @@ gimple_call_operator_delete_p (const gcall *stmt)
    return false;
  }

+typedef int_hash <int, 0, INT_MAX> i_hash;
+
+static GTY(()) hash_map<i_hash, int> *ii_map;
+
  /* Return true when STMT is builtins call.  */

  bool
  gimple_call_builtin_p (const gimple *stmt)
  {
+  if (!ii_map)
+    ii_map = ii_map->create_ggc (4);
+
+  uintptr_t key = gimple_code (stmt);
+  ii_map->put (key, key);
+
    tree fndecl;
    if (is_gimple_call (stmt)
        && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE


during GIMPLE pass: cplxlower0
/src/gcc/master/gcc/testsuite/gcc.dg/builtins-1.c:97:55: internal compiler error: Segmentation fault
0x1308b30 crash_signal
     /src/gcc/master/gcc/toplev.c:327
0xe7eaa0 bool simple_hashmap_traits<default_hash_traits<int_hash<int, 0, 2147483647> >, int>::is_empty<hash_map<int_hash<int, 0, 2147483647>, int, simple_hashmap_traits<default_hash_traits<int_hash<int, 0, 2147483647> >, int> >::hash_entry>(hash_map<int_hash<int, 0, 2147483647>, int, simple_hashmap_traits<default_hash_traits<int_hash<int, 0, 2147483647> >, int> >::hash_entry const&)
     /src/gcc/master/gcc/hash-map-traits.h:75
0xe7e36a hash_map<int_hash<int, 0, 2147483647>, int, simple_hashmap_traits<default_hash_traits<int_hash<int, 0, 2147483647> >, int> >::hash_entry::is_empty(hash_map<int_hash<int, 0, 2147483647>, int, simple_hashmap_traits<default_hash_traits<int_hash<int, 0, 2147483647> >, int> >::hash_entry const&)
     /src/gcc/master/gcc/hash-map.h:71
0xe7ea32 hash_table<hash_map<int_hash<int, 0, 2147483647>, int, simple_hashmap_traits<default_hash_traits<int_hash<int, 0, 2147483647> >, int> >::hash_entry, false, xcallocator>::is_empty(hash_map<int_hash<int, 0, 2147483647>, int, simple_hashmap_traits<default_hash_traits<int_hash<int, 0, 2147483647> >, int> >::hash_entry&)
     /src/gcc/master/gcc/hash-table.h:541
0xe7e89d hash_table<hash_map<int_hash<int, 0, 2147483647>, int, simple_hashmap_traits<default_hash_traits<int_hash<int, 0, 2147483647> >, int> >::hash_entry, false, xcallocator>::expand()
     /src/gcc/master/gcc/hash-table.h:819
0xe7e155 hash_table<hash_map<int_hash<int, 0, 2147483647>, int, simple_hashmap_traits<default_hash_traits<int_hash<int, 0, 2147483647> >, int> >::hash_entry, false, xcallocator>::find_slot_with_hash(int const&, unsigned int, insert_option)
     /src/gcc/master/gcc/hash-table.h:964
0xe7d9b8 hash_map<int_hash<int, 0, 2147483647>, int, simple_hashmap_traits<default_hash_traits<int_hash<int, 0, 2147483647> >, int> >::put(int const&, int const&)
     /src/gcc/master/gcc/hash-map.h:166
0xe7932f gimple_call_builtin_p(gimple const*)
     /src/gcc/master/gcc/gimple.c:2766
0xece684 maybe_fold_stmt
     /src/gcc/master/gcc/gimplify.c:3303
0xed888e gimplify_modify_expr
     /src/gcc/master/gcc/gimplify.c:5994
0xf03d14 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
     /src/gcc/master/gcc/gimplify.c:14083
0xedbf17 gimplify_stmt(tree_node**, gimple**)
     /src/gcc/master/gcc/gimplify.c:6877
0xec55f0 gimplify_and_add(tree_node*, gimple**)
     /src/gcc/master/gcc/gimplify.c:489
0xec5d8f internal_get_tmp_var
     /src/gcc/master/gcc/gimplify.c:642
0xec5dd6 get_formal_tmp_var(tree_node*, gimple**)
     /src/gcc/master/gcc/gimplify.c:663
0xf07a6b gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
     /src/gcc/master/gcc/gimplify.c:15072
0xf0d30a force_gimple_operand_1(tree_node*, gimple**, bool (*)(tree_node*), tree_node*)
     /src/gcc/master/gcc/gimplify-me.c:78
0xf0d3d7 force_gimple_operand_gsi_1(gimple_stmt_iterator*, tree_node*, bool (*)(tree_node*), tree_node*, bool, gsi_iterator_update)
     /src/gcc/master/gcc/gimplify-me.c:115
0xf0d490 force_gimple_operand_gsi(gimple_stmt_iterator*, tree_node*, bool, tree_node*, bool, gsi_iterator_update)
     /src/gcc/master/gcc/gimplify-me.c:141
0x13791c5 gimplify_build1(gimple_stmt_iterator*, tree_code, tree_node*, tree_node*)
     /src/gcc/master/gcc/tree-cfg.c:9249


Reply via email to