[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