How do I programmatically attach to a .NET Core process running inside a Docker container on my local machine?
Specifically, I have an integration test which runs a set of Docker containers. I want to attach a debugger to a process inside one of those containers. I know the container, and the process, so all I am looking for is a mechanism to actually attach the debugger programmatically so that when I debug my integration test, I can debug straight into my application.
In Visual Studio 2019 it is possible to attach a debugger to a process running inside a Docker container.
When you start your container mount an additional volume containing vsdbg (for example, %USERPROFILE%\vsdbg\vs2017u5) as /remote_debugger.
docker run -v "$($env:USERPROFILE)\vsdbg\vs2017u5:/remote_debugger:rw"
You can then attach a debugger using Debug -> Attach to Process...:

I suspect that I can do it using EnvDTE (as per this answer) but I was hoping for a simpler mechanism if there is one, as EnvDTE-based solutions are often a maintenance headache.
You can use a combination of these offroad debugging steps to set up a launch.json that the Debug Adapter host will support.
It will be necessary for you to use EnvDTE to call DebugAdapterHost.Launch command as you probably don't want user intervention. This MSDN article shows how to get the CommandWindow in Visual Studio so you can send the command.
The steps are:
1. Create a launch.json file like below:
{
// NOTE: replace 'my_container_name' with the name of the container you want to connect to
"version": "0.2.0",
"adapter": "docker.exe",
"adapterArgs": "exec -i my_container_name /remote_debugger/vsdbg --interpreter=vscode",
"configurations": [
{
"name": ".NET Core Docker Attach",
"type": "coreclr",
"request": "attach",
// replace with the process id you want to attach to. You can find this by running 'pidof' in the container
// ex: `docker exec -it my_container_name pidof dotnet`
"processId": 93
}
]
}
Use this command to call your launch.json file:
DebugAdapterHost.Launch /LaunchJson:"<path-to-the-launch.json-file-you-saved>" /EngineGuid:541B8A8A-6081-4506-9F0A-1CE771DEBC04
Get the command window from the DTE (quick and dirty code sample):
DTE dte = (DTE)Package.GetGlobalService(typeof(SDTE));
Window window = dte.Windows.Item(EnvDTE.Constants.vsWindowKindCommandWindow);
window.Activate();
CommandWindow commandWindow = window.Object as CommandWindow;
string command = "DebugAdapterHost.Launch " +
"/LaunchJson:\"path/to/launch.json\" " +
"/EngineGuid:541B8A8A-6081-4506-9F0A-1CE771DEBC04";
commandWindow.SendInput(command, true);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With