[Bug gcov-profile/96913] gcc-11: __gcov_merge_topn hangs

slyfox at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Sep 4 15:26:57 GMT 2020


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

--- Comment #2 from Sergei Trofimovich <slyfox at gcc dot gnu.org> ---
(In reply to Sergei Trofimovich from comment #0)
> The hang happens on real tauthon-2.8.2 interpreter from PR96394 (no nice
> reproducer yet).
> 
> In this instance I tried to build tauthon-2.8.2 against gcc-master. It hangs
> early when tries to merge topn entry:
> 
> """
> #0  0x00007fd73865e0ce in __GI___libc_read (fd=3, buf=0x406284
> <__gcov_var+36>, nbytes=4096) at ../sysdeps/unix/sysv/linux/read.c:26
> #1  0x00007fd7385f0090 in __GI__IO_file_xsgetn (fp=0x1295bc0,
> data=<optimized out>, n=4096) at libioP.h:948
> #2  0x00007fd7385e4d1f in __GI__IO_fread (buf=0x406284 <__gcov_var+36>,
> size=1, count=4096, fp=0x1295bc0) at iofread.c:38
> #3  0x00007fd72ab4237e in gcov_read_words (words=2) at
> ../../../gcc/libgcc/../gcc/gcov-io.c:491
> #4  0x00007fd72ab42483 in __gcov_read_counter () at
> ../../../gcc/libgcc/../gcc/gcov-io.c:528
> #5  0x00007fd72ab4190e in gcov_get_counter_target () at
> ../../../gcc/libgcc/libgcov.h:383
> #6  0x00007fd72ab41c6b in __gcov_merge_topn (counters=0x7fd72ab4d320
> <__gcov4.encoder_clear>, n_counters=24) at
> ../../../gcc/libgcc/libgcov-merge.c:114
> #7  0x00007fd72ab43569 in merge_one_data (
>     filename=0x1154290
> "/tmp/portage/dev-lang/tauthon-2.8.2/work/x86_64-pc-linux-gnu/build/temp.
> linux-x86_64-2.8/tmp/portage/dev-lang/tauthon-2.8.2/work/tauthon-2.8.2/
> Modules/_json.gcda", gi_ptr=0x7fd72ab4a180, summary=0x7ffde7d6e9c0) at
> ../../../gcc/libgcc/libgcov-driver.c:314
> #8  0x00007fd72ab43b1a in dump_one_gcov (gi_ptr=0x7fd72ab4a180,
> gf=0x7ffde7d6ea00, run_counted=0, run_max=125)
>     at ../../../gcc/libgcc/libgcov-driver.c:492
> #9  0x00007fd72ab43cba in gcov_do_dump (list=0x7fd72ab4a180, run_counted=0)
> at ../../../gcc/libgcc/libgcov-driver.c:555
> #10 0x00007fd72ab43d28 in __gcov_dump_one (root=0x7fd72ab4e5c0
> <__gcov_root>) at ../../../gcc/libgcc/libgcov-driver.c:578
...
> 
> Looks like the problem is in decoding of some tag in __gcov_merge_topn().
> There count of entries is huge:
> 
> """
> (gdb) frame 6
> #6  0x00007fd72ab41c6b in __gcov_merge_topn (counters=0x7fd72ab4d320
> <__gcov4.encoder_clear>, n_counters=24) at
> ../../../gcc/libgcc/libgcov-merge.c:114
> 114               gcov_type value = gcov_get_counter_target ();
> (gdb) list __gcov_merge_topn
> 96         -- counter
> 97         */
> 98
> 99      void
> 100     __gcov_merge_topn (gcov_type *counters, unsigned n_counters)
> 101     {
> 102       gcc_assert (!(n_counters % GCOV_TOPN_MEM_COUNTERS));
> 103
> 104       for (unsigned i = 0; i < (n_counters / GCOV_TOPN_MEM_COUNTERS);
> i++)
> 105         {
> (gdb)
> 106           /* First value is number of total executions of the profiler. 
> */
> 107           gcov_type all = gcov_get_counter_ignore_scaling (-1);
> 108           gcov_type n = gcov_get_counter_ignore_scaling (-1);
> 109
> 110           counters[GCOV_TOPN_MEM_COUNTERS * i] += all;
> 111
> 112           for (unsigned j = 0; j < n; j++)
> 113             {
> 114               gcov_type value = gcov_get_counter_target ();
> 115               gcov_type count = gcov_get_counter_ignore_scaling (-1);
> (gdb)
> 116
> 117               // TODO: we should use atomic here
> 118               gcov_topn_add_value (counters + GCOV_TOPN_MEM_COUNTERS *
> i, value,
> 119                                    count, 0, 0);
> 120             }
> 121         }
> 122     }
> 123     #endif /* L_gcov_merge_topn */
> 124
> 125     #endif /* inhibit_libc */

> (gdb) print n
> $1 = 140325305737200

I looks like __gconv_merge_topn() is applied to 'indirect_call' counters
contents. But it's content does not seem to match dynamic topn structure:

$ x86_64-pc-linux-gnu-gcov-dump -l _json.gcda

...
_json.gcda:    01a70000:   0:COUNTERS topn 0 counts
_json.gcda:    01a90000:  48:COUNTERS indirect_call 24 counts
_json.gcda:                   0: 1 1 140325305737168 1 1 140325305737200 0 0
_json.gcda:                   8: 0 0 0 0 0 0 0 0
_json.gcda:                  16: 0 0 0 0 0 0 0 0
...

Note how 140325305737200 is in the middle of topn.

My wild guess is that before

  commit 871e5ada6d53d5eb495cc9f323983f347487c1b2
  Author: Martin Liska <mliska@suse.cz>
  Date:   Fri Jan 31 13:10:14 2020 +0100

    Make TOPN counter dynamically allocated.

both indirect_call and topn had the same fixed n-value structure and were ~ok
to be merged with __gconv_merge_topn().

But now topn got a special 0-values case (why did we emit it at all?) that
merger can't handle and gets slightly past the beginning of 'indirect_call'
section.


More information about the Gcc-bugs mailing list