vimspector icon indicating copy to clipboard operation
vimspector copied to clipboard

[Feature Request] Multiple concurrent sessions (to debug multiprocessing python programs)

Open moetayuko opened this issue 5 years ago • 17 comments

Describe the bug Can't debug multiprocessing python programs

To Reproduce MWE

import time
import multiprocessing as mp


def f():
    while True:
        print("f")
        time.sleep(0.1)


print("main")
p = mp.Process(target=f)
p.start()
p.join()

List of steps to reproduce

  1. Set a breakpoint in f()
  2. Start debugging

Vimspector config file:

{
  "$schema": "https://puremourning.github.io/vimspector/schema/vimspector.schema.json#",
  "configurations": {
    "Current file: Launch": {
      "adapter": "debugpy",
      "configuration": {
        "name": "Current file: Launch",
        "request": "launch",
        "console": "externalTerminal",
        "program": "${file}"
      }
    }
  }
}

Expected behavior Stop at the breakpoint.

Actual behaviour Stop at p.join() and stuck there.

Please include:

  • Vimspector log (~/.vimspector.log)

http://fars.ee/l00b

  • Output from any or all UI diagnostic tabs (Server, etc.)
Unhandled event: debugpyAttach

Environemnt

NOTE: NeoVim is supported only on a best-effort basis. Please check the README for limitations of neovim. Don't be offended if I ask you to reproduce issues in Vim.

NOTE: Windows is not supported. There is a branch with windows support, which you can contribute to, rather than opening an issue.

  • Version of Vimspector: 87e80db94d0623043d591f10d706cc50d1acc4f0

  • Output of vim --version or nvim --version

VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Mar  1 2020 17:21:03)
Included patches: 1-343
Compiled by Arch Linux
Huge version without GUI.  Features included (+) or not (-):
+acl               -farsi             -mouse_sysmouse    -tag_old_static
+arabic            +file_in_path      +mouse_urxvt       -tag_any_white
+autocmd           +find_in_path      +mouse_xterm       +tcl/dyn
+autochdir         +float             +multi_byte        +termguicolors
-autoservername    +folding           +multi_lang        +terminal
-balloon_eval      -footer            -mzscheme          +terminfo
+balloon_eval_term +fork()            +netbeans_intg     +termresponse
-browse            +gettext           +num64             +textobjects
++builtin_terms    -hangul_input      +packages          +textprop
+byte_offset       +iconv             +path_extra        +timers
+channel           +insert_expand     +perl/dyn          +title
+cindent           +job               +persistent_undo   -toolbar
-clientserver      +jumplist          +popupwin          +user_commands
-clipboard         +keymap            +postscript        +vartabs
+cmdline_compl     +lambda            +printer           +vertsplit
+cmdline_hist      +langmap           +profile           +virtualedit
+cmdline_info      +libcall           +python/dyn        +visual
+comments          +linebreak         +python3/dyn       +visualextra
+conceal           +lispindent        +quickfix          +viminfo
+cryptv            +listcmds          +reltime           +vreplace
+cscope            +localmap          +rightleft         +wildignore
+cursorbind        +lua/dyn           +ruby/dyn          +wildmenu
+cursorshape       +menu              +scrollbind        +windows
+dialog_con        +mksession         +signs             +writebackup
+diff              +modify_fname      +smartindent       -X11
+digraphs          +mouse             -sound             -xfontset
-dnd               -mouseshape        +spell             -xim
-ebcdic            +mouse_dec         +startuptime       -xpm
+emacs_tags        +mouse_gpm         +statusline        -xsmp
+eval              -mouse_jsbterm     -sun_workshop      -xterm_clipboard
+ex_extra          +mouse_netterm     +syntax            -xterm_save
+extra_search      +mouse_sgr         +tag_binary        
   system vimrc file: "/etc/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
       defaults file: "$VIMRUNTIME/defaults.vim"
  fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H     -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1       
Linking: gcc   -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-E -Wl,-rpath,/usr/lib/perl5/5.30/core_perl/CORE  -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -L/usr/local/lib -Wl,--as-needed -o vim        -lm -ltinfo -lelf -lnsl    -lacl -lattr -lgpm -ldl   -Wl,-E -Wl,-rpath,/usr/lib/perl5/5.30/core_perl/CORE -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -L/usr/local/lib  -L/usr/lib/perl5/5.30/core_perl/CORE -lperl -lpthread -ldl -lm -lcrypt -lutil -lc   -L/usr/lib -ltclstub8.6 -ldl -lz -lpthread -lm     
  • Output of which vim or which nvim:
/usr/sbin/vim
  • Output of :py3 pass:
nothing
  • Output of :py3 import vim:
nothing
  • Operating system: Arch Linux on WSL2

Additional context This works in vscode

moetayuko avatar Mar 27 '20 12:03 moetayuko

Thanks for the detailed report. If i remember correctly there is some flag you can pass to the debug adapter to tell it to debug into child processes.

Googling debugpy child processes yields this: https://github.com/microsoft/debugpy/blob/master/doc/Subprocess%20debugging.md not sure if that's useful or not.

The unhandled event <clearly custom event name here> is also suspicious. If the debug adapter is using non standard events, then Vimspector's not going to be able to support it.

(i refuse to implement anything outside of the protocol as i do not have the bandwidth to do this).

puremourning avatar Mar 27 '20 12:03 puremourning

@int19h - any advise on this one ? Is there anything special that's required for debugpy to debug into child processes created by multiprocessing.Process() ?

puremourning avatar Mar 27 '20 12:03 puremourning

There's certainly some shenanigans in the log here:

2020-03-27 19:56:35,079 - DEBUG - Message received: {'seq': 14, 'type': 'event', 'event': 'debugpyAttach', 'body': {'python': '/usr/sbin/python3', 'name': 'Subprocess 12078', 'request': 'attach', 'console': 'externalTerminal', 'program': '/tmp/test.py', 'host': '127.0.0.1', 'port': 36197, 'subProcessId': 12078}}
2020-03-27 19:56:35,079 - WARNING - User Msg: Unhandled event: debugpyAttach
2020-03-27 19:56:35,079 - DEBUG - Message received: {'seq': 15, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 0, 'name': 'multiprocessing.popen_fork', 'path': '/usr/lib/python3.8/multiprocessing/popen_fork.py', 'package': 'multiprocessing'}}}
2020-03-27 19:56:35,080 - DEBUG - Message received: {'seq': 16, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 1, 'name': 'multiprocessing.process', 'path': '/usr/lib/python3.8/multiprocessing/process.py', 'package': 'multiprocessing'}}}
2020-03-27 19:56:35,080 - DEBUG - Message received: {'seq': 17, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 2, 'name': '__main__', 'path': '/tmp/test.py'}}}
2020-03-27 19:56:35,080 - DEBUG - Message received: {'seq': 18, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 3, 'name': 'runpy', 'path': '/usr/lib/python3.8/runpy.py'}}}
2020-03-27 19:56:35,080 - DEBUG - Message received: {'seq': 19, 'type': 'response', 'request_seq': 8, 'success': True, 'command': 'scopes', 'body': {'scopes': [{'name': 'Locals', 'variablesReference': 2, 'expensive': False, 'source': {}}]}}
2020-03-27 19:56:35,080 - DEBUG - Sending Message: {"command": "variables", "arguments": {"variablesReference": 2}, "seq": 9, "type": "request"}
2020-03-27 19:56:35,080 - DEBUG - Calling: vimspector#internal#job#Send(g:vimspector_internal_arg_0)
2020-03-27 19:56:35,107 - DEBUG - Message received: {'seq': 20, 'type': 'response', 'request_seq': 9, 'success': False, 'command': 'variables', 'message': 'Unable to find thread to evaluate variable reference.'}
2020-03-27 19:56:35,108 - ERROR - Request failed: Unable to find thread to evaluate variable reference.
2020-03-27 19:56:35,332 - INFO - Server stderr: E+00004.427: /handling #9 request "variables" from IDE[1]/
             Handler 'IDE.request' (file '/home/dianlujitao/.vim/plugged/vimspector/gadgets/linux/debugpy/build/lib/debugpy/adapter/../../debugpy/adapter/components.py', line 127)
             couldn't handle #9 request "variables" from IDE[1]:
             Unable to find thread to evaluate variable reference.

