How to add compilation for profiling to static library?

2k views Asked by At

My project currently has a library that is static linked (compiled with gcc and linked with ar), but I am currently trying to profile my whole entire project with gprof, in which I would also like to profile this statically linked library. Is there any way of going about doing this?

Gprof requires that you provide -pg to GCC for compilation and -pg to the linker. However, ar complains when -pg is added to the list of flags for it.

1

There are 1 answers

0
John Saxton On BEST ANSWER

I haven't used gprof in a long time, but is -pg even a valid argument to ar? Does profiling work if you compile all of the objects with -pg, then create your archive without -pg?

If you can't get gprof to work, gperftools contains a CPU profiler which I think should work very well in this case. You don't need to compile your application with any special flags, and you don't need to try to change how your static library is linked.

Before starting, there are two tradeoffs involved with using gperftools that you should be aware of:

  • gperftools is a sampling profiler. As such, your results won't be 100% accurate, but they should be really good. The big upside to using a sampling profiler is that it won't really slow your application down.
  • In multithreaded applications, in my experience, gperftools will only profile the main thread. The only way I've been able to successfully profile worker threads is by adding profiling code to my application. With that said, profiling the main thread shouldn't require any code changes.

There are lots of different ways to use gperftools. My preferred way is to load the gperftools library with $LD_PRELOAD, specify a logging destination with $CPUPROFILE, and maybe bump up the sample frequency with $CPUPROFILE_FREQUENCY before starting my application up. Something like this:

 export LD_PRELOAD=/usr/lib/libprofiler.so
 export CPUPROFILE=/tmp/prof.out
 export CPUPROFILE_FREQUENCY=10000
 ./my_application

This will write a bunch of profiling information to /tmp/prof.out. You can run a post-processing script to convert this file into something human readable. There are lots of supported output formats -- my preferred one is callgrind:

google-pprof --callgrind /path/to/my_application /tmp/prof.out > callgrind.dat
kcachegrind callgrind.dat &

This should provide a nice view of where your program is spending its time.

If you're interested, I spent some time over the weekend learning how to use gperftools to profile I/O bound applications, and I documented a lot of my findings here. There's a lot of overlap with what you're trying to do, so maybe it will be helpful.