void ouch(int sig)
{
printf("OUCH: - I got signal %d\n", sig);
exit(0);
}
void a(){
printf("\t\t ---call a() function\n");
}
void c(){
printf("\t\t ---call c() function\n");
}
int b(){
printf("\t --- call b() function\n");
a();
c();
while (1)
{
}
return 0;
}
int main(){
struct sigaction act;
act.sa_handler = ouch;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGBUS, &act, 0);
printf(" main() function()\n");
b();
}
编译以上程序,
gcc -pg -g -o perf perf.c
程序正常运行结束后,会产生gmon.out. 但在某些情况下,因为程序不能正常退出,gmon.out是不能生成的。这时候我们需要添加一个信号处理函数,保证当收到某个信号时,自动调用exit函数,从而产生gmon.out.
在这个例子中,因为存在死循环,程序不能正堂退出,所以添加了信号处理函数。
当perf运行后,用kill -7 perf退出程序。然后运行gprof.
->qdbuild2:./perf
main() function()
--- call b() function
---call a() function
---call c() function
->qdbuild2:ps -ef | grep perf
jx 655 29541 99 12:09 pts/215 00:00:13 ./perf
->qdbuild2:kill -7 655
->qdbuild2:gprof perf gmon.out -l
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
50.52 8.26 8.26 b (perf.c:23 @ 4007ab)
50.52 16.53 8.26 b (perf.c:26 @ 4007b5)
0.00 16.53 0.00 1 0.00 0.00 a (perf.c:12 @ 400764)
0.00 16.53 0.00 1 0.00 0.00 b (perf.c:20 @ 40078e)
0.00 16.53 0.00 1 0.00 0.00 c (perf.c:16 @ 400779)
Call graph (explanation follows)
granularity: each sample hit covers 2 byte(s) for 0.06% of 16.53 seconds
index % time self children called name
0.00 0.00 1/1 b (perf.c:21 @ 400797) [11]
[3] 0.0 0.00 0.00 1 a (perf.c:12 @ 400764) [3]
-----------------------------------------------
0.00 0.00 1/1 main (perf.c:38 @ 400809) [24]
[4] 0.0 0.00 0.00 1 b (perf.c:20 @ 40078e) [4]
-----------------------------------------------
0.00 0.00 1/1 b (perf.c:23 @ 4007ab) [1]
[5] 0.0 0.00 0.00 1 c (perf.c:16 @ 400779) [5]
-----------------------------------------------
从gprof的输出我们可以得到,perf.c的23到26行占用大部分时间。然后我们可以对程序进行些优化。