3

Question

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.

Background

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...: Attach to docker process

Possible options

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.

Cœur
  • 37,241
  • 25
  • 195
  • 267
RB.
  • 36,301
  • 12
  • 91
  • 131
  • Further research leads me to believe that the [Debug Adapter Host](https://github.com/microsoft/VSDebugAdapterHost) is the component that displays the UI - I'm hoping I can use that programmatically perhaps. – RB. Oct 08 '19 at 14:09
  • 1
    Not familiar with that topic, but I'm trying to involve someone experienced in it, may it helps :) – LoLance Oct 10 '19 at 06:54
  • Hi RB, according to Pierson's answer, you may have to use EnvDTE in this process, you could consider marking it as answer if it resolves your issue. Thanks to Pierson! – LoLance Oct 11 '19 at 01:21

1 Answers1

3

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
    }
  ]
}
  1. 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

  2. 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);
RB.
  • 36,301
  • 12
  • 91
  • 131
Pierson
  • 96
  • 4