如何使用VSCode调试Linux核心转储文件?

14
我正在使用VSCode编写C++应用程序,有意生成核心转储,并且无法调试核心转储。请问是否有人有相关经验可以分享?
***** 更新 ***** 我相信现在已经解决了这个问题。我创建了第二个针对核心文件的调试配置。我需要添加“coreDumpPath”选项,指向生成的转储文件。我还需要删除preLaunchTask选项,该选项会始终构建一个新的可执行文件。
5个回答

18

VScode文档

内存转储调试

VS Code的C/C++扩展还具有调试内存转储的功能。要调试内存转储,请打开launch.json文件,将coreDumpPath(对于GDB或LLDB)或dumpPath(对于Visual Studio Windows Debugger)属性添加到C ++ Launch配置中,并将其值设置为字符串,其中包含内存转储的路径。即使在x64机器上调试x86程序,这也可以正常工作。

P.S. 提问者已经在问题中更新了解决方案。但是添加此答案以帮助那些直接跳到答案部分的人;)


更新: 用于C/C++扩展的示例launch.json,不需要硬编码核心文件名

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "cppdbg",
            "request": "launch",
            "name": "Open a core dump(c/c++)",
            "program": "<Path to the program here>",
            "coreDumpPath": "${input:coreFileName}",
            "cwd": "${workspaceFolder}",
            "MIMode": "lldb" // or gdb, if you are using gdb
        }
    ],
    "inputs": [
      {
        "id": "coreFileName",
        "type": "promptString",
        "description": "Enter core file path"
      }
    ]
}

使用CodeLLDB扩展而不硬编码核心文件名的示例launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "custom",
            "name": "Open a core dump",
            "initCommands": [
                "target create -c ${input:coreFileName}"
            ]
        }
    ],
    "inputs": [
      {
        "id": "coreFileName",
        "type": "promptString",
        "description": "Enter core file path"
      }
    ]    
}

我的 vscode 不接受 initCommands,而是允许我直接提供 coreDumpPath - mic_e
我的错...示例launch.json应与CodeLLDB扩展一起使用,我现在也为C/C++扩展添加了一个示例。 - Insaf K

4

举个例子,@insaf的回答可以被用作launch.json的模板(在调试边栏顶部点击设置按钮进行编辑):

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "<PATH-TO-BINARY>",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "coreDumpPath": "<PATH-TO-CORE-DUMP>"
        }
    ]
}

根据二进制文件和核心转储文件的路径进行编辑。

然后点击绿色的播放按钮(开始调试)-- 它实际上并没有启动任何内容,只是加载核心转储文件。


2
我写了一个小助手脚本,它以可机读的方式复制了coredumpctl的功能。
它会:
  • 搜索systemd日志中记录的核心转储文件
  • 使用fzf让用户交互式地选择其中一个文件
  • 将选定的核心转储文件解压缩到/tmp/coredump
  • 将相关的可执行文件链接到/tmp/coredump_program
然后,我创建了以下tasks.json:
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "select coredump",
            "type": "shell",
            "command": "coredumpselect.py",
            "args": [],
            "presentation": {
                "reveal": "always",
                "panel": "new"
            }
        }
    ]
}

并将以下调试配置添加到launch.json

        {
            "name": "View coredump",
            "type": "cppdbg",
            "request": "launch",
            "program": "/tmp/coredump-program",
            "args": [],
            "cwd": "${workspaceRoot}",
            "coreDumpPath": "/tmp/coredump",
            "preLaunchTask": "select coredump",
            "MIMode": "gdb",
        }

现在,当您启动“查看核心转储”调试操作时,在终端中会给出交互式选择核心转储的选项。选择其中一个后,vscode调试器将打开它。
要在Linux系统上运行脚本,您需要安装systemd Python软件包。在Ubuntu上,使用sudo apt install python3-systemd。在 Arch Linux 上,使用sudo pacman -S python-systemd。使用pip,该软件包可用作systemd-python(不要与不兼容的不同软件包systemd混淆)。您还需要fzfsudo apt install fzfsudo pacman -S fzf)以及适当的核心转储解压缩程序(例如lz4zstd)。