puremourning avatar Mar 27 '20 12:03 puremourning

The unhandled event <clearly custom event name here> is also suspicious. If the debug adapter is using non standard events, then Vimspector's not going to be able to support it.

vscode's python plugin handles it in a handleCustomEvent function so...it's probably not part of the standard DAP

moetayuko avatar Mar 27 '20 14:03 moetayuko

Yes, it would seem that there is some collusion between the debug adapter and its VSCode extension to handle this multi-process debugging. In VSCode do you get like multiple debug sessions (one attached to the parent and one attached to the spawned child process ? )

puremourning avatar Mar 27 '20 14:03 puremourning

In VSCode do you get like multiple debug sessions (one attached to the parent and one attached to the spawned child process ? )

Yes, each process has its own session. To make it clear I extended the example to create two sub-processes:

import time
import multiprocessing as mp


def f1():
    while True:
        print("f1")
        time.sleep(0.1)


def f2():
    while True:
        print("f2")
        time.sleep(0.1)


print("main")
p1 = mp.Process(target=f1)
p1.start()
p2 = mp.Process(target=f2)
p2.start()

p1.join()
p2.join()

After executing p1.start(), a new session was created, the parent session was paused and the debugging window automatically attached to the new session:

image

I can re-attach to the parent session from "call stack" window like this:

image

and continue to start the next process:

image

"variables" and "watch" windows change when switching between sessions.

Multi-processing support is quite important for python, not only for debugging sub-processes, but also for debugging the main process itself, because the debugger stuck once a new process was created even if no breakpoint was set within sub-processes. I'd really appreciate it if this could be implemented.

moetayuko avatar Mar 27 '20 16:03 moetayuko

Vimspector doesn't support multiple concurrent debug sessions of any type right now, and this is clearly using custom features unique to the vscode-python extension, so there's not really much hope of this being supported, unless something changes in DAP.

puremourning avatar Mar 27 '20 16:03 puremourning

Yep, the way DAP is structured, every process has to be its own separate session. On debugpy side, when subprocess is detected and detoured, we send a custom event that basically contains the body of the "attach" event that is necessary to attach to that subprocess - the client has to handle that accordingly.

We are hoping to submit this sort of "reverse attach request" for standardization in the main protocol eventually. But that will only happen after this custom implementation had some time to prove that it's a solid approach.

When it's not supported, to avoid child processes getting stuck because the client is not there to attach to them, the debug configuration should specify "subProcess": false.

int19h avatar Mar 27 '20 19:03 int19h

I added "subProcess": false as Pavel mentioned, and according to the logging it's actually sent to the debugger:

2020-03-28 10:54:09,766 - DEBUG - Sending Message: {"command": "launch", "arguments": {"python": "/usr/sbin/python3", "name": "Current file: Launch", "request": "launch", "subProcess": false, "console": "externalTerminal", "program": "/tmp/test.py"}, "seq": 1, "type": "request"}

But the debugpyAttach event along with the attach request was still sent to vimspector and stuck at .join()

Anything wrong with my configuration?

moetayuko avatar Mar 28 '20 03:03 moetayuko

Nope, it's correct - the problem is that we regressed "subProcess" :/

I'll track this as https://github.com/microsoft/debugpy/issues/90

int19h avatar Mar 31 '20 19:03 int19h

Looks like we would need to also handle the "process" event which I think we currently ignore:

2020-12-01 18:47:04,928 - DEBUG - Message received: {'seq': 9, 'type': 'event', 'event': 'process', 'body': {'name': 'manage.py', 'systemProcessId': 77, 'isLocalProcess': True, 'startMethod': 'attach'}}

