On 12/16/20 10:08 AM, Iain Sandoe wrote:
This will break bootstrap on targets without init_priority (e.g. Darwin)

All right, based on the chat on IRC, I suggest using C static constructor
with corresponding priority.

Ready to be installed?
Thanks,
Martin
>From 4ecf4f8df8d5b6b75cfe7cc5df90176e0a5014b8 Mon Sep 17 00:00:00 2001
From: Martin Liska <mli...@suse.cz>
Date: Wed, 16 Dec 2020 10:02:10 +0100
Subject: [PATCH] Fix --enable-gather-detailed-mem-stats build.

The build suffers from the static initialization order fiasco:

==30085== Invalid read of size 4
==30085==    at 0x1D451CD: hash_table_mod1 (hash-table.h:344)
==30085==    by 0x1D451CD: hash_table<hash_map<mem_alloc_description<vec_usage>::mem_location_hash, vec_usage*, simple_hashmap_traits<default_hash_traits<mem_alloc_description<vec_usage>::mem_location_hash>, vec_usage*> >::hash_entry, false, xcallocator>::find_with_hash(mem_location* const&, unsigned int) (hash-table.h:911)
==30085==    by 0x1D411F7: get (hash-map.h:185)
==30085==    by 0x1D411F7: register_descriptor (mem-stats.h:417)
==30085==    by 0x1D411F7: register_descriptor (mem-stats.h:451)
==30085==    by 0x1D411F7: vec_prefix::register_overhead(void*, unsigned long, unsigned long, char const*, int, char const*) (vec.c:132)
==30085==    by 0xA2DB28: reserve<loc_spans::span> (vec.h:294)
==30085==    by 0xA2DB28: vec<loc_spans::span, va_heap, vl_ptr>::reserve(unsigned int, bool, char const*, int, char const*) [clone .isra.0] (vec.h:1778)
==30085==    by 0x9039C7: reserve_exact (vec.h:1798)
==30085==    by 0x9039C7: create (vec.h:1813)
==30085==    by 0x9039C7: loc_spans (module.cc:3281)
==30085==    by 0x9039C7: __static_initialization_and_destruction_0 (module.cc:3340)
==30085==    by 0x9039C7: _GLOBAL__sub_I_map_context_from (gt-cp-module.h:360)
==30085==    by 0x1E00F6C: __libc_csu_init (elf-init.c:89)
==30085==    by 0x4FFF0DD: (below main) (in /lib64/libc-2.32.so)
==30085==  Address 0x28 is not stack'd, malloc'd or (recently) free'd

So vec_mem_desc is not initialized before a static member in module.cc.
We can fix it by using constructor attribute.

gcc/ChangeLog:

	* vec.c (init_vec_mem_desc): New function.
	(vec_prefix::register_overhead): Use vec_mem_desc as pointer
	now.
	(vec_prefix::release_overhead): Likewise.
	(dump_vec_loc_statistics): Likewise.
---
 gcc/vec.c | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/gcc/vec.c b/gcc/vec.c
index a28899170ed..ac91400c2df 100644
--- a/gcc/vec.c
+++ b/gcc/vec.c
@@ -121,7 +121,17 @@ public:
 };
 
 /* Vector memory description.  */
-static mem_alloc_description <vec_usage> vec_mem_desc;
+static mem_alloc_description <vec_usage> *vec_mem_desc;
+
+/* Static constructor for vec_mem_desc that happens before ithe initialization
+   of all static variables.  */
+
+static void
+__attribute__((constructor (101)))
+init_vec_mem_desc (void)
+{
+  vec_mem_desc = new mem_alloc_description<vec_usage> ();
+}
 
 /* Account the overhead.  */
 
@@ -129,10 +139,10 @@ void
 vec_prefix::register_overhead (void *ptr, size_t elements,
 			       size_t element_size MEM_STAT_DECL)
 {
-  vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN, false
-				    FINAL_PASS_MEM_STAT);
+  vec_mem_desc->register_descriptor (ptr, VEC_ORIGIN, false
+				     FINAL_PASS_MEM_STAT);
   vec_usage *usage
-    = vec_mem_desc.register_instance_overhead (elements * element_size, ptr);
+    = vec_mem_desc->register_instance_overhead (elements * element_size, ptr);
   usage->m_element_size = element_size;
   usage->m_items += elements;
   if (usage->m_items_peak < usage->m_items)
@@ -145,11 +155,11 @@ void
 vec_prefix::release_overhead (void *ptr, size_t size, size_t elements,
 			      bool in_dtor MEM_STAT_DECL)
 {
-  if (!vec_mem_desc.contains_descriptor_for_instance (ptr))
-    vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN,
+  if (!vec_mem_desc->contains_descriptor_for_instance (ptr))
+    vec_mem_desc->register_descriptor (ptr, VEC_ORIGIN,
 				      false FINAL_PASS_MEM_STAT);
-  vec_usage *usage = vec_mem_desc.release_instance_overhead (ptr, size,
-							     in_dtor);
+  vec_usage *usage = vec_mem_desc->release_instance_overhead (ptr, size,
+							      in_dtor);
   usage->m_items -= elements;
 }
 
@@ -183,7 +193,7 @@ vec_prefix::calculate_allocation_1 (unsigned alloc, unsigned desired)
 void
 dump_vec_loc_statistics (void)
 {
-  vec_mem_desc.dump (VEC_ORIGIN);
+  vec_mem_desc->dump (VEC_ORIGIN);
 }
 
 #if CHECKING_P
-- 
2.29.2

Reply via email to