早速、試してみましょう。次のようなPython scriptを用意します。
$ cat hello.py #!/usr/bin/env python import sys sys.stdout.write('Hello, my first script.\n')GDBを起動して、実行します。
(gdb) source hello.py Hello, my first script.
Python scriptからのGDB機能の利用
次に、Python scriptからGDBの機能を使用する例を紹介します。gdb.execute()関数を使用すれば、GDBのコマンドラインで行う操作を実行できます。サンプルのデバッグ対象として以下のtarget.ccを使用します。
[target.cc] #include <cstdio> #include <cstdlib> #include <time.h> int getval(int div) { return time(NULL) / div; } int main(void) { printf("val: %d\n", getval(5)); return EXIT_SUCCESS; }これをshow-bt.pyで次の4つのことを行います。
- break pointをgetval()関数の先頭に設定
- プログラムを実行
- break pointで停止時のbacktraceを表示する
- break pointで停止時のraxレジスタを表示する
[show-bt.py] gdb.execute('b getval') gdb.execute('run') gdb.execute('bt') gdb.execute('p/x $rax')以下はコマンドラインからスクリプトを実行させる例です。 コマンドライン引数の-qは、GDB起動時のcopyrightなどの表示を抑制します。-xで実行するスクリプトファイルを指定します。
$ gdb -q -x show-bt.py target Reading symbols from /home/foo/target...done. Breakpoint 1 at 0x400627: file target.cc, line 7. Breakpoint 1, getval (div=5) at target.cc:7 7 return time(NULL) / div; #0 getval (div=5) at target.cc:7 #1 0x0000000000400656 in main () at target.cc:12 #2 0x00007ffff72d2ead in __libc_start_main (main=, argc= , ubp_av= , init= , fini= , rtld_fini= , stack_end=0x7fffffffe128) at libc-start.c:228 #3 0x0000000000400539 in _start () $1 = 0x7ffff763aee8
コマンドの出力をPythonの文字列として取得する
上記の例では、通常のGDBコマンドを実行するだけでしたが、この出力をPythonの文字列として取得してみましょう。これは、gdb.execute()関数のto_string引数にTrueを渡すことで実現できます。Pythonは、文字列処理も得意ですから、容易に特定の文字列を抽出したり、整形して表示することが可能になります。以下の例では、stacktrace出力の各行からframe番号と最後の単語を抽出して表示します。
$ cat show-bt-and-format.py gdb.execute('b getval') gdb.execute('run') bt = gdb.execute('bt', to_string=True) for line in bt.split('\n'): words = line.split(' ') print '%s %s' % (words[0], words[-1])
$ gdb -q -x show-bt-and-format.py target Reading symbols from /home/foo/target...done. Breakpoint 1 at 0x400627: file target.cc, line 7. Breakpoint 1, getval (div=5) at target.cc:7 7 return time(NULL) / div; #0 target.cc:7 #1 target.cc:12 #2 libc-start.c:228 #3 ()
0 件のコメント:
コメントを投稿