On 08/29/2018 11:17 AM, Richard Biener wrote: > On Wed, Aug 29, 2018 at 10:31 AM Martin Liška <mli...@suse.cz> wrote: >> >> Hello. >> >> Moving the thread from gcc ML into gcc-patches. That's first implementation >> of shared libgcov library. Currently inclusion of t-libgcov is added only >> to *-linux targets. Is it fine to add to all configurations that already >> include 't-slibgcc t-slibgcc-elf-ver'? >> >> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests. > > I understand this is to make profiling work with multiple DSOs (all > instrumented).
Yes. > But does this also make the case work when those DSOs are dlopened/dlclosed > multiple times? That works fine even now, when a DSO is loaded, __gcov_init is called and it registers gcov_info into __gcov_root. Following sample: #include <dlfcn.h> #include <assert.h> #include <unistd.h> int main() { for (int i = 0; i < 10; i++) { void *handle = dlopen ("libfoo.so", RTLD_NOW); assert (handle); void (*fn) (void) = dlsym (handle, "foo"); assert (fn); fn (); sleep (1); } return 0; } has: $ gcov-dump -l foo.gcda foo.gcda:data:magic `gcda':version `A82*' foo.gcda:stamp 2235622999 foo.gcda: a3000000: 22:PROGRAM_SUMMARY checksum=0x02bfe640 foo.gcda: counts=2, runs=1, sum_all=20, run_max=10, sum_max=10 foo.gcda: counter histogram: foo.gcda: 9: num counts=2, min counter=10, cum_counter=20 foo.gcda: 01000000: 3:FUNCTION ident=1636255671, lineno_checksum=0x2172766e, cfg_checksum=0xc0bbb23e foo.gcda: 01a10000: 4:COUNTERS arcs 2 counts foo.gcda: 0: 10 10 foo.gcda: 01af0000: 2:COUNTERS time_profiler 1 counts foo.gcda: 0: 1 which is fine, runs == 1 and arcs counter executed 10x. I understand that with the shared libgcov implementation this > library must be finalized last? If you do profiling, then you depend on libgcov, thus it's loaded before a DSO (or executable) is loaded. Wouldn't it be better to have some additional > object that lives in an executable only? Or do we want profiled DSOs without > profiling the executable using it? That should be rare, but it will be possible as __gcov_exit will be eventually called. Does that case work with the shared libgcov > (with dlopen/dlclose)? Yes, I've just tested that. Does it work when DSO1 is compiled with GCC N > and DSO2 is compiled with GCC N+1 where the libgcov ABI changed? For such case we have: /* Exactly one of these will be live in the process image. */ struct gcov_master __gcov_master = {GCOV_VERSION, 0}; ... and it's check in __gcov_init. > > I think we need a better understanding of the situation before jumping to > the conclusion that a shared libgcov is the solution. Maybe better isolating > the individual instances is better? It's undesired as seen in the PR. When doing profiling of indirect jumps we need have exactly one __gcov_indirect_call_callee. That's because one can do indirect calls that cross DSO boundaries. Martin > > Richard. > >> Martin >> >> libgcc/ChangeLog: >> >> 2018-08-28 Martin Liska <mli...@suse.cz> >> >> PR gcov-profile/84107 >> * Makefile.in: Build libgcov.so objects separately, >> add rule for libgcov.map and how the library >> is linked. >> * config.host: Add t-libgcov and t-libgcov-elf-ver >> to *-linux targets. >> * config/t-libgcov: New file. >> * config/t-libgcov-elf-ver: New file. >> * libgcov-driver.c: Declare function if new L_gcov_shared >> is defined. >> * libgcov-interface.c: Likewise. >> * libgcov-merge.c: Likewise. >> * libgcov-profiler.c: Likewise. >> * libgcov-std.ver.in: New file. >> * libgcov.h (__gcov_init): Remove ATTRIBUTE_HIDDEN. >> (__gcov_exit): Likewise. >> (__gcov_merge_add): Likewise. >> (__gcov_merge_time_profile): Likewise. >> (__gcov_merge_single): Likewise. >> (__gcov_merge_ior): Likewise. >> (__gcov_merge_icall_topn): Likewise. >> (gcov_sort_n_vals): Likewise. >> (__gcov_fork): Likewise. >> (__gcov_execl): Likewise. >> (__gcov_execlp): Likewise. >> (__gcov_execle): Likewise. >> (__gcov_execv): Likewise. >> (__gcov_execvp): Likewise. >> (__gcov_execve): Likewise. >> --- >> libgcc/Makefile.in | 56 ++++++++++++++++++++++++++++++--- >> libgcc/config.host | 2 +- >> libgcc/config/t-libgcov | 46 +++++++++++++++++++++++++++ >> libgcc/config/t-libgcov-elf-ver | 3 ++ >> libgcc/libgcov-driver.c | 4 +-- >> libgcc/libgcov-interface.c | 28 ++++++++--------- >> libgcc/libgcov-merge.c | 14 ++++----- >> libgcc/libgcov-profiler.c | 34 ++++++++++---------- >> libgcc/libgcov-std.ver.in | 53 +++++++++++++++++++++++++++++++ >> libgcc/libgcov.h | 31 +++++++++--------- >> 10 files changed, 209 insertions(+), 62 deletions(-) >> create mode 100644 libgcc/config/t-libgcov >> create mode 100644 libgcc/config/t-libgcov-elf-ver >> create mode 100644 libgcc/libgcov-std.ver.in >> >>