getsentry / sentry-dotnet-minidump

Capture Minidump of .NET Applications
26 stars 3 forks source link

Alternative Minidump creation #1

Open bruno-garcia opened 3 years ago

bruno-garcia commented 3 years ago

The minidump created by crashpad works fine and all native frames get correctly symbolicated. But to expand the server into symbolicating managed frames, DAC EnumMemoryRegions needs to be used to read the memory sections needed by the .NET debugger like ClrMD or sos into the minidump. That would require a patch to crashpad (tough to get accepted) and a lot more low level work than simply using the cross platform tool provided by .NET to create minidumps cross platform.

More context here: https://github.com/dotnet/diagnostics/issues/1885

There are many options too instead of shelling out a program. A wealth of information on this comment from @noahfalk:

https://github.com/dotnet/diagnostics/issues/151#issuecomment-756588099

Alternative 1: Bundle .NET's createdump tool to create the minidump

It's possible the lib would need to multi-target and provide a version of createdump for the right CLR version.

Alternative 2: Use Microsoft.Diagnostics.NetCore.Client

This is to use the main Sentry .NET SDK to kick off the dump creation programatically and on restart/or a bundled handler .NET program to upload it. Or even upload on app restart with the .NET SDK, minidump in envelope.

Alternative 3: Call WriteDump from Microsoft.Diagnostics.NetCore.Client

Docs

Some limitations:

The process hosting the library needs to be NS2.0 or a netcoreapp2.1 or later. However, the target process needs to be 3.1 or above (5.0 if you want windows dumps, and 6.0 for machO native dumps as Noah pointed out) to get the dump support. From this comment

Thanks @dbruning for the link

dbruning commented 3 years ago

dotnet/runtime/issues/56135 is discussing mechanisms to allow an app to request that the runtime take core dumps if the app crashes. That might be another alternative mechanism to create the dump, and then maybe the app could check for dump file on restart & submit it to Sentry for analysis.

dbruning commented 3 years ago

I think all of those 3 options would require a separate process to be spawned & asked to monitor the process ID of the main app's process. I don't think it's possible to take a dump of a process from inside the process. And I imagine the monitoring process would require admin rights to read from the main app's process. So that's probably not going to work for apps that don't already require admin rights?

noahfalk commented 3 years ago

I think all of those 3 options would require a separate process to be spawned

They do. In options (2) and (3) the runtime is spawning that process for you, in option (1) you would be spawning it yourself when you launched createdump.

And I imagine the monitoring process would require admin rights to read from the main app's process

This gets a bit nuanced because different environments have different rules. Options (2) and (3) should work correctly for an app launched without admin permissions on Windows, Linux, and MacOS outside of a container environment. Inside of a container I think we've seen it depend on configuration. On Linux it would normally require admin rights to get ptrace permissions, but there is an exemption that a parent process can give ptrace permissions to a child process it creates. We utilize that exemption by having the dotnet process being dumped spawn the createdump child process which will capture the dump.

AraHaan commented 3 years ago

I think it can actually capture itself with no issues, I opened a PR to my repository as well to my MiniDump library which registers an UnhandledException event handler which then generates the dump then deploys an event telling the user that it was dumped as well as that they should set the exit code explicitly on their end in that event.

You can find it at https://github.com/Elskom/Sdk/

wfjsw commented 12 months ago

I think it can actually capture itself with no issues, I opened a PR to my repository as well to my MiniDump library which registers an UnhandledException event handler which then generates the dump then deploys an event telling the user that it was dumped as well as that they should set the exit code explicitly on their end in that event.

You can find it at https://github.com/Elskom/Sdk/

I suspect in the cases when a memory dump is needed, the UnhandledException will actually not be triggered.

AraHaan commented 12 months ago

Another option would to p/invoke dbghelp.dll and calling MiniDumpWriteDump as well. Just only certain fields seems to work with .NET processes when creating minidumps though.

wfjsw commented 12 months ago

In .NET Core, when an unmanaged code happens to raise an Access Violation (or similar things), the runtime will crash right away and no managed code is going to have any chance to execute. (I might have mistyped something in the earlier comment)

AraHaan commented 12 months ago

In .NET Core, when an unmanaged code happens to raise an Access Violation (or similar things), the runtime will crash right away and no managed code is going to have any chance to execute. (I might have mistyped something in the earlier comment)

That is why if you add your own native code to it, it must also register a native exception handler as well.

wfjsw commented 12 months ago

I don't think I've seen native code in that. Could you please point me to that?

bruno-garcia commented 11 months ago

In .NET Core, when an unmanaged code happens to raise an Access Violation (or similar things), the runtime will crash right away and no managed code is going to have any chance to execute. (I might have mistyped something in the earlier comment)

We solved this for AOT compiled .NET 8 code in our next release.

With the Sentry SDK for .NET version 4.0.0 and forward (currently 4.0.0-beta.0) we bundle sentry-native in Windows, macOS and Linux (similar to what I tried to do originally in this repo).

You can see it in nuget.info: https://nuget.info/packages/Sentry/4.0.0-beta.0

image

We also bundle sentry-cli in the package, so when you compile your project in Release mode, we can upload all debug files to Sentry automatically. Docs for configuring that here.

All .NET error capturing works the same as JIT. But if it has a hard crash, a minidump is captured with all your C#-land breadcrumbs, tags, etc.

vaind commented 11 months ago

Just to clarify, this bit is WIP (https://github.com/getsentry/sentry-dotnet/issues/2770):

All .NET error capturing works the same as JIT. But if it has a hard crash, a minidump is captured with all your C#-land breadcrumbs, tags, etc.

wfjsw commented 11 months ago

Is that a AOT-only thing? I guess it would be long until WPF got its AOT support... I'm looking for a JIT solution.

bruno-garcia commented 11 months ago

Is that a AOT-only thing? I guess it would be long until WPF got its AOT support... I'm looking for a JIT solution.

Tracking minidump support for JIT runtime here: https://github.com/getsentry/sentry-dotnet/issues/2076 To confirm that's CoreCLR you're looking for, right?

Could you please write about your use case on that ticket instead?