一般调试linux程序,使用gdb即可!但是如果要对程序进行性能分析,或者没有办法使用gdb调试的时候,pstack和strace会排上大用场!!!!
pstack
sudo apt install pstack
pstack命令⽤来显示每个进程的调⽤栈。可以使⽤pstack来查看进程正在挂起的执⾏⽅法,也可以⽤来查看进程的本地线程堆栈。它实际上是gstack
的一个链接,而gstack本身是基于gdb封装的shell脚本。pstack
是gdb的一部分,如果系统没有pstack命令,使用yum搜索安装gdb
即可。
使⽤⽅式:pstack 进程ID
[root@VM_0_3_centos ~]# pstack 25901
Thread 2 (Thread 0x7f950fd02700 (LWP 25902)):
#0 0x00007f9514a1ff73 in select () from /usr/lib64/libc.so.6
#1 0x00007f95136b95a5 in apr_sleep () from /usr/lib64/libapr-1.so.0
#2 0x00007f9514645f19 in ?? ()
#3 0x0000000001186ec0 in ?? ()
#4 0x0000000001186ec0 in ?? ()
#5 0x00007f950fd01d60 in ?? ()
#6 0x00007f95146a3d9e in ?? ()
#7 0x0000000001184da0 in ?? ()
#8 0x0000000000000000 in ?? ()
Thread 1 (Thread 0x7f9515b348c0 (LWP 25901)):
#0 0x00007f9514a29483 in epoll_wait () from /usr/lib64/libc.so.6
#1 0x000000000048604f in CEventDispatch::StartDispatch (this=0x1195600,
wait_timeout=100) at /root/im/0voice_im/server/src/base/EventDispatch.cpp:365
#2 0x0000000000479ad2 in netlib_eventloop (wait_timeout=100) at
/root/im/0voice_im/server/src/base/netlib.cpp:160
#3 0x000000000046f598 in main (argc=1, argv=0x7ffc278e13a8) at
/root/im/0voice_im/server/src/login_server/login_server.cpp:132
strace
系统调⽤⼯具,是Linux系统下的⼀款程序调试⼯具,⽤来监控⼀个应⽤程序所使⽤的 系统调⽤,通过它可以跟踪系统调⽤,让你熟悉⼀个Linux程序在背后是怎么⼯作的。 适⽤于想研究Linux底层的⼯作机制的场景。多用于程序性能分析!
参数
-c 统计每⼀系统调⽤的所执⾏的时间,次数和出错的次数等.
-d 输出strace关于标准错误的调试信息.
-f 跟踪由fork调⽤所产⽣的⼦进程.
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.
-F 尝试跟踪vfork调⽤.在-f时,vfork不被跟踪.
-h 输出简要的帮助信息.
-i 输出系统调⽤的⼊⼝指针.
-q 禁⽌输出关于脱离的消息.
-r 打印出相对时间关于,,每⼀个系统调⽤.
-t 在输出中的每⼀⾏前加上时间信息.
-tt 在输出中的每⼀⾏前加上时间信息,微秒级.
-ttt 微秒级输出,以秒了表示时间.
-T 显示每⼀调⽤所耗的时间.
-v 输出所有的系统调⽤.⼀些调⽤关于环境变量,状态,输⼊输出等调⽤由于使⽤频繁,默认不输出.
-V 输出strace的版本信息.
-x 以⼗六进制形式输出⾮标准字符串
-xx 所有字符串以⼗六进制形式输出.
-a column 设置返回值的输出位置.默认 为40.
-e expr 指定⼀个表达式,⽤来控制如何跟踪.格式如下:
[qualifier=][!]value1[,value2]...
qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之⼀.value是⽤来限定的符号或数字.
默认的 qualifier是 trace.感叹号是否定符号.例如:
-eopen等价于 -e trace=open,表示只跟踪open调⽤.⽽-etrace!=open表示跟踪除了open以外的其他调
⽤.有两个特殊的符号 all 和 none.
注意有些shell使⽤!来执⾏历史记录⾥的命令,所以要使⽤\\.
-e trace=set
只跟踪指定的系统 调⽤.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调⽤.默认的为
set=all.
-e trace=file
只跟踪有关⽂件操作的系统调⽤.
-e trace=process
只跟踪有关进程控制的系统调⽤.
-e trace=network
跟踪与⽹络有关的所有系统调⽤.
-e strace=signal
跟踪所有与系统信号有关的 系统调⽤
-e trace=ipc
跟踪所有与进程通讯有关的系统调⽤
-e abbrev=set
设定 strace输出的系统调⽤的结果集.-v 等与 abbrev=none.默认为abbrev=all.
-e raw=set
将指 定的系统调⽤的参数以⼗六进制显示.
-e signal=set
指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号.54
-e read=set
输出从指定⽂件中读出 的数据.例如:
-e read=3,5
-e write=set
输出写⼊到指定⽂件中的数据.
-o filename
将strace的输出写⼊⽂件filename
-p pid
跟踪指定的进程pid.
-s strsize
指定输出的字符串的最⼤⻓度.默认为32.⽂件名⼀直全部输出.
-u username
以username 的UID和GID执⾏被跟踪的命令
实时查看进程
[root@VM_0_3_centos ~]# strace -p 25901
strace: Process 25901 attached
gettimeofday({1566530771, 437813}, NULL) = 0
epoll_wait(6, [], 1024, 100) = 0
gettimeofday({1566530771, 538318}, NULL) = 0
gettimeofday({1566530771, 538424}, NULL) = 0
gettimeofday({1566530771, 538458}, NULL) = 0
epoll_wait(6, [], 1024, 100) = 0
gettimeofday({1566530771, 638872}, NULL) = 0
epoll_wait(6, [], 1024, 100) = 0
gettimeofday({1566530771, 739125}, NULL) = 0
epoll_wait(6, [], 1024, 100) = 0
测试⼀段时间进程运⾏情况
[root@VM_0_3_centos ~]# strace -c -p 25901
strace: Process 25901 attached
^Cstrace: Process 25901 detached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
88.29 0.002972 19 160 epoll_wait
7.31 0.000246 1 198 gettimeofday
4.19 0.000141 47 3 sendto
0.12 0.000004 1 4 2 recvfrom
0.09 0.000003 2 2 ioctl
------ ----------- ----------- --------- --------- ----------------55
100.00 0.003366 367 2 total
输⼊strace -c -p 25901后过段时间按ctrl+c退出