使用 Apport 故障转储调试 Python 程序

Use Apport crash dump to debug Python program

我有一个 Python 程序,有时会由于 "double free or corruption" 错误而崩溃。我试图找出发生这种情况的地方(可能在我正在使用的众多库之一中),以便我可以防止它崩溃。为此,我启用了核心转储,现在我有一个 Apport .crash 文件可以使用。

这就是我卡住的地方。如何将核心转储加载到 gdb 或其他可以让我查看可用堆栈跟踪信息的东西中?

apport-retrace 看起来不错,但无法加载,因为 .crash 文件中没有包:

ERROR: report file does not contain one of the required fields: CoreDump DistroRelease Package ExecutablePath

我也不知道如何将它直接加载到 gdb 中。我已经在完整的 .crash 文件、.crash 文件的 "CoreDump" 部分以及 [=29= 的 base64 解码版本上尝试了 gdb /usr/bin/python <crashfile> ] 部分。每次我收到这个错误:

<crashfile> is not a core dump: File format not recognized

有没有一种方法可以在不需要包的情况下使用 apport-retrace,或者以 gdb 可以使用的方式从崩溃文件中提取核心转储?

事实证明,修改 .crash 文件以允许 apport-retrace 打开它相当简单。我只需要添加

Package: python2.7

到文件。为了更好地衡量,我还确保 "ExecutablePath" 用于 Python:

ExecutablePath: /usr/bin/python2.7

在我的例子中,可执行路径以前是一个不同的文件(一个特定于我的程序的文件)。我不知道这一步是否真的有必要。

完成此操作后,我可以 运行 apport-retrace -g <crashfile> 在 gdb 中打开它,然后使用 bt 提取堆栈跟踪。

1) 您可以将 -R 开关添加到 apport-retrace 而不是修改 .crash 文件。这会生成一个 Packages: 字段,如果包系统本身发生崩溃,该字段尤其可能会丢失。

此外,如果您只想输出回溯,可以使用 -s 开关代替 -g-g 加载交互式调试器。这可能看起来像:

apport-retrace -C /tmp/apportcache/ -R -s -S system \
    /var/crash/$executable-path.$uid.crash > output.trace

2) 另一种方法是通过设置内核参数来禁用 apport,从而生成二进制核心文件以供 gdb -c.

使用
ulimit -c unlimited
sysctl kernel.core_pattern=/var/crash/core.%e.%p

3) 安装 apport-retrace 后,另请参阅 https://wiki.ubuntu.com/DebuggingProgramCrash 获取 GUI 方法。