pragmagic / vscode-nim

An extension for VS Code which provides support for the Nim language.
Other
237 stars 37 forks source link

debug support #65

Open kobi2187 opened 6 years ago

kobi2187 commented 6 years ago

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!

RSDuck commented 6 years ago

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.

kobi2187 commented 6 years ago

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.

RSDuck commented 6 years ago

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.

kobi2187 commented 6 years ago

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

R3D9477 commented 6 years ago

@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: 1

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"
        }
    ]
}
brjohnsn commented 6 years ago

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.

R3D9477 commented 6 years ago

@brjohnsn Thanks for hint! I'll play with it

R3D9477 commented 6 years ago

@brjohnsn Btw, what is "Variables -> Local"? As I understand, there must be displayed two local variables with values 1 and 2, or no?

brjohnsn commented 6 years ago

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()
R3D9477 commented 6 years ago

@brjohnsn it works, I tried 2 extensions, here is results:

--- vscode-lldb LLDB example_1_lldb example_2_lldb

--- nativedebug GDB example_1_gdb example_2_gdb LLDB-MI example_3_lldb-mi example_4_lldb-mi

Also I tried MSCppTools for VSCode, but unsuccessfull. It doesn't work with Nim.

R3D9477 commented 6 years ago

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.

R3D9477 commented 6 years ago

Another bad situations:

drywolf commented 5 years ago

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

kosz78 commented 5 years ago

@drywolf I have added breakpoint support in the latest release of extension. Now it works with CppTools without any modification

drywolf commented 5 years ago

@kosz78 Nice, I will be checking it out

xland commented 5 years ago

How about this issue's progressing?

teras commented 5 years ago

Hello So, is there any way to properly display strings/data structures in debugger?

travisstaloch commented 5 years ago

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
john9631 commented 5 years ago

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"
        }
    ]
}
  1. 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
                }
            ]
        },
    ]
}
travisstaloch commented 5 years ago

I have been able to use vscode to debug nim from wsl by

// 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

rokups commented 5 years ago

@travisstaloch does it show variables properly for you? It doesnt work for me. image

travisstaloch commented 5 years ago

Try it from inside in a function. I noticed the same thing until I moved the code into a function.

rokups commented 5 years ago

Hah indeed that did the trick. Thanks :+1:

size-1 commented 4 years ago

@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 :)

dave-doty commented 3 years ago

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 ...

@travisstaloch

I went through all the steps you describe, and I got this error when pressing F5 to run the debugger:

image

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":

image

It then automatically switches that to another window, "cppdbg: lcs", with just this printed:

image

The whole window looks like this:

image

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.

gtd138 commented 1 year ago

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