runtime: Windows exception during mixed debugging truncates stack
This issue only happens with .NET Core, but it isn’t clear to me whether this issue is most likely the fault of CoreCLR, Visual Studio, or both. If this is better suited for VS Feedback, I can post it there instead.
Environment
- .NET Core SDK 2.2.104
- Also reproduced with 3.0.100-preview3-010431
- Windows 10 1809 (Build 17763.348 - Latest updates installed)
- Visual Studio 2017 15.9.8
- Also reproduced with Visual Studio in safe mode.
- Also reproduced with Visual Studio 2019 16.0.0 RC.1 SVC1)
Summary
The call stack shown in Visual Studio is truncated when the process is stopped by a SEHException and native code is debugging, but only under .NET Core. (.NET Framework shows the full stack as expected.)
To reproduce, create a new .NET Core console app, populate Program.cs as follows:
using System;
using System.Runtime.InteropServices;
namespace WindowsExceptionNukesStack
{
public static class Program
{
[DllImport("Kernel32.dll")]
public static extern void RaiseException(int exceptionCode, int exceptionFlags, int numberOfArguments, IntPtr arguments);
public static void Main(string[] args)
{
Console.WriteLine("Before exception");
RaiseException(0, 0, 0, IntPtr.Zero);
Console.WriteLine("After exception");
}
}
}
Launch the application from Visual Studio, the Windows exception is translated into a SEHException as expected. The call stack ends at the managed to native transition as expected:

Create/modify launchSettings.json to enable native code debugging:
{
"profiles": {
"WindowsExceptionNukesStack": {
"commandName": "Project",
"nativeDebugging": true
}
}
}
Launch again, the call stack will be truncated, showing only a WaitForSingleObjectEx call. This remains true if you load symbols from Microsoft’s symbol server:

Modify the project file to use .NET Framework instead:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>
</Project>
Launch again, the call stack is not truncated and shows both managed and native stack frames as expected:

About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 1
- Comments: 24 (17 by maintainers)
I’ve managed to stumble upon this issue when investigating similar problems in my project. It seems if a native exception happens or even
__debugbreak()is called then managed frames are completely missing. This is making debugging problems happening in native code fairly difficult.As @PathogenDavid mentioned - this issue is being bounced from one milestone to another - is there any hope that somebody will look into that?
My info: running .net 6 on windows and app is x64. pinvoke into a simple function that has
__debugbreak()in it also truncates managed callstack.cc: @janvorli and @tommcdon since it seems this issue got completely stuck after some back and forth. Any hope that this can be resolved, should a contributor look into that?
cc: @jkoritzinsky since you are working on a source gen based pinvoke - is that behavior better when generated bindings are used?
@mgexo I am not sure if everyone in this thread is also using app-local .NET Core Runtimes but I found the root cause for the App Local runtime case. If you would like to be informed when a version of Visual Studio with the fix ships, please open a Visual Studio feedback ticket (Help->Send Feedback->Report a problem), paste a link to the feedback ticket into this issue, and I can connect it up.
@PathogenDavid there are a few known bugs with interop debugging, even from the framework days. Most of them vanish when you debug mixed mode x64. I haven’t seen that many interop debugging bugs reported on CoreCLR, so I’d expect the maturity here is helping us. During these type of migrations what you might find easier is keep framework, and try to have most components target
netstandard. Then start porting the components that are really Core vs Framework specific to core at last. This should help flip a switch in a bit of more ease at the end. Also, as things go, do you have the possibility to target release versions but also help us tests the fixes on 5.0 runtimes? It would be nice to have customer validation here 😄As for this, I have a hunch that something in the Core implementation of some stub or something alike changed some invariant we used to hold as valid. If this messes with the frame structure somehow, it’s possible that it is really confusing our stack-walking code; it wouldn’t be the first time that we have some address-range logic that fails in some edge cases and we end up stopping to unwind too early/late or not doing it quite right. This hits especially hard when you are using mixed mode debugging, as your app is being debugged using several engines. Visual Studio will have to defer to the appropriate engine to unwind part of the stack. When unwinding the managed frames, our code has to give back information on the frames and some stack pointer information. it sounds to me that we are returning the wrong stack pointer at the point of a transition to native code. Then, when VS tries to keep unwinding the native frames, they choke because the information we give back is not accurate. Some previous cases where I’ve seen such wrong pieces of information being handed back are: self-modifying code (modify thread context and stack layout/memory corruption), special frames (i.e. transition frames we can’t identify in the debugger), corrupting exceptions such as stack overflow (for example, your last screenshot before the SEH shows that there’s a GSCookie_check, which if it fails tells me some stack check failed, and that’s interesting). I’d need to take a closer look here to be able to tell for sure.
@PathogenDavid thank you for opening the feedback item. We are working with the appropriate teams to investigate the issue.