在本地ubuntu下,使用psatck调试程序时出现以下问题:
Could not attach to target 40712: No such process.
detach: No such process
然而进程id并没有问题,kill 也能正常杀掉进程。
使用 sudo psatck 则出现一堆 No symbols found
40735: ./server
(No symbols found in )
(No symbols found in /usr/lib/x86_64-linux-gnu/libstdc++.so.6)
(No symbols found in /lib/x86_64-linux-gnu/libc.so.6)
(No symbols found in /lib/x86_64-linux-gnu/libm.so.6)
(No symbols found in /lib64/ld-linux-x86-64.so.2)
(No symbols found in /lib/x86_64-linux-gnu/libgcc_s.so.1)
0x7f9112dce9f3: _fini + 0x7f91129ccd8f (7ffc63845908, 100401bee, 300000002, 10, 39300002, 0) + 20
0x00401b6e: main + 0x127 (11c00, 7ffc63845908, 163845918, 401a47, 0, f2b333238618c14a) + ffff80039cbbc390
0x7f9112ce7830: _fini + 0x7f91128e5bcc (11fe2d8d48550020, 8949f68949530020, 8ec8348e5294cd5, ffef77e803fdc148, db312074ed8548ff, 841f0f) + 41ff894156013b11
crawl: Input/output error
Error tracing through process 40735
0x11f6258d4c544155: _fini + 0x11f6258d4c1424f1
查资料了解到,pstack应该是个shell脚本,但在我的/usr/bin/下找到的pstack,却是一个乱码文件。
使用 apt 重新卸载安装了一遍,发现还是如此。
于是登录到自己的云服务器上去看了一下,服务器系统是centos,yum安装pstack后,pstack功能运行正常,在/usr/bin/下我们可以看到pstack链接到了另一个文件gstack。
找到gstack,是这样一个脚本
#!/bin/sh
if test $# -ne 1; then
echo "Usage: `basename $0 .sh` <process-id>" 1>&2
exit 1
fi
if test ! -r /proc/$1; then
echo "Process $1 not found." 1>&2
exit 1
fi
# GDB doesn't allow "thread apply all bt" when the process isn't
# threaded; need to peek at the process to determine if that or the
# simpler "bt" should be used.
backtrace="bt"
if test -d /proc/$1/task ; then
# Newer kernel; has a task/ directory.
if test `/bin/ls /proc/$1/task | /usr/bin/wc -l` -gt 1 2>/dev/null ; then
backtrace="thread apply all bt"
fi
elif test -f /proc/$1/maps ; then
# Older kernel; go by it loading libpthread.
if /bin/grep -e libpthread /proc/$1/maps > /dev/null 2>&1 ; then
backtrace="thread apply all bt"
fi
fi
GDB=${GDB:-/usr/bin/gdb}
# Run GDB, strip out unwanted noise.
# --readnever is no longer used since .gdb_index is now in use.
$GDB --quiet -nx $GDBARGS /proc/$1/exe $1 <<EOF 2>&1 |
set width 0
set height 0
set pagination no
$backtrace
EOF
/bin/sed -n \
-e 's/^\((gdb) \)*//' \
-e '/^#/p' \
-e '/^Thread/p'
这个脚本其实是把gdb的功能封装了一下:
- 获取一个参数,为进程ID。
- 检测该进程是否正在运行。
- 如果进程只有单个线程,则在gdb中采用“bt”命令;如果为多线程,则采用“thread apply all bt”命令。
- 执行gdb,附着到指定的进程上,并向gdb传入多个命令,并将执行输出的结果传给的sed,提取堆栈信息进行打印。
于是,直接把云服务器上的这个脚本复制替换掉本地乱码的pstack文件,修改执行权限后,发现即可正常运行pstack查看进程堆栈。
fuzhuo@fuzhuo-virtual-machine:/usr/bin$ sudo pstack 43586
#0 0x00007f257dd499f3 in __epoll_wait_nocancel () at ../sysdeps/unix/syscall-template.S:84
#1 0x000000000040125a in epoll_et(int) ()
#2 0x0000000000401b6e in main ()
为何apt安装pstack会出现这样的问题,emm…