適当にバックトレース

いがさんとの会話でなんか作ってたの思い出しました。

 i@um ~> stacktrace w3mcooksrv
 /Users/i/426: No such file or directory.
 Attaching to process 426.
 Reading symbols for shared libraries . done
 Reading symbols for shared libraries ....... done
 0x9004eb97 in accept ()
 #0  0x9004eb97 in accept ()
 #1  0x00002d2a in main (argc=1, argv=0xbfffeeb4, envp=0xbfffeebc)
     at w3mcooksrv.c:702

こんな感じでプロセス名か PID 指定して実行すると gdb 使ってスタックトレース出すだけ、っていう。以下コード。 MacOSX に pgrep が無かったので自分で適当に実装した。

 #!/usr/bin/env ruby
 if !c=ARGV[0]
   raise "#$0 <pid or process name>"
 end
 t=`ps -auxww`.map do |l|
   a=l.split
   [a[1].to_i, a[10]]
 end.select do |i,n|
   if c=~/^\d+$/
     i==c.to_i
   else
     n.index(c)
   end
 end
 if t.size>1&&/^\d+$/!~c
   u=t.select do |i,n|
     n=~/(^|\/)#{c}$/
   end
   t=u if u.size==1
 end
 if t.empty?
   puts"No match"
 elsif t.size>1
   puts"Umbiguous:"
   t.each{|i,n|puts"#{i} #{n}"}
 else
   open('/tmp/bt','w'){|of|of.puts('bt')}
   exec"gdb -nx -x /tmp/bt -batch -p #{t[0][0]}"
 end
なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h