diff mbox

a new libgcov interface: __gcov_dump_all

Message ID CAAkRFZLuXyevU9xUmq1AFKEq+JjTH-G=Oe0pWWY=MkkxMR5jHA@mail.gmail.com
State New
Headers show

Commit Message

Xinliang David Li July 18, 2014, 9:41 p.m. UTC
Hi, the following patch implements a new dumper interface to allow
dumping of profile data for all instrumented shared libraries.

For good reasons, existing libgcov implements the dumping on a
per-shared library basis (i.e., gcov_exit is hidden, gcov_list is file
static). This allows each shared library's profile data to be dumped
independently with separate summary data. The downside is that there
is no interface that can be invoked to dump profile data for all
shared modules.

The attached patch does that. Ok for trunk after testing?

thanks,

David

Comments

Nathan Sidwell July 20, 2014, 7:42 p.m. UTC | #1
On 07/18/14 22:41, Xinliang David Li wrote:
> Hi, the following patch implements a new dumper interface to allow
> dumping of profile data for all instrumented shared libraries.
>
> For good reasons, existing libgcov implements the dumping on a
> per-shared library basis (i.e., gcov_exit is hidden, gcov_list is file
> static). This allows each shared library's profile data to be dumped
> independently with separate summary data. The downside is that there
> is no interface that can be invoked to dump profile data for all
> shared modules.

This seems like useful functionality, but I don't think this is the right way to 
do this.  You're duplicating the gcov info object chain.  Why can't you expose 
gcov_list from gcov-driver.c (possibly with a different name, of course?

nathan
Xinliang David Li July 20, 2014, 8:38 p.m. UTC | #2
The gcov_info chain is not duplicated -- there is already one chain
(linking only modules of the library) per shared library in current
implementation.  My change does not affect underlying behavior at all
-- it merely introduces a new interface to access private dumper
methods associated with shared libs.

David



On Sun, Jul 20, 2014 at 12:42 PM, Nathan Sidwell <nathan@acm.org> wrote:
> On 07/18/14 22:41, Xinliang David Li wrote:
>>
>> Hi, the following patch implements a new dumper interface to allow
>> dumping of profile data for all instrumented shared libraries.
>>
>> For good reasons, existing libgcov implements the dumping on a
>> per-shared library basis (i.e., gcov_exit is hidden, gcov_list is file
>> static). This allows each shared library's profile data to be dumped
>> independently with separate summary data. The downside is that there
>> is no interface that can be invoked to dump profile data for all
>> shared modules.
>
>
> This seems like useful functionality, but I don't think this is the right
> way to do this.  You're duplicating the gcov info object chain.  Why can't
> you expose gcov_list from gcov-driver.c (possibly with a different name, of
> course?
>
> nathan
Nathan Sidwell July 21, 2014, 6:12 a.m. UTC | #3
On 07/20/14 21:38, Xinliang David Li wrote:
> The gcov_info chain is not duplicated -- there is already one chain
> (linking only modules of the library) per shared library in current
> implementation.  My change does not affect underlying behavior at all
> -- it merely introduces a new interface to access private dumper
> methods associated with shared libs.

ah, got it.  thanks for clarifying.  Can't help thinking gcov_init should be 
doing this, and wondering about dlload/dlclose.  Let me think

nathan
diff mbox

Patch

Index: libgcc/ChangeLog
===================================================================
--- libgcc/ChangeLog	(revision 212682)
+++ libgcc/ChangeLog	(working copy)
@@ -1,3 +1,9 @@ 
+2014-07-18  Xinliang David Li  <davidxl@google.com>
+
+	* libgcov-driver.c: Force __gcov_dump to be exported
+	* libgcov-interface.c (register_dumper): New function.
+	(__gcov_dump_all): Ditto.
+
 2014-07-14  Richard Biener  <rguenther@suse.de>
 
 	* libgcov.h (struct gcov_fn_info): Make ctrs size 1.
Index: libgcc/libgcov-driver.c
===================================================================
--- libgcc/libgcov-driver.c	(revision 212682)
+++ libgcc/libgcov-driver.c	(working copy)
@@ -55,6 +55,13 @@  extern void set_gcov_dump_complete (void
 extern void reset_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
 extern int get_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
 extern void set_gcov_list (struct gcov_info *) ATTRIBUTE_HIDDEN;
+  
+#ifndef IN_GCOV_TOOL
+
+/* Creates strong reference to force _gcov_dump.o to be linked
+   in shared library for exported interfaces.  */
+void (*__gcov_dummy_ref)(void) = &__gcov_dump;
+#endif
 
 struct gcov_fn_buffer
 {
Index: libgcc/libgcov-interface.c
===================================================================
--- libgcc/libgcov-interface.c	(revision 212682)
+++ libgcc/libgcov-interface.c	(working copy)
@@ -115,6 +115,43 @@  __gcov_dump (void)
   set_gcov_dump_complete ();
 }
 
+typedef void (*gcov_dumper_type) (void);
+struct dumper_entry
+{
+  gcov_dumper_type dumper;
+  struct dumper_entry *next_dumper;
+};
+
+static struct dumper_entry this_dumper = {&__gcov_dump, 0};
+
+/* global dumper list with default visibilty. */
+struct dumper_entry *__gcov_dumper_list;
+
+
+__attribute__((constructor))
+static void 
+register_dumper (void)
+{
+  this_dumper.next_dumper = __gcov_dumper_list;
+  __gcov_dumper_list = &this_dumper;
+}
+
+/* Public interface to dump profile data for all shared libraries
+   via registered dumpers from the libraries. This interface
+   has default visibility (unlike gcov_dump which has hidden
+   visbility.  */
+
+void
+__gcov_dump_all (void)
+{
+  struct dumper_entry *dumper = __gcov_dumper_list;
+  while (dumper)
+   {
+     dumper->dumper ();
+     dumper = dumper->next_dumper;
+   }
+}
+
 #endif /* L_gcov_dump */
 
 
Index: libgcc/libgcov.h
===================================================================
--- libgcc/libgcov.h	(revision 212682)
+++ libgcc/libgcov.h	(working copy)
@@ -218,8 +218,14 @@  extern void __gcov_flush (void) ATTRIBUT
 /* Function to reset all counters to 0.  */
 extern void __gcov_reset (void);
 
-/* Function to enable early write of profile information so far.  */
-extern void __gcov_dump (void);
+/* Function to enable early write of profile information so far.  
+   __GCOV_DUMP is also used by __GCOV_DUMP_ALL. The latter 
+   depends on __GCOV_DUMP to have hidden or protected visibility
+   so that each library has its own copy of the registered dumper.  */
+extern void __gcov_dump (void) ATTRIBUTE_HIDDEN;
+
+/* Call __gcov_dump registered from each shared library.  */
+void __gcov_dump_all (void);
 
 /* The merge function that just sums the counters.  */
 extern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;