https://microsoft.github.io/debug-adapter-protocol/specification#Events_Process

another log from @ross-weir https://gist.github.com/ross-weir/5de8fce2ab53eb34e4a71ae2d4e7eb5b

puremourning avatar Dec 01 '20 09:12 puremourning

@puremourning Maybe/maybe not useful, full log attaching to a subprocess using the body object as the configuration from a debugpyAttach event. Connecting to the subprocess was successful and debuggable.

2020-12-01 20:36:45,938 - DEBUG - Reading configurations from: None
2020-12-01 20:36:45,939 - DEBUG - Reading configurations from: /Users/user/Development/app/.vimspector.json
2020-12-01 20:36:45,949 - DEBUG - Reading gadget config: /Users/user/.vim/plugged/vimspector/gadgets/macos/.gadgets.json
2020-12-01 20:36:45,951 - DEBUG - Reading gadget config: None
2020-12-01 20:36:47,801 - INFO - Configuration: {"adapter": "multi-session", "variables": {"host": "127.0.0.1", "port": "22961"}, "breakpoints": {"exception": {"raised": "N", "uncaught": "", "userUnhandled": ""}}, "configuration": {"request": "attach", "django": true, "type": "python", "name": "Subprocess 98", "connect": {"host": "127.0.0.1", "port": 22961}, "subProcessId": 98, "pathMappings": [{"localRoot": "/Users/user/Development/app", "remoteRoot": "/opt/app"}]}}
2020-12-01 20:36:47,802 - INFO - Adapter: {"host": "127.0.0.1", "port": "22961"}
2020-12-01 20:36:48,097 - INFO - Starting debug adapter with: {"host": "127.0.0.1", "port": "22961"}
2020-12-01 20:36:48,100 - INFO - Debug Adapter Started
2020-12-01 20:36:48,101 - DEBUG - Sending Message: {"command": "initialize", "arguments": {"adapterID": "adapter", "clientID": "vimspector", "clientName": "vimspector", "linesStartAt1": true, "columnsStartAt1": true, "locale": "en_GB", "pathFormat": "path", "supportsVariableType": true, "supportsVariablePaging": false, "supportsRunInTerminalRequest": true}, "seq": 0, "type": "request"}
2020-12-01 20:36:48,210 - DEBUG - Message received: {'seq': 1, 'type': 'event', 'event': 'output', 'body': {'category': 'telemetry', 'output': 'ptvsd', 'data': {'packageVersion': '1.2.0'}}}
2020-12-01 20:36:48,241 - DEBUG - Message received: {'seq': 2, 'type': 'event', 'event': 'output', 'body': {'category': 'telemetry', 'output': 'debugpy', 'data': {'packageVersion': '1.2.0'}}}
2020-12-01 20:36:48,266 - DEBUG - Message received: {'seq': 3, 'type': 'response', 'request_seq': 0, 'success': True, 'command': 'initialize', 'body': {'supportsCompletionsRequest': True, 'supportsConditionalBreakpoints': True, 'supportsConfigurationDoneRequest': True, 'supportsDebuggerProperties': True, 'supportsDelayedStackTraceLoading': True, 'supportsEvaluateForHovers': True, 'supportsExceptionInfoRequest': True, 'supportsExceptionOptions': True, 'supportsHitConditionalBreakpoints': True, 'supportsLogPoints': True, 'supportsModulesRequest': True, 'supportsSetExpression': True, 'supportsSetVariable': True, 'supportsValueFormattingOptions': True, 'supportsTerminateDebuggee': True, 'supportsGotoTargetsRequest': True, 'exceptionBreakpointFilters': [{'filter': 'raised', 'label': 'Raised Exceptions', 'default': False}, {'filter': 'uncaught', 'label': 'Uncaught Exceptions', 'default': True}]}}
2020-12-01 20:36:48,267 - DEBUG - LAUNCH!
2020-12-01 20:36:48,267 - DEBUG - Sending Message: {"command": "attach", "arguments": {"request": "attach", "django": true, "type": "python", "name": "Subprocess 98", "connect": {"host": "127.0.0.1", "port": 22961}, "subProcessId": 98, "pathMappings": [{"localRoot": "/Users/user/Development/app", "remoteRoot": "/opt/app"}]}, "seq": 1, "type": "request"}
2020-12-01 20:36:48,289 - DEBUG - Message received: {'seq': 4, 'type': 'event', 'event': 'debugpyWaitingForServer', 'body': {'host': '127.0.0.1', 'port': 35331}}
2020-12-01 20:36:48,289 - WARNING - User Msg: Unhandled event: debugpyWaitingForServer
2020-12-01 20:36:48,441 - DEBUG - Message received: {'seq': 5, 'type': 'event', 'event': 'initialized'}
2020-12-01 20:36:48,443 - DEBUG - Sending Message: {"command": "setBreakpoints", "arguments": {"source": {"name": "thing.py", "path": "/Users/user/Development/app/lbs/api_internal/things/viewsets/thing.py"}, "breakpoints": [{"line": 125}]}, "sourceModified": false, "seq": 2, "type": "request"}
2020-12-01 20:36:48,444 - DEBUG - Sending Message: {"command": "setExceptionBreakpoints", "arguments": {"filters": ["uncaught"], "exceptionOptions": []}, "seq": 3, "type": "request"}
2020-12-01 20:36:48,509 - DEBUG - Message received: {'seq': 6, 'type': 'response', 'request_seq': 2, 'success': True, 'command': 'setBreakpoints', 'body': {'breakpoints': [{'verified': True, 'id': 1, 'source': {'name': 'thing.py', 'path': '/Users/user/Development/app/lbs/api_internal/things/viewsets/thing.py'}, 'line': 125}]}}
2020-12-01 20:36:48,510 - DEBUG - Breakpoints at this point: {
  "/Users/user/Development/app/lbs/api_internal/things/viewsets/thing.py": [
    {
      "verified": true,
      "id": 1,
      "source": {
        "name": "thing.py",
        "path": "/Users/user/Development/app/lbs/api_internal/things/viewsets/thing.py"
      },
      "line": 125
    }
  ]
}
2020-12-01 20:36:48,560 - DEBUG - Message received: {'seq': 7, 'type': 'response', 'request_seq': 3, 'success': True, 'command': 'setExceptionBreakpoints'}
2020-12-01 20:36:48,561 - DEBUG - Sending Message: {"command": "configurationDone", "seq": 4, "type": "request"}
2020-12-01 20:36:48,617 - DEBUG - Message received: {'seq': 8, 'type': 'response', 'request_seq': 4, 'success': True, 'command': 'configurationDone'}
2020-12-01 20:36:48,656 - DEBUG - Message received: {'seq': 9, 'type': 'response', 'request_seq': 1, 'success': True, 'command': 'attach'}
2020-12-01 20:36:48,657 - DEBUG - Sending Message: {"command": "threads", "seq": 5, "type": "request"}
2020-12-01 20:36:48,657 - DEBUG - Message received: {'seq': 10, 'type': 'event', 'event': 'process', 'body': {'name': 'manage.py', 'systemProcessId': 98, 'isLocalProcess': True, 'startMethod': 'attach'}}
2020-12-01 20:36:48,657 - INFO - User Msg: The debugee was started: manage.py
2020-12-01 20:36:48,696 - DEBUG - Message received: {'seq': 11, 'type': 'event', 'event': 'thread', 'body': {'reason': 'started', 'threadId': 1}}
2020-12-01 20:36:48,696 - DEBUG - Message received: {'seq': 12, 'type': 'event', 'event': 'thread', 'body': {'reason': 'started', 'threadId': 2}}
2020-12-01 20:36:48,698 - DEBUG - Message received: {'seq': 13, 'type': 'event', 'event': 'thread', 'body': {'reason': 'started', 'threadId': 3}}
2020-12-01 20:36:48,699 - DEBUG - Message received: {'seq': 14, 'type': 'event', 'event': 'thread', 'body': {'reason': 'started', 'threadId': 4}}
2020-12-01 20:36:48,699 - DEBUG - Message received: {'seq': 15, 'type': 'event', 'event': 'thread', 'body': {'reason': 'started', 'threadId': 5}}
2020-12-01 20:36:48,700 - DEBUG - Message received: {'seq': 16, 'type': 'response', 'request_seq': 5, 'success': True, 'command': 'threads', 'body': {'threads': [{'id': 1, 'name': 'MainThread'}, {'id': 2, 'name': 'django-main-thread'}, {'id': 3, 'name': 'ThreadPoolExecutor-0_0'}, {'id': 4, 'name': 'ThreadPoolExecutor-1_0'}, {'id': 5, 'name': 'ThreadPoolExecutor-1_1'}]}}
2020-12-01 20:36:48,701 - DEBUG - Sending Message: {"command": "threads", "seq": 6, "type": "request"}
2020-12-01 20:36:48,737 - DEBUG - Message received: {'seq': 17, 'type': 'response', 'request_seq': 6, 'success': True, 'command': 'threads', 'body': {'threads': [{'id': 1, 'name': 'MainThread'}, {'id': 2, 'name': 'django-main-thread'}, {'id': 3, 'name': 'ThreadPoolExecutor-0_0'}, {'id': 4, 'name': 'ThreadPoolExecutor-1_0'}, {'id': 5, 'name': 'ThreadPoolExecutor-1_1'}]}}
2020-12-01 20:37:21,090 - DEBUG - Message received: {'seq': 18, 'type': 'event', 'event': 'stopped', 'body': {'reason': 'breakpoint', 'threadId': 3, 'preserveFocusHint': False, 'allThreadsStopped': True}}
2020-12-01 20:37:21,090 - WARNING - User Msg: Paused in thread 3 due to breakpoint
2020-12-01 20:37:21,137 - DEBUG - Sending Message: {"command": "threads", "seq": 7, "type": "request"}
2020-12-01 20:37:21,317 - DEBUG - Message received: {'seq': 19, 'type': 'response', 'request_seq': 7, 'success': True, 'command': 'threads', 'body': {'threads': [{'id': 1, 'name': 'MainThread'}, {'id': 2, 'name': 'django-main-thread'}, {'id': 3, 'name': 'ThreadPoolExecutor-0_0'}, {'id': 4, 'name': 'ThreadPoolExecutor-1_0'}, {'id': 5, 'name': 'ThreadPoolExecutor-1_1'}]}}
2020-12-01 20:37:21,319 - DEBUG - Sending Message: {"command": "stackTrace", "arguments": {"threadId": 3}, "seq": 8, "type": "request"}
2020-12-01 20:37:21,534 - DEBUG - Message received: {'seq': 20, 'type': 'response', 'request_seq': 8, 'success': True, 'command': 'stackTrace', 'body': {'stackFrames': [{'id': 6, 'name': 'get_queryset', 'line': 125, 'column': 1, 'source': {'path': '/Users/user/Development/app/lbs/api_internal/things/viewsets/thing.py', 'sourceReference': 0}}, {'id': 7, 'name': 'do_revision_view', 'line': 55, 'column': 1, 'source': {'path': '/Users/user/Development/app/lbs/core/middleware.py', 'sourceReference': 0}}], 'totalFrames': 2}}
2020-12-01 20:37:21,798 - DEBUG - Sending Message: {"command": "scopes", "arguments": {"frameId": 6}, "seq": 9, "type": "request"}
2020-12-01 20:37:21,801 - DEBUG - Message received: {'seq': 21, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 0, 'name': 'lbs.api_internal.things.viewsets.thing', 'path': '/Users/user/Development/app/lbs/api_internal/things/viewsets/thing.py', 'package': 'lbs.api_internal.things.viewsets'}}}
2020-12-01 20:37:21,999 - DEBUG - Message received: {'seq': 22, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 1, 'name': 'rest_framework.mixins', 'path': '/usr/local/lib/python3.7/site-packages/rest_framework/mixins.py', 'package': 'rest_framework'}}}
2020-12-01 20:37:22,000 - DEBUG - Message received: {'seq': 23, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 2, 'name': 'rest_framework.views', 'path': '/usr/local/lib/python3.7/site-packages/rest_framework/views.py', 'package': 'rest_framework'}}}
2020-12-01 20:37:22,000 - DEBUG - Message received: {'seq': 24, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 3, 'name': 'rest_framework.viewsets', 'path': '/usr/local/lib/python3.7/site-packages/rest_framework/viewsets.py', 'package': 'rest_framework'}}}
2020-12-01 20:37:22,001 - DEBUG - Message received: {'seq': 25, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 4, 'name': 'django.views.decorators.csrf', 'path': '/usr/local/lib/python3.7/site-packages/django/views/decorators/csrf.py', 'package': 'django.views.decorators'}}}
2020-12-01 20:37:22,001 - DEBUG - Message received: {'seq': 26, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 5, 'name': 'django.core.handlers.base', 'path': '/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py', 'package': 'django.core.handlers'}}}
2020-12-01 20:37:22,001 - DEBUG - Message received: {'seq': 27, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 6, 'name': 'django.core.handlers.exception', 'path': '/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py', 'package': 'django.core.handlers'}}}
2020-12-01 20:37:22,003 - DEBUG - Message received: {'seq': 28, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 7, 'name': 'debug_toolbar.middleware', 'path': '/usr/local/lib/python3.7/site-packages/debug_toolbar/middleware.py', 'package': 'debug_toolbar'}}}
2020-12-01 20:37:22,003 - DEBUG - Message received: {'seq': 29, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 8, 'name': 'django.utils.deprecation', 'path': '/usr/local/lib/python3.7/site-packages/django/utils/deprecation.py', 'package': 'django.utils'}}}
2020-12-01 20:37:22,004 - DEBUG - Message received: {'seq': 30, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 9, 'name': 'lbs.core.middleware', 'path': '/Users/user/Development/app/lbs/core/middleware.py', 'package': 'lbs.core'}}}
2020-12-01 20:37:22,006 - DEBUG - Message received: {'seq': 31, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 10, 'name': 'reversion.middleware', 'path': '/usr/local/lib/python3.7/site-packages/reversion/middleware.py', 'package': 'reversion'}}}
2020-12-01 20:37:22,007 - DEBUG - Message received: {'seq': 32, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 11, 'name': 'whitenoise.middleware', 'path': '/usr/local/lib/python3.7/site-packages/whitenoise/middleware.py', 'package': 'whitenoise'}}}
2020-12-01 20:37:22,007 - DEBUG - Message received: {'seq': 33, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 12, 'name': 'channels.http', 'path': '/usr/local/lib/python3.7/site-packages/channels/http.py', 'package': 'channels'}}}
2020-12-01 20:37:22,008 - DEBUG - Message received: {'seq': 34, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 13, 'name': 'asgiref.sync', 'path': '/usr/local/lib/python3.7/site-packages/asgiref/sync.py', 'package': 'asgiref'}}}
2020-12-01 20:37:22,009 - DEBUG - Message received: {'seq': 35, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 14, 'name': 'concurrent.futures.thread', 'path': '/usr/local/lib/python3.7/concurrent/futures/thread.py', 'package': 'concurrent.futures'}}}
2020-12-01 20:37:22,010 - DEBUG - Message received: {'seq': 36, 'type': 'event', 'event': 'module', 'body': {'reason': 'new', 'module': {'id': 15, 'name': 'threading', 'path': '/usr/local/lib/python3.7/threading.py'}}}
2020-12-01 20:37:22,025 - DEBUG - Message received: {'seq': 37, 'type': 'response', 'request_seq': 9, 'success': True, 'command': 'scopes', 'body': {'scopes': [{'name': 'Locals', 'variablesReference': 8, 'expensive': False, 'presentationHint': 'locals', 'source': {}}, {'name': 'Globals', 'variablesReference': 9, 'expensive': False, 'source': {}}]}}
2020-12-01 20:37:22,025 - DEBUG - Sending Message: {"command": "variables", "arguments": {"variablesReference": 8}, "seq": 10, "type": "request"}
2020-12-01 20:37:22,368 - DEBUG - Message received: {'seq': 38, 'type': 'response', 'request_seq': 10, 'success': True, 'command': 'variables', 'body': {'variables': [{'name': 'self', 'value': '<lbs.api_internal.things.viewsets.thing.ObjectViewSet object at 0x7f02504a6a90>', 'type': 'ObjectViewSet', 'evaluateName': 'self', 'variablesReference': 10}]}}
2020-12-01 20:55:08,960 - DEBUG - Stop debug adapter with no callback
2020-12-01 20:55:08,961 - DEBUG - Sending Message: {"command": "disconnect", "arguments": {}, "seq": 11, "type": "request"}
2020-12-01 20:55:09,002 - DEBUG - Message received: {'seq': 39, 'type': 'event', 'event': 'terminated'}
2020-12-01 20:55:09,002 - INFO - User Msg: Debugging was terminated by the server.
2020-12-01 20:55:09,003 - DEBUG - Message received: {'seq': 40, 'type': 'response', 'request_seq': 11, 'success': True, 'command': 'disconnect'}
2020-12-01 20:55:09,052 - INFO - The server has terminated with status 0
2020-12-01 20:55:09,053 - DEBUG - No server exit handler

