开发者

Get gprof to profile based on wall-clock time?

开发者 https://www.devze.com 2022-12-29 15:26 出处:网络
My understanding is that by default gprof takes into account CPU time. Is there a way to get it to profile based on wall-clock time?

My understanding is that by default gprof takes into account CPU time. Is there a way to get it to profile based on wall-clock time?

My program does a lot of disk i/o, so the CPU time it uses only represents a fraction of the actual execution time. I need to know which portions of the disk i/o take开发者_开发技巧 up the most time.


You can measure wall-clock time by using profiler from google-perftools. To switch google profiler to wall-clock mode, set the environment variable CPUPROFILE_REALTIME=1.


gprof won't do this. Look at this.

And this.

In a nutshell: Under gdb, get it running and do Ctrl-Break or Ctrl-C 10 times at random, and display the call stack. If your I/O is taking (for example) 60% of the time, then on (roughly) 6 out of 10 pauses, you will see it in the writebuf or readbuf routine, and the lines of code requesting that I/O will be clearly displayed on the stack.

You could also use lsstack to get the same information.


You can use strace or cachegrind to profile the code properly. strace will give you details of time spent in system calls and cachegrind will give detailed analysis of resource utilization.


It is very easy to change gprof to do wall-clock profiling. The only 8 chars to replace are:

ITIMER_PROF -> ITIMER_REAL

SIGPROF -> SIGALRM

in the file glibc/sysdeps/posix/profil.c, function __profil, near the calls to setitimer and sigaction (more exact __Setitimer and __sigaction)

After the change any program which uses SIGALRM will be broken and any program which have no blocking-syscall restarting code can give wrong results.

Also, you can directly change int values in glibc binary (please, dont do this on system wide libc.so, make a separate copy and give it to the program with LD_LIBRARY_PATH)

For binary patch, ITIMER_PROF is 2; ITIMER_REAL is 0; SIGPROF is 27 (0x1b); SIGALRM is 14 (0x0e). There are two places for each constant in function profil of glibc.

Another way is to write a ptrace-debugger, which will change arguments of setitimer and sigaction functions at run-time.


You can do this using the -finstrument-functions option with the gcc compiler. That will get a custom function called at entry/exit point of any function, just need to provide a couple of function callbacks (__cyg_profile_func_enter and __cyg_profile_func_exit).

You can find more details by looking up the -finstrument-functions option in the gcc manual.

There is also a good post on Balau's technical blog that provides an end to end overview/example of how this works: Trace and profile function calls with GCC

0

精彩评论

暂无评论...
验证码 换一张
取 消