GCOV Cross Profiling: __gcov_flush() does not flush coverage data for shared libraries
Nicholas Mc Guire
der.herr@hofr.at
Fri Jun 19 18:58:00 GMT 2015
On Fri, 19 Jun 2015, Utpal Patel wrote:
> I am trying to get code coverage for an arm based embedded system.
> Using x86 for cross compilation.So basically, I have a cross profiling
> question.
>
> For the application I want to generate code coverage data, I have
> defined a signal handler inside which I call __gcov_flush() to flush
> code coverage data to .gcda files. I am sending SIGUSR1 to the
> application. The application uses multiple .so files where bulk of the
> code and logic is implemented.
>
> When I send the signal to the process, the .gcda files for just the
> application get created/updated. The .gcda files for the .so's are not
> created/updated at all.
>
> Is there a way to make __gcov_flush() flush all the coverage data for
> the .so's that the application is using?
>
> I dont want to force the application to exit() because that would
> defeat the purpose of what I am trying to do. I need to be able to
> dump coverage data for the application and the .so it uses at runtime.
> Please help!!
>
When you compiled your application with -fprofile-arcs -ftest-coverage
only the application was instrumented (conceptually a 64bit counters in
each basic block of the apps minimum spaning tree) and those counters
are what __gcov_flush() is dumping.
So if you want profiling infos from libraries you need to compile the library
for profiling as gcov is a static instrumentation and there is no way to get
infos from a .so without that it was compiled for profiling just like your
application. If the application is compiled for profiling then its data
will be dumped when you call __gcov_flush() but since you can not send
signals to a library to call some handler you would need to install some
other mechanism in the library e.g. brute force put a
int libdump(void) {
__gcov_flush();
}
into the library and call that from your application signal handler just like
you called __gcov_flush(); now.
This is from a trivial library that just provides an open
call that is a wrapper to libc open and the libdump function
2: 77:int libdump(void) {
2: 78: __gcov_flush();
1: 79: return 0;
-: 80:}
-: 81:/* we now can get code coverage of the library */
145: 82:int open(const char *pathname, int flags, mode_t mode) {
145: 83: return __open(pathname, flags, mode);
-: 84:}
the library is compiled with
gcc -fPIC -Wall -g -O2 -fprofile-arcs -ftest-coverage -shared -o libgctest.so.0 libgc.c
the application has the libdump() in the signal handler
int libdump(void);
void gc_handler(int signum)
{
printf("received signal\n");
__gcov_flush(); /* dump coverage data on receiving SIGUSR1 */
libdump(); /* and dump library converage data */
}
and is compiled with
gcc -O2 -fprofile-arcs -ftest-coverage hello.c -o hello -lgctest
kill -10 <PIDOF application>
will now dump the gcda of both application and library.
HTH
hofrat
ps: I have no clue why the count of the return 0 line in the libhandler does
not have a count of 2 as well....
More information about the Gcc-help
mailing list