Linux 调试工具
2016-05-11 16:09
471 查看
gprof
代码信息
代码:N皇后问题,N=14bool 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 365596 root@ubuntu:~/gprof# ls gmon.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>(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<int>() (cmath:99) 8.04 9.75 1.15 recursion() (queen.cpp:27)
函数调用图
-q
gprof queen gmon.out -b -q index % time self children called name 8.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>(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 signalsint 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.out strace -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
</root/strace/pattern_text>,
“Hello World!\n”, 4096) = 13
显示系统调用时间
-r
-t
-r 相对时间,-t 绝对时间
strace -r -e write ./a.out
0.006490write(1, “Hello World!\n”, 13Hello World!) = 13
0.007378write(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 spch2008 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1039 spch2008 3u IPv4 10976 0t0 TCP 10.0.2.15:ssh->10.0.2.2:57083 root@ubuntu:~/gprof# lsof -a -i -u spch2008 -t 1039
可以用于某些操作,比如
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).
相关文章推荐
- Linux inotify监听文件变化机制
- 每天一个linux命令-scp
- 在ubtuntu中使用包管理器 linux-brew
- Linux-2.查看硬件信息-cpu
- 每天一个Linux命令-chmod
- linux 进程组 作业 会话
- Linux 系统监测工具
- Linux系统性能统计工具Sar和实时系统性能监控脚本
- linux系统swappiness参数在内存与交换分区间优化
- 安装centos6.3
- centos6.4下编译安装 python2.7
- Elasticsearch索引(company)_Centos下CURL增删改
- IMUNES on Linux
- libcurl库 windows,linux 编译使用
- Linux内核中的printf实现【转】
- CentOS release (Linux)上无法识别NTFS格式U盘的解决方法
- centos 7,pip安装
- kali linux Python 黑客编程1 开发环境初始化
- linux下php环境配置
- Linux文件系统基本操作(mount挂载,umount卸载)