python - 调试:使用 gdb 单步执行 Python 脚本?

标签 python debugging gdb

假设我们有以下 super 简单的 Python 脚本:

print "Initializing"....
a=10
print "Variable value is %d" % (a)
print "All done!"

...然后说,我想通过在 a=10 行放置一个断点来调试此脚本,然后单步执行该脚本。

现在,我想为此使用 gdb,因为我想调试可能作为共享对象一部分的 Python 绑定(bind)(.so) 库 - 因此,理想情况下,我会在 Python 代码行上放置一个断点,然后“进入”共享对象的 C 部分...(请注意 DebuggingWithGdb - PythonInfo Wiki 并没有真正明确声明这是可能的)

问题是:gdb 本身无法真正识别断点,放置在 Python 脚本行:

$ gdb python
GNU gdb (GDB) 7.3.50.20110806-cvs 
...
Reading symbols from /usr/bin/python...(no debugging symbols found)...done.
(gdb) b test.py:3
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (test.py:3) pending.
(gdb) run test.py
Starting program: /usr/bin/python test.py
...

...虽然整个 Python 脚本确实在 gdb 中运行,但根本无法到达断点。

所以 - 是我想要做的,完全可能使用 gdb;如果没有,对于类似的东西,我还有什么其他选择?

最佳答案

非常有趣的问题。这是我的方法。创建signal_test.py:

import os
import signal

PID = os.getpid()

def do_nothing(*args):
    pass

def foo():
    print "Initializing..."
    a=10
    os.kill(PID, signal.SIGUSR1)
    print "Variable value is %d" % (a)
    print "All done!"

signal.signal(signal.SIGUSR1, do_nothing)

foo()

然后就可以在gdb下运行了:

$ gdb --args python signal_test.py
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-37.el5_7.1)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /net/gs/vol3/software/modules-sw/python/2.7/Linux/RHEL5/x86_64/bin/python...done.

当你运行它时,它会一直运行到你调用 kill():

(gdb) run
Starting program: /net/gs/vol3/software/modules-sw/python/2.7/Linux/RHEL5/x86_64/bin/python signal_test.py
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000
[Thread debugging using libthread_db enabled]
Initializing...

Program received signal SIGUSR1, User defined signal 1.
0x0000003d340306f7 in kill () from /lib64/libc.so.6

然后您可以查看回溯:

(gdb) backtrace
#0  0x0000003d340306f7 in kill () from /lib64/libc.so.6
#1  0x00000000004d82dd in posix_kill (self=<value optimized out>, args=<value optimized out>)
    at ./Modules/posixmodule.c:4047
#2  0x000000000049b574 in call_function (f=0x8aca30, throwflag=<value optimized out>)
    at Python/ceval.c:4012
#3  PyEval_EvalFrameEx (f=0x8aca30, throwflag=<value optimized out>) at Python/ceval.c:2665
#4  0x000000000049c5cd in call_function (f=0x8ac560, throwflag=<value optimized out>)
    at Python/ceval.c:4098
#5  PyEval_EvalFrameEx (f=0x8ac560, throwflag=<value optimized out>) at Python/ceval.c:2665
#6  0x000000000049d3bb in PyEval_EvalCodeEx (co=0x2aaaae224f30, globals=<value optimized out>, 
    locals=<value optimized out>, args=0x0, argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0, 
    closure=0x0) at Python/ceval.c:3252
#7  0x000000000049d432 in PyEval_EvalCode (co=0x1a48, globals=0xa, locals=0x0) at Python/ceval.c:666
#8  0x00000000004bf321 in run_mod (fp=0x89ad60, filename=0x7fffffffb5b4 "signal_test.py", 
    start=<value optimized out>, globals=0x7e4680, locals=0x7e4680, closeit=1, flags=0x7fffffffaee0)
    at Python/pythonrun.c:1346
#9  PyRun_FileExFlags (fp=0x89ad60, filename=0x7fffffffb5b4 "signal_test.py", 
    start=<value optimized out>, globals=0x7e4680, locals=0x7e4680, closeit=1, flags=0x7fffffffaee0)
    at Python/pythonrun.c:1332
#10 0x00000000004bf5d8 in PyRun_SimpleFileExFlags (fp=<value optimized out>, 
    filename=0x7fffffffb5b4 "signal_test.py", closeit=1, flags=0x7fffffffaee0)
    at Python/pythonrun.c:936
#11 0x00000000004148cc in Py_Main (argc=<value optimized out>, argv=<value optimized out>)
    at Modules/main.c:599
#12 0x0000003d3401d994 in __libc_start_main () from /lib64/libc.so.6
#13 0x0000000000413b19 in _start ()

如果继续,程序的其余部分将正常运行。

(gdb) continue
Continuing.
Variable value is 10
All done!

Program exited normally.

相反,您可以在适当的框架中单步执行,直到找到您感兴趣的语句。您可能需要运行一个调试 Python 以使其更有意义。

关于python - 调试:使用 gdb 单步执行 Python 脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7412708/

相关文章:

python - 如何使用 Homebrew 安装 Py2Cairo 等 Python 库

android - Qt Creator 在 Android 8.0 (LG G6) 上不显示日志消息

linux - 如何让 gdb 从已安装的库中加载符号?

linux - 没有明显原因的段错误

python - 通过TCP从arduino发送数据到python

python - 尽管 rasterized=True,为什么 matplotlib 图形文件大小很大?

ruby-on-rails - Ruby 调试器安装错误

c - 在 gdb 中打印以 NUL 开头的字符串

python - 图像库从 JPEG 转换为

c - C语言dll调试