12

I am purposely generating a core dump from a C++ application I'm writing using VSCode. I cannot figure out how to debug the core dump. Has anyone had any experience with this they'd be willing to share?

***** UPDATE ***** I believe I have it working now. I created a second debug configuration for core files. I needed to add the "coreDumpPath" option that pointed to the dump file generated. I also needed to remove preLaunchTask option that would always build a new executable.


David Massat
  • 181
  • 1
  • 1
  • 8

5 Answers5

17

From the VScode docs

Memory dump debugging

The C/C++ extension for VS Code also has the ability to debug memory dumps. To debug a memory dump, open your launch.json file and add the coreDumpPath (for GDB or LLDB) or dumpPath (for the Visual Studio Windows Debugger) property to the C++ Launch configuration, set its value to be a string containing the path to the memory dump. This will even work for x86 programs being debugged on an x64 machine.

P.S. The asker has already updated the question with the solution. But adding this answer to help those people who jump directly into the answer section ;)


Update: Sample launch.json for C/C++ extension without hardcoding core file name

{
    "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"
      }
    ]
}

Sample launch.json for CodeLLDB extension without hardcoding core file name

{
    "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 K
  • 336
  • 4
  • 8
  • my `vscode` does not accept `initCommands`; instead it allows me to directly give `coreDumpPath`. – mic_e Apr 14 '21 at 18:39
  • My bad... The sample launch.json is to be used with CodeLLDB extension, I have added a sample for C/C++ extension as well, now. – Insaf K May 12 '21 at 06:29
4

To give a concrete example of @insaf's answer. This can be used as a template for launch.json (click the settings button on top of the debug side-bar to edit it):

{
    // 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>"
        }
    ]
}

Edit the paths of the binary and core dump accordingly.

Then press the green play button (start debugging) -- it doesn't really start anything but load the core dump.

bluenote10
  • 23,414
  • 14
  • 122
  • 178
1

I wrote a little helper script that duplicates the functionality of coredumpctl in a machine-readable way.

It

  • searches the systemd journal for logged coredumps
  • uses fzf to allow the user to interactively select one of them
  • decompresses the selected coredump to /tmp/coredump
  • links the associated executable to /tmp/coredump_program

Then I created the following tasks.json:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "select coredump",
            "type": "shell",
            "command": "coredumpselect.py",
            "args": [],
            "presentation": {
                "reveal": "always",
                "panel": "new"
            }
        }
    ]
}

and added the following debug configuration to launch.json:

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

Now when you launch the "View coredump" debugging action, you'll be given an interactive choice of coredumps in the terminal. After selecting one of them, the vscode debugger will open it.

To run the script on your Linux system, you need to install the systemd Python package. On Ubuntu, use sudo apt install python3-systemd. On Arch Linux, use sudo pacman -S python-systemd. With pip, the packages is available as systemd-python (not to be confused with systemd, which is a different incompatible package). You'll also need fzf (sudo apt install fzf, sudo pacman -S fzf), and the proper decompressor for the coredump (e.g. lz4 or zstd).

mic_e
  • 5,594
  • 4
  • 34
  • 49
  • That looks so good (for the reader: needs python3, which is also used when making that executable) - but sadly doesn't work (lz4 can be `pip3 install`ed, systemd, too (after installing sytemd-devel via system package manager) as it fails with "File "./coredumpselect.py", line 38/25 AttributeError: module 'systemd.journal' has no attribute 'Reader'". Any hint to get it working? – Simon Sobisch Nov 09 '22 at 15:36
  • Hm... this is weird. I developed this script on Ubuntu 20.04; there I needed to `apt install python3-lz4 python3-systemd`; this works (for me) up to day (`systemd.journal` has the class `Reader`). On recent Arch Linux, I had to `pacman -S python-systemd python-lz4` and that also works. What system are you using? – mic_e Nov 09 '22 at 20:04
  • pip installs this package: https://github.com/mosquito/cysystemd while my script depends on the package that is installed through `apt install python3-systemd` (https://github.com/systemd/python-systemd). The packages have the same names but different APIs, which is quite unfortunate. – mic_e Nov 09 '22 at 20:12
  • 1
    As a rule of thumb, before you install something through pip always check whether your distribution packages the feature directly; if you have Ubuntu, just uninstall the pip package and install the correct package with `apt install python3-systemd`. It also looks like the correct package __is__ available on pip, but with a different name: https://pypi.org/project/systemd-python/ – mic_e Nov 09 '22 at 20:18
  • installing `python3-systemd python3-lz4` (removing the other installed packages via pip before) seems to have worked. Please edit your answer adding this note "install the two dependencies python3-systemd and python3-lz4 via system package manager, not via pip" to make that much more useful. Note: when executing with python3 I get "AttributeError: module 'os' has no attribute 'exit' " - should that be `sys,exit` or `os._exit`? – Simon Sobisch Nov 09 '22 at 20:26
  • Thanks for the edit, which helped. Note for future me: when `./coredumpselect.py` days "no coredumps are available" this is likely the case - have a look at the "coredump" column of `sudo coredumpctl`... – Simon Sobisch Nov 09 '22 at 20:28
0

I defer to the two examples above for launch.json configurations but in addition to that, if you have any home grown .so libraries, you're going to want to add

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

or it won't find the symbols for those libraries which in my case were terribly important.

stu
  • 8,461
  • 18
  • 74
  • 112
-5

You don't use a source code editor (even VSCode) to debug a core dump (because a core file has not a textual format). You use gdb (or perhaps some other debugger, such as lldb). GDB has a very nice user manual that I strongly recommend to read. You also don't use VSCode to compile your C++ code, but a compiler such as GCC or Clang (probably VSCode could be configured to start g++ for you).

On Linux, if your C or C++ program was built with -g passed to g++ or gcc as an executable $HOME/bin/foo you could try

 gdb $HOME/bin/foo core

then use post mortem commands of the gdb debugger. Read the documentation of gdb for details. The presence and name of the core dump file is configurable (at the lowest level using setrlimit(2) and thru proc(5), so bash builtin ulimit or zsh builtin limit). See also core(5). Notice that your login shell could be changed with chsh(1). On Linux, bash is often (not always) the default shell, but you might switch to zsh or even to the fish shell. Read of course about Unix shells.

You also don't need to generate a core dump on purpose. It is often simpler to set a breakpoint under gdb. You could generate a core of a running process using gcore(1). You could attach gdb to a running process using the -p option of gdb(1). I see very few cases where generating a core dump on purpose is useful. But of course abort(3) (also used by assert(3)) generates a core dump.

Your application should better be compiled (using the -g option to GCC or Clang) with DWARF debug information. Assume your application executable is some yourapp executable file. Then you debug the core dump (for a core file, see core(5) for more; notice that gdb(1) is mentioned in core(5) man page, given by the man core command) using gdb yourapp core

Some source code editors are capable of running gdb (my editor is emacs and it is capable of running gdb with M-x gdb). You should dive into the documentation of your source code editor to understand how to do that.

But I recommend using gdb on the command line in a terminal. It is a very handy tool. See this answer to a related question.

gdb is using the very low level ptrace(2) system call to set breakpoints etc etc.. You almost never need ptrace (except if you write your own debugger, which could take years of work), but you use gdb which uses ptrace.

PS. How to run gdb from VSCode is a different question. Since I don't use VSCode, I cannot answer it. And it might not even worth doing. Even with 30 years of emacs experience, I often run gdb in a terminal. Since it is simpler than running it from emacs (or VSCode).

NB. These days, in 2019, "source code editor" is a near synonym for "IDE". Both locutions in practice refer to the same products, but they differ in the way they present them. You can call emacs an IDE, I (and the GNU community) prefer to call it a source code editor, but we both will use it for the same things: nicely writing and browsing and working on source code and building and debugging it.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 2
    I was trying to avoid using gdb in the command line mode, and didn't much like the tui feature. Now that I have this working, it's really nice, I can see all my local\global variables, call stacks per thread, and it appears to be working very well. Only time will tell how good it is at an actual production dump where the application is not toy application. I appreciate you taking the time to answer my question! – David Massat Apr 18 '19 at 00:23
  • 4
    VSCode is not a text editor it is an IDE. It has tight gdb integration. In VSCode you can step through your code using GDB and set breakpoints in your editor. You can attach to running process and see what the stack and backtrace look like. This is a snarky uninformed answer that isn't helpful – jterm May 10 '19 at 03:49
  • Most advanced editors and IDE are able to provide features such as integrating dbg. – Nicolas Bousquet Aug 04 '21 at 09:59