您的位置:首页 > 运维架构 > Linux

Linux 调试工具

2016-05-11 16:09 471 查看


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
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 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.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.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 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).
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: