Re: GCOV Cross Profiling: __gcov_flush() does not flush coverage data for shared libraries

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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....



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux