gdb のRPM に付属する /usr/bin/gstack, /usr/bin/gcore コマンド

Scientific Linux 6 系の gdb の RPM に /usr/bin/gstack, /usr/bin/gcore というスクリプトが含まれているのを知りました。どちらも gdb をラップしたシェルスクリプトです。 (追記: CentOS5 の gdb にも入ってました )

/usr/bin/gstack

指定したプロセス(マルチスレッドの場合は全スレッド)のスタックトレースを表示します

  • monit の例
# /usr/bin/gstack `cat /var/run/monit.pid`
Thread 2 (Thread 0x7fd3ea10a700 (LWP 27548)):
#0  0x0000003cb48dea63 in poll () from /lib64/libc.so.6
#1  0x000000000041c9c7 in can_read_ms ()
#2  0x0000000000433107 in start_httpd ()
#3  0x000000000041acd8 in thread_wrapper ()
#4  0x0000003cb4c07851 in start_thread () from /lib64/libpthread.so.0
#5  0x0000003cb48e811d in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7fd3ea3197c0 (LWP 27546)):
#0  0x0000003cb48ac3bd in nanosleep () from /lib64/libc.so.6
#1  0x0000003cb48ac230 in sleep () from /lib64/libc.so.6
#2  0x00000000004146ed in do_action ()
#3  0x0000000000414f81 in main ()

また /usr/bin/pstack というコマンドもあるのですが、gstack へのシンボリックリンクとなっています

/usr/bin/gcore [-o filename] pid

指定したプロセスのコアダンプを取ります

  • monit の例
# /usr/bin/gcore -o /tmp/monit.core `cat /var/run/monit.pid` 
[Thread debugging using libthread_db enabled]
[New Thread 0x7fd3ea10a700 (LWP 27548)]
0x0000003cb48ac3bd in nanosleep () at ../sysdeps/unix/syscall-template.S:82
82      T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
Saved corefile /tmp/monit.core.27546
  • コアである
# file /tmp/monit.core.27546 
/tmp/monit.core.27546: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from '/usr/bin/monit'

プロセスのメモリ使用量によってはファイルサイズがだいぶ大きくなると思うので要注意です。(コマンドを実行する前にサイズをどう見積もれるのかが分からない)

またコアダンプを取っている間はプロセスが state T (トレース状態) で停止しているのでその点も要要注意。

その他

プロダクション環境で利用している monit (ver 5.4.1 ) が時折デッドロックのような現象を起こしいていて 対応に困っている方がいたので、これらのツールで何らかの原因究明に役立てられないかなと思っていました。 gdb を直で叩いて スタックトレースやコアダンプを取ってもらう手もありますが、障害で忙しいケース場合はコマンドとして用意されていると扱いが楽ですね。