-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support to retry attaching within a specific timeout #7331
Comments
Blocks microsoft/vscode-docker#1255 |
Isn't the problem the fact that the preLaunch task returns even before the script has completed. I.e. it's not really an issue with the python extension. However an issue with the preLaunch script. preLaunch functionality isn't something that's provided by the extension. The extension is doing what it's meant to do. It starts the debugger when VSCode yes it when it's time to do so. I.e. the race condition is VSCode specific or due to the preLaunch retuning too early |
@DonJayamanne VSCode does actually wait until |
Since it's expected that the entrypoint is a long-running application, the |
Not sure how this is a bug in the extension. We aren't in control of the preLaunch task or any of that orchestration! |
Same problem could happen with other debuggers. |
It's not a bug, but it's a shortcoming that can't be addressed by Docker itself or by the Docker VSCode extension (they have no idea what constitutes 'the debugger listener is ready' or how to detect it). For comparison, the Node.js debugger has a timeout parameter that can help in this sort of scenario: https://github.com/microsoft/vscode-node-debug2/blob/965054f347a8f4ea4a690f82083e9ad8f708633e/package.json#L301 |
Updated label as enhancement (confused as you originally filled it as a bug). |
Here's the problem--this blocks all remote attach scenarios if you want to start up the remote process with a preLaunchTask. It is not limited to just Docker. There are only two choices--either you wait on For VSCode-Docker in particular, if we had VSCode's CustomExecution we could introduce a sleep after launching the container, but that API is still proposed and has been since March. Without that API there's no way to do a sleep other than to explicitly put a dummy sleep task as the preLaunchTask, which is a pretty ugly user experience. Nevertheless, sleeping is a clunky workaround to the problem. |
Proposed solution
|
@bwateratmsft If you incorporate this, then there's no need to modify the extension. Makes it more bullet proof (no need to change, node, python and other language specific extension to get around this issue with preLaunchScript in the docker extension). E.g. creating a custom debugger in docker extension would also resolve this. This way docker extension can wait for the port to be opened. |
I have looked into health checks, but there's still problems:
Again, this is not specific to Docker. This is any scenario where the user wants to do remote debugging and use a preLaunchTask to start the remote debugger. Why would any other extension need to make changes? If the Python debug extension had a |
Java, C#, and other languages would have similar issues when waiting for ports to open... I'm just looking for a way to resolve this in a generic way, without having to add retires, that sounds hacky. Anyways based in what you're saying it doesn't sound like we have a choice. |
I haven't looked into Java yet so I can't speak for it, but for .NET debugging retry is already built in between vsdbg and the debug adapter. In any case our usage is primarily Node, with .NET Core and Python in second and third. No other languages come even close to these three. |
I got one part about .NET Core wrong; we don't launch vsdbg inside then attach, rather we launch it interactively with |
@karthiknadig @int19h /cc |
I wonder if it would help if you could reverse the direction of the connection? i.e. from Docker to VSCode, rather than the other way around? Basically the order for the debugger bits would be:
It sounds like this would solve the prelaunch problem? |
@int19h I'm not really sure how that works, can you elaborate? We are constrained by the order of execution that VSCode does things with (debug config resolved, preLaunchTask(s) executed, debug config 'executed'). In our case, it's this:
Would it still be possible to do what you're describing, while constrained with that order? I'd definitely be interested to hear more about this approach. EDIT: rephrasing for clarity |
In particular, one thing I do want to avoid is cramming everything into |
To clarify the specifics. We have an (experimental, not officially advertised or supported yet) feature in our prerelease bits where you can do this in debug config in launch.json: "request": "attach",
"host": ...,
"port": ...,
"listen": true, If you do this and then start the debug session, it will sit there and wait for the incoming connection. And you can tell ptvsd to initiate by either using On the protocol level, what happens there is that VSCode will send the "attach" request, but it won't receive "initialized" event or the "attach" response until there's a socket connection from the adapter to the debuggee. So if I'm understanding everything correctly, the way this will work in your scenario is that the preLaunchScript will return before the actual script completes, and move on to start the debug session. But the debug session, once started, will then block waiting for connection, and that will only happen once the script completes and starts the debuggee. So you wouldn't really need to sync anything explicitly. |
It is definitely possible that the the client part in the container starts up before the listener is ready on the host--would that fail as it does currently? If so we'd still have the race condition, just swapping the client/server. |
Ahh, I see what you mean now. Yes, it would also be a race condition... Can you clarify how this flow works with vsdbg.exe? Specifically, at which step do you launch it, such that it is guaranteed to be there and listening by the time the debug session starts? Our new adapter design has an out-of-process bit as well, and I'm thinking that it might be possible to rig it to be used in a similar way, but it depends on the details. |
For .NET Core / vsdbg, it looks like this:
|
So, basically the C# extension lets you customize the command line for spawning the adapter, which allows it to be spawned remotely inside the container via the appropriate helper - and then it's really a "launch" scenario, where the remote adapter starts the process within the container? It sounds like this approach could be reused. We spawn our new out-of-proc adapter via |
Yes, for C# it truly is a 'launch' scenario instead of 'attach'. That approach would work great for us, if you're already working toward it anyway. If it helps, here's where their settings start: https://github.com/OmniSharp/omnisharp-vscode/blob/6405d17613152249d820a11e1120d03fdc8f20df/package.json#L1123 And here's an example of what we resolve (some irrelevant bits removed for brevity) that results in launching 'TestWeb.dll':
Of note, the C# extension will call pipeProgram + pipeArgs from within pipeCwd, ( Then, to VSDBG, it instructs it on launching the process, with program + args from within cwd: Our actual code for this starts here: https://github.com/microsoft/vscode-docker/blob/35513c85ade31e0b6c6e8924f3055dbe828dd174/src/debugging/netcore/NetCoreDebugHelper.ts#L140 As far as vsdbg is concerned, it's just launching a |
Closing as stale. |
Hey guys! I have a different usecase, but could benefit from debugger attach retry. I've got a Django app running in a docker-dompose cluster, launched with How an I configure debugger launch configuration, so that it would try to reconnect debugger session, when Django process restarts? It takes about 5-10 secs to restart Django process and relaunch In my current setup, Django spins up with # manage.py
if __name__ == "__main__":
from django.conf import settings
from django.core.management import execute_from_command_line
if settings.DEBUG:
if os.environ.get('DJANGO_SETTINGS_MODULE').split('.')[-1] == 'docker-local':
DEBUG_PORT = 8001
import ptvsd
ptvsd.enable_attach(address=('0.0.0.0', DEBUG_PORT))
print(f'VSCode debug tools attached. Listening on port {DEBUG_PORT}')
execute_from_command_line(sys.argv) Debugger launch configuration: {
"version": "0.2.0",
"configurations": [
{
"name": "Django: Docker debug",
"type": "python",
"request": "attach",
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/src"
}
],
"port": 8001,
"host": "127.0.0.1",
"listen": {
"port": 8001,
"host": "127.0.0.1",
}
}
]
} |
Summary
Environment data
Steps to reproduce:
docker run -dt -v C:\Users\brandonw\.vscode\extensions\ms-python.python-2019.9.34911\pythonFiles:/pydbg -v ${workspaceFolder}:/app -w /app -p 5678:5678 --entrypoint python python:alpine /pydbg/ptvsd_launcher.py --default --host 0.0.0.0 --port 5678 --wait myApp.py
Expected behaviour
Attach works if preLaunchTask is used to start a waiting debug server with ptvsd
Actual behaviour
Attach does not work. No error is shown, it appears like debugging starts and immediately stops. If you comment out the preLaunchTask in launch.json, and then manually run the task with Ctrl + Shift + P > Run Task, it will start the container. If you then F5 it attaches successfully. I've also tried putting a dummy task containing a 2-second sleep inbetween, and this also works. So it seems to just be a race condition.
Logs
Nothing is output in Python output window, nor in Developer Tools console window.
Workspace
.vscode/launch.json:
.vscode/tasks.json (note, you'll need to change the C:\users\brandonw...\pythonFiles:/pydbg path):
myApp.py:
The text was updated successfully, but these errors were encountered: