我正在使用 GDB 调试 Kubuntu 12.04 上 Python 应用程序中的分段错误。据说 GDB 版本 7 具有用于提取有关 Python 堆栈的信息的内置宏(http://docs.python.org/devguide/gdb.html),但我无法让它工作。我已经安装了 python-dbg。
当我在 GDB 中请求 python 堆栈跟踪时,结果如下所示:
(gdb) py-bt
#5 (unable to read python frame information)
#16 (unable to read python frame information)
#26 (unable to read python frame information)
...
我的GDB版本是7.4-2012.04-0ubuntu2,Python是2.7.3-0ubuntu3。
答案1
问题在于:要访问 GDB 中的调试符号,您必须调用不同的二进制文件:“python-dbg”而不是“python”(在 /usr/share/doc/python2.7-dbg/README.debug 中找到)。
答案2
在 Ubuntu 16.04 上,我设法通过以下方式在 Python 3.5 中获取 Python 堆栈跟踪:
安装
python3-dbg
和python3-dev
:$ sudo apt install python3-dbg python3-dev
python3-dbg
软件包附带了简短的文档说明如何使用它,/usr/share/doc/python3-dbg/README.debug
我将在下一步中使用它。将解压后的 GDB 帮助脚本
/usr/share/doc/python3.5/gdbinit.gz
附加到~/.gdbinit
:zcat /usr/share/doc/python3.5/gdbinit.gz >> ~/.gdbinit
现在 gdb 将能够找到 Python 二进制文件的符号并py-bt
可以在 gdb 中显示 Python 堆栈跟踪:
$ gdb -p 4762
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Attaching to process 4762
[New LWP 4852]
[New LWP 4853]
[New LWP 4854]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f38e43deb5d in poll () at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) py-bt
Traceback (most recent call first):
File "/usr/bin/indicator-cpufreq", line 80, in <module>
Gtk.main()
(gdb)
答案3
有时,无法获取调试信息;例如,如果您使用 conda Python,这些包不附带调试信息。事实证明,py-spy (https://github.com/benfred/py-spy) 具有更强大的 Python 回溯转储实现,不依赖于是否有可用的准确调试符号。但是,由于它也使用 ptrace,因此您必须先分离 gdb。以下是使其工作的方法:
- 在 gdb 中执行你的操作,到达你想要获取 Python 回溯的断点。
- 使用以下方式让 gdb 传递 SIGSTOP
handle SIGSTOP noprint nostop pass
- 暂停该过程
signal SIGSTOP
- 使用 分离 gdb
detach
。记下 PID - 在另一个终端中运行
py-spy dump --pid $PID
。这将为您提供回溯。 - 你可以使用 继续运行 gdb
attach $PID
。请注意,即使进程被 SIGSTOP 了,你仍然可以继续该进程,并且它将正常运行,如果你再次分离,它将继续暂停
答案4
也许这对某些人有帮助:二进制文件在我的 Debian 系统上命名python2.7-dbg
,来自python2.7-dbg
包。我还安装了python2.7-dev
包和apt-get source python2.7-dbg
,这样gdb
就可以找到 Python 解释器的源文件。
有了这一切,我设法调试SIGSEGV
我遇到的问题:https://bugs.python.org/issue34870