***** 更新 ***** 我相信现在已经解决了这个问题。我创建了第二个针对核心文件的调试配置。我需要添加“coreDumpPath”选项,指向生成的转储文件。我还需要删除preLaunchTask选项,该选项会始终构建一个新的可执行文件。
内存转储调试
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"
}
]
}
举个例子,@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>"
}
]
}
根据二进制文件和核心转储文件的路径进行编辑。
然后点击绿色的播放按钮(开始调试)-- 它实际上并没有启动任何内容,只是加载核心转储文件。
coredumpctl
的功能。fzf
让用户交互式地选择其中一个文件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",
}
sudo apt install python3-systemd
。在 Arch Linux 上,使用sudo pacman -S python-systemd
。使用pip,该软件包可用作systemd-python
(不要与不兼容的不同软件包systemd
混淆)。您还需要fzf
(sudo apt install fzf
,sudo pacman -S fzf
)以及适当的核心转储解压缩程序(例如lz4
或zstd
)。apt install python3-lz4 python3-systemd
;这对我来说有效(我的systemd.journal
有Reader
类)。最近在Arch Linux上,我必须使用pacman -S python-systemd python-lz4
,这也有效。你使用的是什么系统? - mic_epython3-systemd python3-lz4
(在之前通过pip安装的其他包被删除之后),似乎已经生效了。请编辑您的答案并添加此注释“使用系统软件包管理器安装两个依赖项python3-systemd和python3-lz4,而不是通过pip安装”,以使其更有用。注意:当使用python3执行时,我会得到“AttributeError:module 'os' has no attribute 'exit'”-是否应该使用 sys, exit
或 os._exit
? - Simon Sobisch./coredumpselect.py
显示“没有可用的核心转储”时,这很可能是情况 - 请查看 sudo coredumpctl
的“coredump”列... - Simon Sobisch关于launch.json配置,我推荐上述两个例子。除此之外,如果您有自己编写的 .so 库,您需要添加:
"additionalSOLibSearchPath": "${workspaceFolder}/path/to/sharedobjects/",
否则它将无法找到那些库的符号,而在我的情况下,这些库非常重要。
你不应该使用源代码编辑器(即使是VS Code)来调试一个core
dump (因为core
文件并没有文本格式)。你需要使用gdb(或其他一些调试器,例如lldb)。GDB有非常好的用户手册,我强烈推荐阅读。你也不应该使用VS Code来编译你的C++代码,而是使用编译器,例如GCC或Clang(可能可以将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
内置命令 ulimit
或 zsh
内置命令 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
(除非您编写自己的调试器,这可能需要数年时间),但您会使用使用 ptrace
的 gdb
。
附注:如何从VSCode运行是一个不同的问题。由于我不使用VSCode,我无法回答它。而且这可能并不值得做。即使有30年的经验,我经常在终端中运行。因为它比从(或VSCode)中运行更简单。
NB. 如今,在2019年,“源代码编辑器”几乎是“IDE”的同义词。实际上,这两个术语都指的是相同的产品,但它们在呈现方式上有所不同。你可以称emacs为IDE,我(以及GNU社区)更喜欢称其为源代码编辑器,但我们都将用它来漂亮地编写、浏览和处理源代码以及构建和调试它。
vscode
不接受initCommands
,而是允许我直接提供coreDumpPath
。 - mic_e