linux的调试工具,Linux 调试工具

gprof

代码信息

代码:N皇后问题,N=14

bool place(int *result, int row){ for(int i = 1; i < row; i++) { if(result[i] == result[row] || abs(i-row) == abs(result[i] - result[row])) { return false; } } return true;}

调用关系

main->queen->recursion->place

profile 信息

-pg: 生成profile信息,供gprof使用  -g: 生成调试信息

g++ -pg -g queen.cpp -o queen

gmon.out 文件

root@ubuntu:~/gprof# ./queen 365596root@ubuntu:~/gprof# lsgmon.out queen queen.cpp

性能分析

函数级耗时 -p

gprof queen gmon.out -b -p % cumulative self self total time seconds seconds calls s/call s/call name 60.14 8.60 8.60 377901398 0.00 0.00 place(int*, int)22.48 11.81 3.21 1 3.21 14.21 recursion(int*, int, int, int&)16.78 14.21 2.40 3609962696 0.00 0.00 std::abs(int)

% time: 该函数占用总运行时间的百分比  cumulative seconds:累积时间,即上述列表中,self seconds累积和。  self seconds:运行该函数耗时,不包含子函数耗时。  calls:函数调用次数  self s/call:调用该函数一次的平均耗时。(self seconds / calls)。  total s/call:调用该函数一次的平均耗时,包括子函数。

recursion 自身运行一次平均需要3.21秒,若包含子函数,则平均需要14.21秒。place平均耗时均为0,是因为调用次数过多,而大部分调用,几乎可以瞬间完成。

place函数实际耗时为:2.40 + 8.60 = 11.00

行级耗时 -l

gprof queen gmon.out -b -l % cumulative self self total time seconds seconds calls ms/call ms/call name 50.77 7.26 7.26 place() (queen.cpp:9) 9.37 8.60 1.34 3609962696 0.00 0.00   std::abs() (cmath:99) 8.04 9.75 1.15 recursion() (queen.cpp:27)

函数调用图 -q

gprof queen gmon.out -b -qindex % time self children called name8.60 2.40 377901398/377901398 recursion(int*, int, int, int&) [3][4] 76.9 8.60 2.40 377901398 place(int*, int) [4]2.40 0.00 3609962696/3609962696 std::abs(int) [5]

self: 自身调用耗时  children: 子函数调用耗时

place 行首行尾[4]表明该列表分析place调用关系;377901398为调用次数。  recursion为place父函数;x/y,recursion调用place函数x次,程序共调用place函数y次。  abs为place子函数;x/y,place调用abs函数x次,程序供调用abs函数y次。  参考:How to read gprof output

代码直观显示 -A

bool place(int *result, int row) 377901398->{ for(int i = 1; i < row; i++) { if(result[i] == result[row] || abs(i-row) == abs(result[i] - result[row])) { return false; } } return true; }

实战

综上: 对于palce函数来说,其中的abs消耗时间较多,成为了瓶颈。

int diff_a = i - row;int diff_b = result[i] - result[row];if (diff_a == diff_b || diff_a == -diff_b){ return false;}

Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 82.62 8.48 8.48 377901398 0.00 0.00 place(int*, int) 17.38 10.27 1.78 1 1.78 10.27 recursion(int*, int, int, int&)

place消耗时间为8.48秒,比优化前11秒,节省了2.52秒。

strace

trace system calls and signals

int main(){ char text[256]; FILE *fp = fopen("pattern_text", "r"); while (fp && fgets(text, 256, fp)){ puts(text); } return 0;}

列出全部系统调用

strace ./a.out

root@ubuntu:~/strace# strace ./a.out  execve(“./a.out”, [“./a.out”], [/* 16 vars */]) = 0  brk(0) = 0x80a8000  ……

指定查看系统调用 -e

strace -e open ./a.outstrace -e trace=open,read ./a.out

open(“pattern_text”, O_RDONLY) = 3  read(3, “Hello World!\n”, 4096) = 13

显示文件名 -y

strace -y -e trace=open,read ./a.out

open(“pattern_text”, O_RDONLY) = 3  read(3, “Hello World!\n”, 4096) = 13

显示系统调用时间 -r -t

-r 相对时间,-t 绝对时间

strace -r -e write ./a.out

0.006490 write(1, “Hello World!\n”, 13Hello World!) = 13  0.007378 write(1, “\n”, 1) = 1

显示概略 -c

strace -c -e trace=read ./a.out

% time  seconds  usecs/call calls syscall   0.00 0.000000    0    3  read

多进程跟踪

-f 追踪fork  -ff 单独输出,输出文件名以-o指定文件名+pid

strace -f -ff -o rec -e write ./fork

追踪已运行进程 -p

strace -p 1645 -e write

信号追踪

void func(int signo){ printf("got signal\n");}int main(){ signal(SIGUSR1, func); sleep(100); return 0;}

nanosleep({100, 0}, {73, 160744108}) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)  — SIGUSR1 {si_signo=SIGUSR1, si_code=SI_USER, si_pid=914, si_uid=0} —  fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 0), …}) = 0

ltrace

A library call tracer。追踪库函数调用,用法与strace类似。

ltrace ./a.out

fopen(“pattern_text”, “r”) = 0x9d8a008  fgets(“Hello World!\n”, 256, 0x9d8a008) = 0xbfe01bec  puts(“Hello World!\n”Hello World!) = 14  fgets(nil, 256, 0x9d8a008) = 0

lsof

文件

#查看用户spch2008打开的文件lsof -u spch2008#多用户查询lsof -u spch2008,root#取反lsof -u ^spch2008#查看程序打开的文件lsof -c taf#查看进程打开的文件lsof -p pid#查看文件描述符关联的文件lsof -d fd #查看某个文件打开信息lsof file_path

网络

#查看打开的网络lsof -i#查看协议lsof -i udp#查看端口lsof -i :22#查看协议与端口lsof -i tcp:22#查看unix domain socket#lsof -U

组合

或的方式组合表达式

#查看某个进程打开的文件或某个程序打开的文件lsof -c taf -p 1039

且的方式组合表达式 -a

lsof -a -u spch2008 -i tcp

杂项

-t: 只输出pid

root@ubuntu:~/gprof# lsof -a -i -u spch2008COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEsshd 1039 spch2008 3u IPv4 10976 0t0 TCP 10.0.2.15:ssh->10.0.2.2:57083root@ubuntu:~/gprof# lsof -a -i -u spch2008 -t1039

可以用于某些操作,比如kill -9 `lsof -a -i -u spch2008 -t`

dmesg

The dmesg command is used to write the kernel messages in Linux and other Unix-like operating systems to standard output (which by default is the display screen).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值