debug support
kobi2187 opened this issue ยท 26 comments
Hello, what would be needed for a good debug experience inside vscode? I start this issue as a discussion thread and cooperation.
I see an LLDB extension for c++ and rust. -- [link] that looks really nice.
I am hopeful that the same extension can be used by us
however, setting a breakpoint in nim mode, is not yet possible.
I am also not sure how to use debugging directly from the editor (tasks?)
These things need direct support from the nim extension.
Thanks!
I've already done some experiments with --lineDir:on
, --debugger:native
and this extension with both the official C/C++ extension and NativeDebug and it kind of works.
First of all settings break points does work, they correspond to the respective lines in the Nim code. But reading the values of variables is just a mess(especially with sequences).
Since the latest major version of Nim, it supports generating a list of all symbols and their mangled names, which could be accesed to mangle or demangle the symbols.
Just to be clear, setting a breakpoint in the nim file or the generated C ?
if the first, do I need to update the extension or nim itself, to the latest (git) version, to see this feature?
Thanks.
I've set break points in the Nim file and it's completely independant from this extension. You simply have to debug the binary you've created just like you would debug it, if it was a C/C++ binary.
The reason for this is that the Nim compiler stuffs the generated C files full with #line
directives(when the --lineDir:on
switch is used), which override the current file and line informations of the next line, which the C compiler than puts into the debug informations, which the debugger uses.
Thanks, after an update many things work better, specifically setting break points, stopping at them, watching values. Looks like all is good with basic debug.
You may close this issue if you want
@kobi2187, @RSDuck wich versions are you used?
I'm tried with lldb-5.0, vscode 1.20.1, gdb 7.11.1
Both extensions (LLDB and NativeDebug)
But can't read/evaluate variables/expressions:
Here is sample for NativeDebug+LLDB:
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": [
{
"type": "lldb-mi",
"request": "launch",
"name": "Launch Program",
"target": "./main",
"preLaunchTask": "Build Debug",
"cwd": "${workspaceRoot}"
}
]
}
tasks.json:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Build Debug",
"type": "shell",
"command": "nim c -d:debug --debuginfo --lineDir:on --debugger:native main.nim"
}
]
}
I think you have done everything correctly. However, the Nim variable names are mangled when generating c source and the mapping of the variable names to their mangled versions is not currently performed for you automatically by any debugging extension.
If you look in the nimcache folder of your project you will find a file named main.ndi. This file contains the mappings of the original variable name to the mangled name. My main.ndi file contains the following lines (as well as other info):
a a_9cWLbw5tGuQDnREm7o4KXdA /.../main.nim 6 4
b b_butjSOByVkZOvORx2CNAPA /.../main.nim 7 4
The first line indicates that the variable 'a' found at location 6,4 (zero-based row,col) in file main.nim has been mangled to a_9cWLbw5tGuQDnREm7o4KXdA. So when debugging the program if you want to inspect the value of variable 'a' from the Nim source, you need to specify a_9cWLbw5tGuQDnREm7o4KXdA to the debugger.
@brjohnsn Btw, what is "Variables -> Local"? As I understand, there must be displayed two local variables with values 1 and 2, or no?
Yes I would have expected the same thing, but I have not read the docs for the Native Debug extension (if there are any) to know for sure. If you wrap your code in a proc those variables do seem to appear in their unmangled form. Try debugging with code similar to the following...
proc add(x, y: int): int =
x+y
proc main =
echo "3 + 5 = ", add(3, 5)
var a = 1
var b = 2
echo a
echo b
main()
@brjohnsn it works, I tried 2 extensions, here is results:
--- vscode-lldb
LLDB
--- nativedebug
GDB
LLDB-MI
Also I tried MSCppTools for VSCode, but unsuccessfull. It doesn't work with Nim.
Note: plugin vscode-lldb doesn't support input stream.
main.nim
echo "Enter your name:"
let name = readLine(stdin)
output:
Enter your name:
*enter* name
error: 'name' is not a valid command.
error: Unrecognized command 'name'.
the plugin NativeDebug with GDB works fine.
Hi,
I also have successfully used the Microsoft C++ debugger in VSCode by passing just --debugger:native
to the nim compiler to generate the #line
directives.
But I am not able to set breakpoints within the .nim
source files ... the language extension does not seem to allow it.
I used a workaround by associating .nim files temporarily with the cpp
language service ... in settings.json:
"files.associations": {
// "*.nim": "cpp",
},
Then I was able to set breakpoints in the .nim files, but all the syntax highlighting and all other nim language functionality obviously was gone.
After setting the breakpoints, I commented the line in settings.json ... then I was able to start the debugger and it did hit the breakpoints in the .nim file ๐
Also all symbols that were not mangled by the nim compiler can be inspected via mouse-over or in the watch window. (but ofc with the limitations already mentioned above)
Is there anything I could do to set breakpoints in the .nim files without the mentioned workarround ?
Right now this is the only big thing that would be stopping someone from being able to directly debug .nim files using the MsCpp debugger in VSCode.
PS: this trick even works while the debugger is already running, i.e. you can set new breakpoints while debugging.
Thanks
How about this issue's progressing?
Hello
So, is there any way to properly display strings/data structures in debugger?
There is a nim-gdb.py script in tools which is supposed to help with this. On windows, I tried making a nim-gdb.bat file which calls nim-gdb.py and setting miDebuggerPath in launch.json to point to this instead of regular gdb. But I'm having some trouble installing gdb for python currently so the script isn't running. I think if i can get gdb python installed, it will work tho.
nim-gdb.bat:
python nim-gdb.py --debugger:native %*
nim build command:
nim c -d:debug --debuginfo --lineDir:on --debugger:native <file>.nim
I always struggle with the next VS Code Setup ... in fact this time it was VSCodium (open source, MS not monitoring you). I'm including my full files in case it helps someone else :)
My setup is for Linux; I run Mint 19 so it would suit Ubuntu & probably most other Linuxes + OSX.
Two files needed for Nim.
1 For compilation you need to setup tasks.json. Here's my setup for compiling nim with cpp, c, and c + debug. Note that the command will need to target your nim compiler so /home/john/.local/bin/nim will probably change.
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build nim cpp",
"type": "shell",
"command": "/home/john/.local/bin/nim",
"args": [
"cpp",
"-r",
"${file}"
],
"group": "build",
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
},
{
"label": "build nim c",
"type": "shell",
"command": "/home/john/.local/bin/nim",
"args": [
"c",
"-r",
"${file}"
],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
},
{
"label": "build debug nim c",
"type": "shell",
"command": "/home/john/.local/bin/nim",
"args": [
"c",
"--debugger:native",
"-r",
"${file}"
],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
}
]
}
- I needed to setup launch.json so that gdb will work with my files. Here's my launch.json which shouldn't require any customization.
{
// 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": "/home/john/Langs/Nim/test",
// "program": "${file}",
"program": "${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
]
}
I have been able to use vscode to debug nim from wsl by
- installing nim on wsl ubuntu ( curl https://nim-lang.org/choosenim/init.sh -sSf | sh ) and adding nim-gdb.py to ~/.nimble/tools/
- installing the remote development vscode extension (and launching vscode from a wsl prompt). I then had to install the nim and c/c++ dev extensions again on the wsl side.
- adding these tasks/launch.json files to a project .vscode folder
// tasks.json
{
"version": "2.0.0",
"tasks": [{
"label": "nimbuild",
"type": "shell",
"command": "~/.nimble/bin/nim",
"args": ["c", "--debugger:native", "${file}"],
}]
}
// launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"preLaunchTask": "nimbuild",
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "nim-gdb",
"setupCommands": [{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}],
}]
}
After doing this I can debug nim and inspect variables from vscode. I hope I didn't leave any steps out. Don't forget to add export PATH=~/.nimble/bin:$PATH
to ~/.profile
@travisstaloch does it show variables properly for you? It doesnt work for me.
Try it from inside in a function. I noticed the same thing until I moved the code into a function.
Hah indeed that did the trick. Thanks ๐
@travisstaloch you forgot to mention that it also requires to download https://github.com/nim-lang/Nim/raw/devel/bin/nim-gdb into ~/.nimble/tools, then "chmod +x nim-gdb" and finally add ~/.nimble/tools to PATH. At least that's what was missing on my side :)
I have been able to use vscode to debug nim from wsl by
- installing nim on wsl ubuntu ( curl https://nim-lang.org/choosenim/init.sh -sSf | sh ) and adding nim-gdb.py to ~/.nimble/tools/
- installing the remote development vscode extension (and launching vscode from a wsl prompt). I then had to install the nim and c/c++ dev extensions again on the wsl side.
- adding these tasks/launch.json files to a project .vscode folder
...
I went through all the steps you describe, and I got this error when pressing F5 to run the debugger:
Can I ask how you configured this?
I see there is a line
"miDebuggerPath": "nim-gdb"
in launch.json. I'm not sure what nim-gdb is or how to get it. Is it related to this? https://github.com/cooldome/Nim-gdb
I do have a file called nim-gdb.py (which I got from here) in the root of my project folder.
Update
you forgot to mention that it also requires to download https://github.com/nim-lang/Nim/raw/devel/bin/nim-gdb into ~/.nimble/tools, then "chmod +x nim-gdb" and finally add ~/.nimble/tools to PATH. At least that's what was missing on my side :)
@size-1 Sorry, I didn't read your reply. But, I followed your instructions. Now I don't get the error complaining about not being able to find nim-gdb. Instead, what happens is that I set a breakpoint in my code, press F5, and this shows up in the TERMINAL window at the bottom of Visual Studio Code:
The first thing is a compilation that appears to be successful with "Task - nimbuild":
It then automatically switches that to another window, "cppdbg: lcs", with just this printed:
The whole window looks like this:
It's giving me the debug step buttons at the top of the screen. However, it has not stopped at the breakpoint to show me local variable names and values.
I have successfully debugged based on the above configurations. But the variable name is missing, and I don't know how to solve this problem.
tasks.json
{ "version": "2.0.0", "tasks": [ { "label": "nimbuild", "type": "shell", "command": "nim c -d:debug --debuginfo --lineDir:on --debugger:native ${file}" } ] }
launch.json
{ "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "lldb", "request": "launch", "program": "${fileDirname}/${fileBasenameNoExtension}", "args": [], "preLaunchTask": "nimbuild", "cwd": "${fileDirname}", }] }