pstack 原理

注意和ptrace(ptrace()系统调用提供了一个方法,该方法使一个程序(追踪者)可以观察和控制另外一个程序(被追踪者)的执行,并检查和改变被追踪者的内存及寄存器。它主要用于实现断点调试和追踪系统调用。GDB的工作机制)区分



和jstack一样, pstack亦能展现进程的线程堆栈快照, 非常方便验证和性能评估.
pstack的作用, 大致可以归纳如下:
  1). 查看线程数(比pstree, 包含了详细的堆栈信息)
  2). 能简单验证是否按照预定的调用顺序/调用栈执行
  3). 采用高频率多次采样使用时, 能发现程序当前的阻塞在哪里, 以及性能消耗点在哪里?
  4). 能反映出疑似的死锁现象(多个线程同时在wait lock, 具体需要进一步验证)
  当然还能举例更多的作用, 相信使用过jstack的coder, 必然深以为然.



pstack原理:
pstack是/usr/bin/gstack的软链接, 而gstack本身是基于gdb封装的shell脚本.
最核心的片段, backtrace=”thread apply all bt”
  shell采用了here document的方式, 完成了GDB的交互工作(注意EOF标识, 及范围内的交互命令).
  重要的是输入thread apply all bt这个交互命令. 该命令要求输出所有的线程堆栈信息.
  对GDB输出的结果, 通过管道并借助sed命令进行了替换和过滤.
  
`#!/bin/bash



if test $# -ne 1; then
    echo “Usage: basename $0 .sh " 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’
`

利用pstack 和 strace分析程序在哪里耗时



ps 查找进程的pid
pstack 打印进程或者线程的栈信息
strace 统计每一步系统调用花费的时间












  1. ps -aux grep nws 可以看出nws的pid为171211


  2. pstack 171211 打印出nws进程下所有的线程栈信息。可以看出程序好几个线程都卡在pwrite这一步。

  3. strace -o output.txt -T -tt -e trace=all -p 171264 nws进程中的171264线程进行系统调用跟踪, 将输出的信息保存在output.txt中



1.死机后,输入:
info threads ——- 查看所有thread信息



  1. thread apply all bt
    显示所有的线程堆栈



Category linux