Runtime: Provide a way to attach a managed debugger to this process or a child process

Created on 5 Apr 2019  路  12Comments  路  Source: dotnet/runtime

I have a .NET Core process that starts another .NET Core process. I want to debug the child process with Visual Studio. I control the code for both processes, but still cannot do this!

Starting the parent process under the debugger is useless. Calling System.Diagnostics.Debugger.Launch() in the child process is useless, because that forces attaching a native debugger, not managed. Even if I check "Manually choose debugging engines" in the JIT debug dialog I cannot uncheck "Native", so I'm forced to use mixed-mode debugging. The child process then gets stuck on the Debugger.Launch() line and I cannot continue it.

Debugger.Break() does nothing if a debugger is not already attached.

Debug.Fail() and Debug.Assert(false) just crash the child process.

area-Diagnostics-coreclr enhancement

All 12 comments

@dotnet/dotnet-diag in case other team members have other ideas.

As far as I know, this is a limitation on Visual Studio more than anything. For the scenarios that I've come across where I needed this, I ended up using the Child Process Debugging Extension and had a relatively good experience. As you said, mixed mode was necessary.

Maybe @gregg-miskelly has some input here as well 馃槃 If you try that extension and have no luck loop back and I'll investigate some more possible suggestions.

The .NET debugging APIs don't provide a notification for child processes launches, so as @hoyosjs mentioned, currently the Child Process extension is the only good option. That should work with .NET Core on Windows.

Thanks a lot, @hoyosjs, that extension works! It would still be nice to fix the problem with Debugger.Launch, of course.

Here's another way to do it, by operating directly against Visual Studio APIs: https://github.com/dotnet/roslyn/pull/28519

That's useful, thanks! I'd rather not add a reference to the Visual Studio API to my project, so I prefer the extension solution.

@loop-evgeny Glad to hear that worked out for you. I'll take a look as to what can be done about Debugger.Launch when I get some time. I'd like to see what's preventing you from continuing the process, to see if it's a potentially weird issue, a bad user experience, or just something that is quirky but has an easy workaround we can document. Thanks for reporting this.

I could have used something like this today. An API like Debugger.Attach(Process p), that would attach the current (meaning Debugger.IsAttached == true) debugger to the process p. In my scenario p is process that I just created.

If you happen to control the code of the child process, you can add this loop to the beginning of the process as follow:

c# while (!Debugger.IsAttached) { }

Wouldn't it be better to Debugger.Launch() instead? That way I don't melt my CPU waiting for the debugger that may never attach.

The whole point though, is that I don't want to have to manually attach a debugger to the child process that I just created.

Wouldn't it be better to Debugger.Launch() instead? That way I don't melt my CPU waiting for the debugger that may never attach.

The whole point though, is that I don't want to have to manually attach a debugger to the child process that I just created.

Got it, the trick is meant for

  1. You do want to attach a debugger,
  2. You don't get to control the code that launches your process (e.g. msbuild), and
  3. You don't have a console to work with (So you can't just add a Console.ReadLine()) to wait.

Yeah, that's the scenario I mean. For the scenario you describe, the Debugger.Launch() api will trigger a debug attach request in the child process. You can then attach or decline, and the process will resume execution. No loop needed.

But, my original API was describing the inverse, where my parent process wants to attach the current debugger to a child process that it just started. That's the API that is missing.

IMHO, it would be better to have the controls for what process to debug be some setting in the debugger (like what the Child Process Debugging Extension does) then to have the app code be in charge of decided what to debug.

One tweak to the while loop from above, I would recommend sticking a Thread.Sleep call in the body of that loop. For example, add code that checks an environment variable to know if the 'pause on startup' is desired, and if so, enter that loop. If you are using VS, and if your process name is unique, you could then use an exe project to attach to the process fairly easily. Clearly not ideal, but about the best that can be done right now.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jkotas picture jkotas  路  3Comments

Timovzl picture Timovzl  路  3Comments

btecu picture btecu  路  3Comments

bencz picture bencz  路  3Comments

iCodeWebApps picture iCodeWebApps  路  3Comments