【原创】pstack 执行解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

首先,确认 pstack 只是一个 shell 脚本。  
[root@Betty ~]# cat `which pstack`
#!/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 | 
set width 0
set height 0
set pagination no
$backtrace
EOF
/bin/sed -n \
    -e 's/^\((gdb) \)*//' \
    -e '/^#/p' \
    -e '/^Thread/p'
[root@Betty ~]#
其次,找个目标进程用于分析执行过程。  
[root@Betty ~]# ps aux|grep redis
root      1879  0.0  0.4 145624 15692 ?        Tsl  May03   0:58 /usr/local/bin/redis-server *:6379              
root     24960  0.0  0.0 103256   856 pts/1    S+   16:44   0:00 grep redis
[root@Betty ~]#
接着查看 pstack 脚本执行过程中个变量的值。  
[root@Betty ~]# sh -x ./pstack 1879
+ test 1 -ne 1
+ test '!' -r /proc/1879
+ backtrace=bt
+ test -d /proc/1879/task
++ /bin/ls /proc/1879/task
++ /usr/bin/wc -l
+ test 3 -gt 1
+ backtrace='thread apply all bt'
+ GDB=/usr/bin/gdb
+ /usr/bin/gdb -nx --quiet --batch --readnever
+ readnever=--readnever
+ /usr/bin/gdb --quiet --readnever -nx /proc/1879/exe 1879
+ /bin/sed -n -e 's/^\((gdb) \)*//' -e '/^#/p' -e '/^Thread/p'
Thread 3 (Thread 0x7f53e67ff700 (LWP 1884)):
#0  0x000000322500b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x000000000045d735 in bioProcessBackgroundJobs ()
#2  0x0000003225007aa1 in start_thread () from /lib64/libpthread.so.0
#3  0x0000003224ce893d in clone () from /lib64/libc.so.6
Thread 2 (Thread 0x7f53e5dfe700 (LWP 1885)):
#0  0x000000322500b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x000000000045d735 in bioProcessBackgroundJobs ()
#2  0x0000003225007aa1 in start_thread () from /lib64/libpthread.so.0
#3  0x0000003224ce893d in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7f53ed0c9720 (LWP 1879)):
#0  0x0000003224ce8f33 in epoll_wait () from /lib64/libc.so.6
#1  0x0000000000419ece in aeProcessEvents ()
#2  0x000000000041a26b in aeMain ()
#3  0x00000000004236ad in main ()
[root@Betty ~]#
最后,手动执行 gdb 查看对应的输出。  
[root@Betty ~]# /usr/bin/gdb --quiet --readnever -nx /proc/1879/exe 1879
Reading symbols from /proc/1879/exe...(no debugging symbols found)...done.
Attaching to program: /proc/1879/exe, process 1879
Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/libdl.so.2
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
[New LWP 1885]
[New LWP 1884]
[Thread debugging using libthread_db enabled]
Loaded symbols for /lib64/libpthread.so.0
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x0000003224ce8f33 in epoll_wait () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.166.el6_7.7.x86_64
(gdb) set width 0
(gdb) set height 0
(gdb) set pagination no
(gdb) thread apply all bt

Thread 3 (Thread 0x7f53e67ff700 (LWP 1884)):
#0  0x000000322500b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x000000000045d735 in bioProcessBackgroundJobs ()
#2  0x0000003225007aa1 in start_thread () from /lib64/libpthread.so.0
#3  0x0000003224ce893d in clone () from /lib64/libc.so.6

Thread 2 (Thread 0x7f53e5dfe700 (LWP 1885)):
#0  0x000000322500b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x000000000045d735 in bioProcessBackgroundJobs ()
#2  0x0000003225007aa1 in start_thread () from /lib64/libpthread.so.0
#3  0x0000003224ce893d in clone () from /lib64/libc.so.6

Thread 1 (Thread 0x7f53ed0c9720 (LWP 1879)):
#0  0x0000003224ce8f33 in epoll_wait () from /lib64/libc.so.6
#1  0x0000000000419ece in aeProcessEvents ()
#2  0x000000000041a26b in aeMain ()
#3  0x00000000004236ad in main ()
(gdb)
恩恩,又学到了新知识~~  

目录
相关文章
|
域名解析 网络协议 Unix
linux常用命令及解释大全(三)
本篇文章继续介绍了一部分linux常用命令,包括字符设置和文件格式转换,文件系统分析,初始化一个文件系统,备份,光盘,网络这六个部分。linux常用命令及解释大全(三)详情请看正文。
104 2
|
6月前
|
存储 索引
8086 汇编笔记(十一):内中断
8086 汇编笔记(十一):内中断
|
Linux Shell 数据安全/隐私保护
linux常用命令及解释大全(一)
本篇文章介绍了一部分linux常用命令,包括系统信息,关机、重启及登出 ,文件和目录,文件搜索,挂载文件系统,磁盘空间,用户和群组这七个部分。linux常用命令及解释详情请看正文。
241 5
|
监控 Linux Perl
linux常用命令及解释大全(二)
本篇文章继续介绍了一部分linux常用命令,包括文件的权限,文件的特殊属性,打包和压缩文件,查看文件内容,文本处理这五个部分。linux常用命令及解释详情请看正文。
78 1
|
缓存 JavaScript Java
3分钟搞懂什么是编译执行和解释执行《轻松搞定大厂面试》
3分钟搞懂什么是编译执行和解释执行《轻松搞定大厂面试》
434 0
3分钟搞懂什么是编译执行和解释执行《轻松搞定大厂面试》
|
Java Unix Linux
面经手册 · 第19篇《Thread.start() ,它是怎么让线程启动的呢?》
开始听这句话还在上学,既不卓越、也不优秀,甚至可能还有点笨!但突然从某次爬到班级的前几名后,开始喜欢上了这种感觉,原来前面的风景是如此灿烂😜! 优秀和卓越差的不是一个等级,当你感觉自己优秀后,还能保持空瓶的心态开始,才能逐步的像卓越迈进,并漫漫长! 是不小时候更容易学会更多的知识,但越大越笨了!人可能很容易被自己的年纪大了,当成长者。却很少能保持一个低姿态谦卑的心态,不断的学习。所以最后,放不下自己,也拾不起能力。
201 0
面经手册 · 第19篇《Thread.start() ,它是怎么让线程启动的呢?》
|
Java 中间件 程序员
面经手册 · 第20篇《Thread 线程,状态转换、方法使用、原理分析》
大部分考试考的,基本都是不怎么用的。例外的咱们不说😄 就像你做程序开发,尤其在RPC+MQ+分库分表,其实很难出现让你用一个机器实例编写多线程压榨CPU性能。很多时候是扔出一个MQ,异步消费了。如果没有资源竞争,例如库表秒杀,那么其实你确实很难接触多并发编程以及锁的使用。 但!凡有例外,比如你需要开发一个数据库路由中间件,那么就肯定会出现在一台应用实例上分配数据库资源池的情况,如果出现竞争就要合理分配资源。如此,类似这样的中间件开发,就会涉及到一些更核心底层的技术的应用。
249 0
面经手册 · 第20篇《Thread 线程,状态转换、方法使用、原理分析》
|
存储 Oracle 关系型数据库
排查程序死循环,死锁的方法 ——pstack
pstack命令可显示每个进程的栈跟踪,pstack $pid即可,pstack命令须由$pid进程的属主或者root运行。 这次出现cpu占比100%的情况,但看memory占比,并无异常,怀疑是某个地方死循环了。
2382 0