-
Notifications
You must be signed in to change notification settings - Fork 357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for process dumping of native and managed code (C++ and C#) #151
Comments
Are you refering to creating a dump or core file? If so you have a few options: On windows - call the win32 API MiniDumpWriteDump() or use any of the windows tools that capture dumps such as ProcDump, Visual Studio Debugger, windbg, or the OS Process Manager. Is that what you were looking for? [Edit]: Specifically for exceptions, watson or a debugger like Visual Studio can help on Windows. On Linux the CreateDump utility has environment variables that will automatically collect crash dumps when an unhandled exception occurs. |
I would like to use API's like this: But main problem is that they do not support native C++ code. It would be perfect if |
I guess at the moment I'm looking only solution for Windows / 64-bit architecture only, other OS support could wait, but eventually API's could become portable. |
MiniDumpWriteDump - guess something similar also needs to be supported for managed side as well. Basically use case is that unknown exception (C# Exception or C++ any exception or page fault) occurs in your application. |
I'm not sure what you mean here. You can call MiniDumpWriteDump on a process that is running .Net Core. Unless you are trying to capture a triage dump on Windows OS older than TH3 I'd expect this to work well. However there would be a different issue in the scenario you described, MiniDumpWriteDump is not designed to take a dump of the same process it is executing within. Self-dumping is inherently problematic and developers have historically resolved that problem by using a 2nd process. For example when an application crashes and triggers Watson, the Watson service launches a process called WerFault.exe to collect the crash dump. If the exceptions you want to capture are crashing your application you could always use Watson's local dump feature. If you are trying to create dumps of exceptions that do not go unhandled then you probably want to call CreateProcess() to launch a helper process and get that helper process to call MinidumpWriteDump on its parent.
You could either use an interop layer (COM or reverse p/invoke) to call CLRMD using C++ code, or there is another API called ICorDebug which is written in C++. The APIs aren't identical, but you can accomplish similar things with them. ICorDebug is unfortunately not as well documented and requires a quite a bit more effort to use so many people prefer CLRMD, but it is a tested and working option if using a C++ library is a critical factor for you.
Thanks for the feedback! Practically speaking we don't have anything like this in the works right now so hopefully one of the options above will still suffice. |
I think it makes sense to have WerFault.exe as special service or host, which can be used to collect process state and information about it. API must be usable from native C++ and from managed C# side, and must be well designed in both cases. (Simple to use, but having technical mechanism to perform all execution scenarios)
I'll try to return back to exception and their handling later on - I have some ideas about them. But in here I would like to halt program and freeze it's execution at that very moment of time.
Basically I don't want to touch any API or design which is either native or managed code specific - we have application which consist code of both worlds, and I think both worlds need to walk hand by hand in design, API, easiness to use, cooperating with each other. I do understand that both worlds are quite far from each other, but one approach is to improve both world simultaneously, driving in best design and API practices.
This is first indication of API, which will vanish next time you come to update it's functionality - I would say it's bit risky to use it. We could make this also so that I will start to write code according to your instructions, using API's proposed by you - I'll try to simplify solution, API's, and make implementation native/managed code neutral - but newly written .dll's could be transferred under Microsoft responsibility. Also if there will be heavier problems with design, implementation, or windows API itself, you could drive in necessary changes into windows as well. |
Perhaps I misunderstood what your goals were. I thought you were trying to get information about APIs and tools that already existed, but now I think you are trying to design a new API. Is that correct?
Despite having limited documentation, ICorDebug API has existed since .NET Framework 1.0, nearly 20 years. We've added to it over time, but once the APIs exist they are stable and supported. This API is also used extensively by Visual Studio debugger. There may be other reasons you choose to not to use this API, but I don't think you need to worry about stability or lack of support.
If you are looking for the folks at Microsoft to collaboratively develop a new feature or to take responsibility for its maintainence, the first step in that process would defining clearly what the use case and why the existing solutions aren't suitable. Above you described some properties of the API you are looking for, but not so much the use-case that would require it to be that way. For example lots of users already can use Watson to get a crash dump for unhandled exceptions and its not clear to me that they would want to use any API even if we gave them an amazing one. I think there are probably other scenarios where this could be useful, but its good to have everyone on the same page about exactly what the goal is and what problems are being solved. Just to be transparent, I doubt this is a project our team would take on right now unless we saw a large community interest, but we're glad to explore, to get feedback, and to provide guidance that might help you make forward progress even if we don't take ownership of it. |
I suspect it should be new API. It's possible indeed that you can you 2-X existing API's, but from my perspective it should be hidden / non-visible to end-user.
I have tried to make mixed mode call stack walker, using more than 3 API's altogether - that solution lasted for 3 years before was broken. I think if complexity goes over 3 API's - better to create one new (which can recombine 3 or more existing - but invisible to end-user).
You're right. I have raised another issue in here: Let's start from that one - I suspect that in order to dump mixed mode application exception, you need to catch it first - but after that you can either attach debugger to it (wait until debugging starts) or perform whole application dump. For dumping application whole watson could be used theoretically - but:
|
The primary use-case for Windows Error Reporting doesn't utilize any API, your .NET app throws an unhandled exception, the OS unhandled exception filter is called, and Windows Error Reporting is automatically invoked to capture a dump. There are some other APIs such as WerReportCreate and here is a random web page I found which showed invoking it from managed code.
The primary use-case where the app crashes definitely works with managed code, we see lots of crash reports that come back to Microsoft with .Net Core unhandled exceptions in them. The support for .Net Core minidumps was added in Windows 10 TH3 I believe, so virtually any Windows 10 user should have that as this point. I haven't personally tested the use cases that explicitly call the ReportCreate API and its much less common, but I don't know of a reason it wouldn't work. While thinking about this last night I did come up with a couple dump related use-cases that might be interesting for .Net runtime to support in the future. I don't know if any of these sounds relevant to your personal goals but throwing it out there:
|
For 1 & 2 - we are looking for windows support at the moment, can this be ported to windows ? 3 - needs to be analyzed. Found also this one: https://chromium.googlesource.com/crashpad/crashpad/+/master/doc/overview_design.md Need to analyze if that one supports managed code. |
Here is another alternative as well: https://github.com/backtrace-labs/crashpad/tree/backtrace |
I was proposing possible future use-cases that might justify the runtime team to maintain an API that seemed similar to what you were proposing. None of these are work that we currently have scheduled. I think you are asking slightly differently if dotnet-dump / CreateDump can be supported on Windows. For dotnet-dump yes we plan to support it on Windows. For CreateDump there is no technical limitation, but it is not a priority for us right now. |
Can you check chromium crashpad - I think it looks good as well. I've managed to build it relatively easily on windows, besides linux support there is also macos & android (experimental) support. Wondering if it makes any sense to upgrade that one to support managed code as well:
|
I'm not sure why self-dumping is considered as problematic. I guess main problem is to catch the exception originally, then process dumping can be performed. I would guess that main problem is https://github.com/tapika/stacktrace/blob/develop/src/exception_handler.cpp
But after we managed to catch an exception, self-dumping will be also possible, something like this is for example performed by dmchook4: https://github.com/muhopensores/dmc4_hook/blob/master/src/dmc4_hook/utils/crash_handler.cpp In similar manner to my boost/stacktrace code it will use minhook to intercept exception callbacks. So main problem is (as described in my own implementation): Using also MH_EnableHook instead of But process dumping might be more difficult, as Do you see any other problem than mentioned above ? One more problem I have not yet tackled - is stackoverflow exception for mixed mode c++, process simply dies after that exception occurs, suspect need even to hook Still have a mixed mode c++ call stack to resolve, and process dumping indeed looks more difficult. |
I created a .NET library that bundles crashpad to create a minidump of the .NET process on a native crash. Works on macOS, Linux and Windows. So far it doesn't show managed frames though, so I'm looking here how I could use https://github.com/getsentry/sentry-dotnet-minidump |
In order to convert instruction pointers into symbolic method names you need to do two translations:
SOS, CLRMD, windbg, and VS can all do it, but the right portions of process memory have to be present in the dump file. If you are using an off-the-shelf dump generation tool there is a good chance that tool has no understanding of how to locate the relevant memory needed because the logic is specific to the exact version of .NET runtime being used. You can side step this problem by capturing all virtual memory but this gives you very large dumps. All of the simple ways I know of to capture the right set of memory in your dump involve using the tools that the .NET team built:
If you already have a dump that has the right memory captured, converting to an IP to a string name for the function is fairly easy. In CLRMD invoke ClrRuntime.GetMethodByInstructionPointer(). In terms of collaboration I'm glad to try answering questions and getting you pointed in the right direction : ) More contribution beyond that largely depends what the goals for the project are. At this point the library sounds quite similar to support we already have in the WriteDump() API so I'd want to understand if there are advantages to the new library relative to what already exists and works. HTH! |
Quite many different things happened about which I haven't mentioned in here. Basically exception handling which I've coded does work, but there are exception from rules, namely my own
This is catched by my C++ exception handling, not .net framework. (Other exception types should be ok - see 32-bit exception handling also does not work, there is a need to hook different functions. (Copied from: dotnet/runtime#12405 (comment)) I've left code in commented state, but my goal is to support 64-bit / windows, so don't care so much about 32-bit support. See https://github.com/tapika/stacktrace/blob/develop/src/exception_handler.cpp#L206 I did not finish managed call stack determination support, but what I have analyzed - https://github.com/microsoft/clrmd can do same things as C++ can, only C# calls windows functions via invoke. Theoretically call stack reconstruction could be done even from C#. I have proposed for boost::stacktrace developer / Antony Polukhin to detach stack trace from But one approach is to completely abandon boost::stacktrace and re-write everything in C#. But I haven't analyzed any deeper - at the moment my own boost::stacktrace + my exception handling is active But besides exception handling it can halt application from crashing. (I'm translating native C++ exception to managed .net exception, and application will only display message, but not crash) We had quite long conversation with coreclr developer on this subject, if you want to read: Meanwhile - in our code I've observed exceptions happening from both - from C++ and from C# code. To have more strict control over C# code, I've also altered xunit, see brief discussion in here: Please let me know if there is something I can do for you. Uff.... I hope my message did not blow your mind. :-) |
See also https://github.com/dotnet/coreclr/issues/23681
When exception occurs in application, it should be possible to dump it's state, including native and it's managed counterparts. (C++ and C#), and restore it back later for debugging.
The text was updated successfully, but these errors were encountered: