Skip to content

Latest commit

 

History

History
223 lines (163 loc) · 8.75 KB

20231008_03.md

File metadata and controls

223 lines (163 loc) · 8.75 KB

debian 使用gdb实现rhel / centos pstack功能

作者

digoal

日期

2023-10-08

标签

PostgreSQL , PolarDB , DuckDB , pstack , gdb , strace , debian


背景

https://blog.csdn.net/JiekeXu/article/details/107479167

http://www.manongjc.com/detail/57-exyaiyhanljwsoz.html

rhel/centos支持pstack, 在Debian上却没有, 原来是这个原因:

yum install -y strace gdb pstack  

因为实际上pstack是个脚本, 指向gstack, 最终还是调用gdb.

[root@JiekeXu ~]# 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}  
  
# 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'  
  • 脚本要求一个参数:进程 ID。
  • 然后通过检测 /proc 目录下进程子目录是否可读,来查看相应进程是否存在。
  • 如果进程只有一个线程,那么使用 gdb 的 “bt” 命令打印线程堆栈信息,否则使用 “thread apply all bt” 命令。
  • 最后调用 gdb,使用 “bt” 或 “thread apply all bt” 命令,并把输出重定向到 sed 工具,由 sed 工具打印出线程堆栈信息。

了解pstack真相后, debian可以安装strace和gdb, 直接调用gdb即可:

apt-get install -y strace gdb  

例如:

gdb -p 8089 --batch -ex "bt"  
  
  
gdb -p 8089 --batch -ex "thread apply all bt full"  
root@d40da947f60f:~# gdb -p 8089 --batch -ex "thread apply all bt full"  
[Thread debugging using libthread_db enabled]  
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".  
0x0000ffffa566011c in __GI_epoll_pwait (epfd=4, events=0xaaaafe49b300, maxevents=1, timeout=-1, set=0x0) at ../sysdeps/unix/sysv/linux/epoll_pwait.c:42  
42	../sysdeps/unix/sysv/linux/epoll_pwait.c: No such file or directory.  
  
Thread 1 (Thread 0xffffa2d66010 (LWP 8089) "postgres"):  
#0  0x0000ffffa566011c in __GI_epoll_pwait (epfd=4, events=0xaaaafe49b300, maxevents=1, timeout=-1, set=0x0) at ../sysdeps/unix/sysv/linux/epoll_pwait.c:42  
        _sys_result = 18446744073709551612  
        sc_ret = <optimized out>  
#1  0x0000aaaae7961e74 in WaitEventSetWait ()  
No symbol table info available.  
#2  0x0000aaaae784d9fc in secure_read ()  
No symbol table info available.  
#3  0x0000aaaae7854d04 in ?? ()  
No symbol table info available.  
#4  0x0000aaaae785593c in pq_getbyte ()  
No symbol table info available.  
#5  0x0000aaaae798bff4 in PostgresMain ()  
No symbol table info available.  
#6  0x0000aaaae78fd180 in ?? ()  
No symbol table info available.  
#7  0x0000aaaae78fe060 in PostmasterMain ()  
No symbol table info available.  
#8  0x0000aaaae764fb70 in main ()  
No symbol table info available.  
[Inferior 1 (process 8089) detached]  
  
  
root@d40da947f60f:~# gdb -p 8089 --batch -ex "thread apply all bt"  
[Thread debugging using libthread_db enabled]  
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".  
0x0000ffffa566011c in __GI_epoll_pwait (epfd=4, events=0xaaaafe49b300, maxevents=1, timeout=-1, set=0x0) at ../sysdeps/unix/sysv/linux/epoll_pwait.c:42  
42	../sysdeps/unix/sysv/linux/epoll_pwait.c: No such file or directory.  
  
Thread 1 (Thread 0xffffa2d66010 (LWP 8089) "postgres"):  
#0  0x0000ffffa566011c in __GI_epoll_pwait (epfd=4, events=0xaaaafe49b300, maxevents=1, timeout=-1, set=0x0) at ../sysdeps/unix/sysv/linux/epoll_pwait.c:42  
#1  0x0000aaaae7961e74 in WaitEventSetWait ()  
#2  0x0000aaaae784d9fc in secure_read ()  
#3  0x0000aaaae7854d04 in ?? ()  
#4  0x0000aaaae785593c in pq_getbyte ()  
#5  0x0000aaaae798bff4 in PostgresMain ()  
#6  0x0000aaaae78fd180 in ?? ()  
#7  0x0000aaaae78fe060 in PostmasterMain ()  
#8  0x0000aaaae764fb70 in main ()  
[Inferior 1 (process 8089) detached]  
  
  
root@d40da947f60f:~# gdb -p 8089 --batch -ex "bt"  
[Thread debugging using libthread_db enabled]  
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".  
0x0000ffffa566011c in __GI_epoll_pwait (epfd=4, events=0xaaaafe49b300, maxevents=1, timeout=-1, set=0x0) at ../sysdeps/unix/sysv/linux/epoll_pwait.c:42  
42	../sysdeps/unix/sysv/linux/epoll_pwait.c: No such file or directory.  
#0  0x0000ffffa566011c in __GI_epoll_pwait (epfd=4, events=0xaaaafe49b300, maxevents=1, timeout=-1, set=0x0) at ../sysdeps/unix/sysv/linux/epoll_pwait.c:42  
#1  0x0000aaaae7961e74 in WaitEventSetWait ()  
#2  0x0000aaaae784d9fc in secure_read ()  
#3  0x0000aaaae7854d04 in ?? ()  
#4  0x0000aaaae785593c in pq_getbyte ()  
#5  0x0000aaaae798bff4 in PostgresMain ()  
#6  0x0000aaaae78fd180 in ?? ()  
#7  0x0000aaaae78fe060 in PostmasterMain ()  
#8  0x0000aaaae764fb70 in main ()  
[Inferior 1 (process 8089) detached]  

以下是chatgpt回复, 未验证.

在使用 GDB 进行调试时,你可以通过设置断点并使用 GDB 的 print 命令来打印每个变量的值。以下是一个示例:

在终端中,使用以下命令启动 GDB,将可执行文件和相关的符号文件传递给它:

gdb /path/to/your/program  

在 GDB 中,使用 break 命令在你希望检查变量的位置设置一个断点:

break function_name  

继续执行程序:

run  

当程序达到断点时,可以使用 print 命令来打印变量的值:

print variable_name  

将 variable_name 替换为要打印的变量名。

继续执行程序,直到下一个断点或程序结束:

continue  

通过重复以上步骤,在程序运行过程中你可以设置多个断点,然后使用 print 命令来打印想要检查的变量的值。

除了 print 命令之外,GDB 还提供了其他一些有用的命令来帮助你调试程序,例如 backtrace(打印函数调用堆栈)和 step(单步执行)等。

请注意,使用 GDB 进行调试需要一些调试知识和技巧。你可能需要了解如何设置断点、单步执行、查看变量的内存地址等。

希望这个解答对你有帮助。如果你有任何其他问题,请随时提问。

digoal's wechat