概述
我们知道调用backtrace()可以获取当前进程的调用堆栈信息,那如果想要获取另外一个进程(我们当然知道这个进程的pid)的调用堆栈信息,是否有办法呢?
在stackoverflow上,就有人提出了这个问题,有网友给出的答案是向该进程发出一个信号,然后由该进程在信号处理函数里获取自身的调用堆栈,然后再发回来…。先不管这种方法行或不行,但至少不适合一般情况,因为它需要在指定进程里进行信号处理。
想想gdb工具,gdb几乎可以attach到任何进程上,在无需其它进程做任何额外工作的情况下,获取它的当前调用堆栈信息,所以说,回到题目问题,能够实现获取指定进程的调用堆栈信息,而恰好就有这么一个特定的工具pstack:
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@localhost ~]# pstack 4468
Thread 2 (Thread 0x4166f940 (LWP 4469)):
#0 0x00007fbcaf6e6b99 in pthread_cond_wait@@GLIBC_2.3.2 ()
#1 0x00007fbcb071e9fb in ?? () from /proc/4468/exe
#2 0x00007fbcaf6e24a7 in start_thread () from /lib64/libpthread.so.0
#3 0x00007fbcaf9cac2d in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7fbcb06f46e0 (LWP 4468)):
#0 0x00007fbcaf9cb018 in epoll_wait () from /lib64/libc.so.6
#1 0x00007fbcb072800c in ?? () from /proc/4468/exe
#2 0x00007fbcb0726fec in ?? () from /proc/4468/exe
#3 0x00007fbcb071d319 in main () from /proc/4468/exe
[root@localhost ~]#
|
从上实例可以看到,pstack可以获取指定进程(通过进程id)的所有线程调用堆栈信息,怎么做到的呢?其实pstack就是一个利用gdb实现的shell脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
[root@localhost ~]# ls -l `which pstack`
lrwxrwxrwx 1 root root 6 Jul 14 2010 /usr/bin/pstack -> gstack
[root@localhost ~]# file /usr/bin/gstack
/usr/bin/gstack: Bourne shell script text executable
[root@localhost ~]# cat !$
cat /usr/bin/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}
if
$GDB -nx --quiet --batch --readnever > /dev/null 2>&1; then
readnever=--readnever
else
readnever=
fi
# Run GDB, strip out unwanted noise.
$GDB --quiet $readnever -nx /proc/$1/exe $1 <<EOF 2>&1 |
$backtrace
EOF
/bin/sed -n
-e
's/^(gdb) //'
-e
'/^#/p'
-e
'/^Thread/p'
[root@localhost ~]#
|
最后
以上就是超级唇彩为你收集整理的能否实现获取指定进程的调用堆栈信息?的全部内容,希望文章能够帮你解决能否实现获取指定进程的调用堆栈信息?所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复