只是想指出一些我在回到这个话题时感到困惑的事情(注意,我目前使用的是 Ubuntu 14.04,GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1):
首先,有一些关于它“可以作为解释器调用gdb
”的参考资料:
#!/usr/bin/gbd -P
...意思是,可以用 shebang 行或编写一个脚本文本文件#!/usr/bin/gbd --python
,然后在其中编写 Python 代码,然后使其可执行chmod +x pygdbscript
,然后运行./pygdbscript
;...但就像在这篇文章中一样:
...,gdb: unrecognized option '--python'
如果我尝试这样的事情,我会明白的。显然这个选项是/曾经是一些“弓箭手”分支的一个特性gdb
?!
因此,为了在 中运行 Python 脚本gdb
,实际上有两种方法:
- 用扩展名命名你的脚本文件
.py
;在这里说test.py
:
def Something():
print("hello from python")
Something()
gdb.execute("quit");
请注意,在这种情况下,您只需编写纯 Python 代码;你不需要import gdb
为了访问gdb
对象。您可以使用以下任一方式运行:
gdb -x test.py
gdb -x=test.py
gdb --command test.py
gdb --command=test.py
gdb -command test.py
gdb -command=test.py
...这似乎是等效的,因为其中任何一个的结果都是相同的打印输出,在gdb
脚本指示退出之前:
$ gdb -x=test.py
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
...
For help, type "help".
Type "apropos word" to search for commands related to "word".
hello from python
请注意,对于这种情况,类似的名称也test.gdb.py
将被解释为纯 Python 脚本,此后以.py
.
- 将您的脚本命名为其他任何名称- 只要它不以扩展名结尾
.py
;在这里说test.pygdb
:
python
def Something():
print("hello from python")
Something()
gdb.execute("quit");
end
在这种情况下,gdb
将脚本解释为gdb
脚本,即带有gdb
命令 - 这意味着,无论您想在此处编写的任何 Python 代码,都必须以“ python
”作为起始行,“ end
”在 Python 末尾代码。同样,它会被这些等效调用中的任何一个调用:
gdb -x test.pygdb
gdb -x=test.pygdb
gdb --command test.pygdb
gdb --command=test.pygdb
gdb -command test.pygdb
gdb -command=test.pygdb
...然后输出与前一种情况相同(因为它运行的是相同的 Python 脚本):
$ gdb -x test.pygdb
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
...
hello from python
并响应 OP:如果 OP 中的 C 代码在/tmp/myprog.c
-int start_test() { return rand() % 50; }
顶部添加,否则将无法编译 - ,并与 with gcc -g myprog.c -o myprog.exe
into一起编译/tmp/myprog.exe
;那么你可以使用这样的myprog.gdb.py
脚本:
# need to specify the executable file which we debug (in this case, not from command line)
# here `gdb` command `file` is used - it does not have a Python equivalent (https://sourceware.org/gdb/onlinedocs/gdb/Objfiles-In-Python.html#index-Objfile_002eframe_005ffilters)
# so we must use gdb.execute:
myexefile="/tmp/myprog.exe"
print("""
### myprog.gdb.py is running: """ + myexefile + """ - and adding breakpoints:
""")
gdb.execute("file " + myexefile)
gdb.execute("set pagination off")
ax = gdb.Breakpoint("test_success")
bx = gdb.Breakpoint("test_failed")
gdb.execute("run")
# here the program will break, so we can do:
print("""
### myprog.gdb.py after the break - current stack frame:
""")
current_frame_at_break = gdb.selected_frame()
print(current_frame_at_break) # instead of gdb.execute("frame")
print("""
### myprog.gdb.py - backtrace:
""")
gdb.execute("backtrace 2")
print("""
### myprog.gdb.py - go to frame that called current frame:
""")
parent_frame = current_frame_at_break.older()
print(parent_frame)
status_var = parent_frame.read_var("status")
print("status_var is: ", status_var)
...然后使用以下命令运行此脚本:
$ gdb -x myprog.gdb.py
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
....
For help, type "help".
Type "apropos word" to search for commands related to "word".
### myprog.gdb.py is running: /tmp/myprog.exe - and adding breakpoints:
Breakpoint 1 at 0x400565: file myprog.c, line 8.
Breakpoint 2 at 0x40055f: file myprog.c, line 4.
Breakpoint 2, test_failed () at myprog.c:4
4 while(1);
### myprog.gdb.py after the break - current stack frame:
{stack=0x7fffffffdc70,code=0x40055b,!special}
### myprog.gdb.py - backtrace:
#0 test_failed () at myprog.c:4
#1 0x000000000040058c in main () at myprog.c:15
### myprog.gdb.py - go to frame that called current frame:
{stack=0x7fffffffdc90,code=0x400567,!special}
status_var is: 33
(gdb)
注意,在这个脚本结束时,(gdb)
交互提示仍然存在,在这里可以正常使用;如果您不需要交互式提示,您可以gdb.execute("quit");
像上面的脚本一样强制gdb
退出,而不是在脚本执行结束时退出。
此外,有关在 gdb Python 中子类化断点类的示例,请参阅如何在 GDB 中的断点处打印当前源代码行,仅此而已?