emacs-lsp / dap-mode

Emacs :heart: Debug Adapter Protocol
https://emacs-lsp.github.io/dap-mode
GNU General Public License v3.0
1.3k stars 182 forks source link

Debug C++ library called from python or jupyter session #475

Open prittjam opened 3 years ago

prittjam commented 3 years ago

Is it possible to step into C++ code from a python script? Is there an example configuration file that demonstrates this? Basically is it possible to do this mixed code type of debugging. Thanks.

yyoncho commented 3 years ago

Based on this - https://stackoverflow.com/questions/46169522/how-to-debug-underlying-c-library-from-python-interface you can with any of the gdb related debug adapter(most likely lldb will work too).

I think that the following will work - start the python process like you normally do(in debug session or not) then use attach to process using any of the gdb/lldb adapters. I guess the only open question is how to load the debug symbols for the C++ shared library but someone with knowledge about that might provide more info(cc @nbfalcon @danielmartin @sebastiansturm).

prittjam commented 3 years ago

@yyoncho, thanks for the response. Can you provide a link to an example showing how to attach the process via the adapter? The debug symbols should be encoded directly in the .so if compiled in -g debug mode, so I don't think there needs to be anything explicit for that.

**** OK, I see that lldb has an example of how to attach. I'll give it a shot... thanks!

yyoncho commented 3 years ago

Here it is another one for cpptools adapter:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Attach",
            "type": "cppdbg",
            "request": "attach",
            "program": "enter program name, for example ${workspaceFolder}/a.out",
            "processId": "${command:pickProcess}",
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}
prittjam commented 3 years ago

@yyoncho, so it works. Similar to your example, I can attach to a jupyter kernel and hit the breakpoint in the C++ code that is associated with the shared object. Thanks, this will be a big help. There is one inconvenience. I have to edit the pid in the debug template every time I launch a new jupyter kernel. Do you have advice for how to make this more convenient? Also, I wonder why it is necessary to provide the program name since the pid uniquely identifies the process you want to attach to.

yyoncho commented 3 years ago

@prittjam if you run it via the provided template you will have an interactive dialog in which you can pick the process by name.

Generally, this will give you the pid of the python process after you have started it(not sure it will be available right away after the first dap-debug).

(process-id (dap--debug-session-proc (dap--cur-session-or-die)))

Something like this:

(defun my/start-python-c++-debugging ()
  (interactive)
  (dap-debug
   (list :type "python"
         ;; python template goes here
         ))

  (dap-debug
   (list :type "cpptools"
         ;; cpp template goes here
         :processId  (process-id (dap--debug-session-proc (dap--cur-session-or-die)))
         )))

As a side note, once this is up and running I will appreciate a gif demonstrating how this works. It is pretty much a demonstration of why emacs is better than the others.

prittjam commented 3 years ago

@yyoncho, I'm happy to provide a gif when I get it going.