看起来很好(对于读者:需要Python3,也是制作可执行文件时使用的) - 但不幸的是它不起作用(lz4可以通过“pip3 install”进行安装,systemd也可以(在通过系统包管理器安装systemd-devel之后)因为它出现了“文件"./coredumpselect.py", line 38/25 AttributeError: module 'systemd.journal' has no attribute 'Reader'”而失败。 有什么提示可以让它正常工作吗? - Simon Sobisch
嗯...这很奇怪。我在Ubuntu 20.04上开发了这个脚本;我需要apt install python3-lz4 python3-systemd;这对我来说有效(我的systemd.journalReader类)。最近在Arch Linux上,我必须使用pacman -S python-systemd python-lz4,这也有效。你使用的是什么系统? - mic_e
使用pip安装此软件包:https://github.com/mosquito/cysystemd,而我的脚本依赖于通过`apt install python3-systemd`(https://github.com/systemd/python-systemd)安装的软件包。这些软件包具有相同的名称但不同的API,这非常不幸。 - mic_e
1
作为一个经验法则,在通过pip安装任何东西之前,始终要检查您的发行版是否直接打包了该功能;如果您使用的是Ubuntu,则只需卸载pip软件包并使用“apt install python3-systemd”安装正确的软件包。看起来正确的软件包也可以在pip上找到,但名称不同:https://pypi.org/project/systemd-python/。 - mic_e
安装 python3-systemd python3-lz4(在之前通过pip安装的其他包被删除之后),似乎已经生效了。请编辑您的答案并添加此注释“使用系统软件包管理器安装两个依赖项python3-systemd和python3-lz4,而不是通过pip安装”,以使其更有用。注意:当使用python3执行时,我会得到“AttributeError:module 'os' has no attribute 'exit'”-是否应该使用 sys, exitos._exit - Simon Sobisch
感谢您的编辑,这很有帮助。未来提醒自己:当 ./coredumpselect.py 显示“没有可用的核心转储”时,这很可能是情况 - 请查看 sudo coredumpctl 的“coredump”列... - Simon Sobisch

0

关于launch.json配置,我推荐上述两个例子。除此之外,如果您有自己编写的 .so 库,您需要添加:

"additionalSOLibSearchPath": "${workspaceFolder}/path/to/sharedobjects/",

否则它将无法找到那些库的符号,而在我的情况下,这些库非常重要。


-5

你不应该使用源代码编辑器(即使是VS Code)来调试一个core dump (因为core文件并没有文本格式)。你需要使用gdb(或其他一些调试器,例如lldb)。GDB有非常好的用户手册,我强烈推荐阅读。你也不应该使用VS Code来编译你的C++代码,而是使用编译器,例如GCCClang(可能可以将VS Code配置为为您启动g++)。

在Linux上,如果您的C或C++程序是使用-g 传递给 g++gcc编译成可执行文件$HOME/bin/foo,您可以尝试以下操作:

 gdb $HOME/bin/foo core

然后使用 gdb 调试器的 post mortem 命令。详情请参阅 gdb 文档。核心转储文件的存在和名称是可配置的(在最低层次上使用 setrlimit(2) 和通过 proc(5)),因此可以使用 bash 内置命令 ulimitzsh 内置命令 limit 进行设置。还请参考 core(5)。请注意,您的登录 shell 可能会更改,例如使用 chsh(1) 命令。在 Linux 上,bash 通常(但不总是)是默认 shell,但您可能会切换到 zsh 或甚至 fish shell。当然,请先了解 Unix shells

你也不需要故意生成核心转储文件。通常在gdb下设置断点更简单。你可以使用gcore(1)生成正在运行进程的核心。你可以使用gdb(1)-p选项将gdb附加到正在运行的进程上。我很少见到有用的故意生成核心转储文件的情况。但当然abort(3)(也被assert(3)使用)会生成一个core转储文件。

你的应用程序最好使用 -g 选项(对于 GCC 或 Clang)编译 DWARF 调试信息。假设你的应用程序可执行文件是某个 yourapp 可执行文件。然后,你可以使用 gdb yourapp core 命令来调试核心转储文件(有关更多信息,请参见 core(5);请注意,gdb(1)core(5) 的 man 页面中提到,由 man core 命令给出)。

一些源代码编辑器可以运行 gdb (我的编辑器是 emacs,它可以通过 M-x gdb 运行 gdb)。您应该深入了解您的源代码编辑器文档以了解如何操作。

但我建议在终端中使用命令行下的 gdb。这是一个非常方便的工具。请参见 this 相关问题的答案。

gdb 使用非常低级别的 ptrace(2) 系统调用来设置断点等等。您几乎永远不需要使用 ptrace(除非您编写自己的调试器,这可能需要数年时间),但您会使用使用 ptracegdb

附注:如何从VSCode运行是一个不同的问题。由于我不使用VSCode,我无法回答它。而且这可能并不值得做。即使有30年的经验,我经常在终端中运行。因为它比从(或VSCode)中运行更简单。

NB. 如今,在2019年,“源代码编辑器”几乎是“IDE”的同义词。实际上,这两个术语都指的是相同的产品,但它们在呈现方式上有所不同。你可以称emacs为IDE,我(以及GNU社区)更喜欢称其为源代码编辑器,但我们都将用它来漂亮地编写、浏览和处理源代码以及构建和调试它。


2
我一直试图避免在命令行模式下使用gdb,并不太喜欢tui功能。现在我已经让它工作了,真的很好用,我可以看到所有的本地/全局变量,每个线程的调用堆栈,而且它似乎运行得非常好。只有时间才能告诉我们它在实际生产转储中的表现如何,因为应用程序并不是玩具应用程序。感谢您抽出时间回答我的问题! - David Massat
4
VSCode 不是一个文本编辑器,而是一个集成开发环境(IDE)。它与 gdb 集成紧密。在 VSCode 中,您可以使用 GDB 逐步调试代码,并在编辑器中设置断点。您可以附加到正在运行的进程并查看堆栈和回溯信息。这是一个不礼貌且缺乏知识的回答,对解决问题没有任何帮助。 - jterm
大多数先进的编辑器和IDE都能够提供集成dbg等功能。 - Nicolas Bousquet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接