ross-weir avatar Dec 01 '20 10:12 ross-weir

I don't think there's anything about the "process" event that you'd need for this. It's only reported for the process that is being debugged in that particular session, always at the very beginning of it, and it seems to be purely informational. Even for process tree UX - if you choose to implement it similarly to how VSCode does - all the requisite info is in the "debugpyAttach" event.

int19h avatar Dec 02 '20 02:12 int19h

Thanks 🙏

puremourning avatar Dec 02 '20 07:12 puremourning

I'd like to have multiple debugging sessions at the same time as well for a different reason: I've got multiple Java applications in the same 'workspace' root (not sure if this is the correct word) and they communicate with each other through API requests and/or queues. Hence it'll be extremely handy if vimspector can attach to multiple applications simultaneously and set breakpoints in different sub-projects.

May I know whether my request is the same as this one or I should open a new ticket?

(Originally reported at dansomething/coc-java-debug#16)

Frederick888 avatar Dec 15 '20 12:12 Frederick888

May I know whether my request is the same as this one or I should open a new ticket?

It's essentially the same. Another issue won't make it come any faster.

puremourning avatar Dec 15 '20 12:12 puremourning

Yep, the way DAP is structured, every process has to be its own separate session. On debugpy side, when subprocess is detected and detoured, we send a custom event that basically contains the body of the "attach" event that is necessary to attach to that subprocess - the client has to handle that accordingly.

We are hoping to submit this sort of "reverse attach request" for standardization in the main protocol eventually. But that will only happen after this custom implementation had some time to prove that it's a solid approach.

Can't wait for this but have to wait, lol.

roachsinai avatar Dec 26 '20 14:12 roachsinai

For anyone tracking this, this should now work in the PR in #748 ; feel free to try it:

Screenshot 2023-04-12 at 15 05 22 Screenshot 2023-04-12 at 15 05 41

puremourning avatar Apr 12 '23 14:04 puremourning

Thanks a lot. Does it also implements https://github.com/puremourning/vimspector/issues/141#issuecomment-745255008 ?

gagara avatar Apr 12 '23 18:04 gagara

Thanks a lot. Does it also implements https://github.com/puremourning/vimspector/issues/141#issuecomment-745255008 ?

No not yet

puremourning avatar Apr 12 '23 18:04 puremourning

Thanks a lot. Does it also implements #141 (comment) ?

This is implemented in pr #756; feel free to check it out.

puremourning avatar Apr 20 '23 11:04 puremourning