0

Currently, there is no way (at least I did not find a way) to catch fatal exceptions (such as Stack Overflow, Segfault, ..) with try-catch block.

I already started issue at .net core repository so for more details you can read there (https://github.com/dotnet/core/issues/4228)

What I'm trying to do is to make the application not crash when there is any segfault/stack overflow/any fatal exception in loaded unmanaged code. what happens now is that .NET CLR kills my application if any fatal error occurs.

Example: In c# managed code loaded external c++ dll via kernel LoadLibrary function. Assume the dll is intentionally created for robustness testing therefore when a specific function is called it triggers segfault (e.g. trying to get data from outside of array bounds). When this error happens this gets caught by .net CLR and immediately kills the calling managed c# code(application).

What I would like is just report that this happens instead of dying silently. I did some research and found out there is the reasoning behind that which is described in the issue above.

Chris Catignani
  • 5,040
  • 16
  • 42
  • 49
Faelon
  • 1
  • 1
    It's a *fatal* exception. It means the application is in an unrecoverable state. Especially `seg fault` - something tried to write to an invalid memory address. You no longer have any idea what the application's memory contains – Panagiotis Kanavos Feb 07 '20 at 13:14
  • 1
    `intentionally created for robustness testing therefore when specific function is called it triggers segfault` it's not robust at all then. C++ has the [out_of_range](http://www.cplusplus.com/reference/stdexcept/out_of_range/) exception for this and a seg fault is definitely *not* appropriate. You can log such exceptions but you can't keep the application running once it gets into such a bad state – Panagiotis Kanavos Feb 07 '20 at 13:16
  • 1
    This is a bug in the library or the client code. Instead of throwing an exception, the library is invoking the nuclear option. Or the client assumes that a fatal library error can be ignored in some way. The only reason for a seg fault is a library bug though - the library should ensure it *doesn't* try to access anything out of bounds – Panagiotis Kanavos Feb 07 '20 at 13:19
  • 1
    One can use vaccines to prevent being sick (try - catch). There is actually no vaccine that prevents being killed by a meteor shower (fatal error) – Cid Feb 07 '20 at 13:20
  • Assume the library was perfect. In that case the SEG FAULT would come from the OS itself, because it detected that *something* tried to access another process's memory, or tried to execute data or something else that indicates a fatal condition. The OS isn't going to allow an application to remain alive after this – Panagiotis Kanavos Feb 07 '20 at 13:23
  • let me clarify my case a bit. The library I am loading is library i have no control over whatsoever, therefore i cannot change it, if i could i would fix the library itself. All im hoping to do with the try catch block is ONLY logging the exception (and showing user that there was some error in GUI for example). Also i would like like that GUI itself would not crash... I can imagine that i want to log the failure, write to user that there was problem, but i want to let him keep using the gui – Faelon Feb 07 '20 at 14:26
  • @Cid there isnt vaccine for that, but there are radios that will tell you that someone has been killed by meteor shower. That what im trying to do without losing the rest of information i ahve about vaccines – Faelon Feb 07 '20 at 14:29
  • Sounds like your only option is to create a wrapper around the library and load it in a new process (like a service or something similar) and then communicate with that process. Then if there is an unrecoverable failure in the library only the external process would be affected and your primary application remains running. Of course this has downsides, its more code to maintain, more boundaries to cross for communication which also adds more overhead, and its an additional component that has to be deployed making the app more "fragile". – Igor Feb 07 '20 at 14:52
  • A wrapper process is pretty much the only way out. For good or bad, the runtime authors have gone to increasingly more thorough lengths to make it impossible for you to handle such exceptions - there is a clear pattern from .NET 1.0 (where you could catch anything) to the present where the runtime becomes ever more picky about what it will allow you to attempt to continue from (to the point where at present, an infinite recursion causing a `StackOverflowException` will kill your process, even if this particular scenario is very much recoverable in practice). – Jeroen Mostert Feb 07 '20 at 14:59
  • Note that even in supposedly "unconstrained" unmanaged languages like C++, trying to catch something as dire as a segfault is pretty much not possible without [undefined behavior](https://stackoverflow.com/a/53436496/4137916). Even there the best you could strive for is to log the exception with as much context as possible, and then call it a day. Attempting to continue can have the extremely undesirable result that your application will start malfunctioning in ways that *aren't* signaled with exceptions. Unfortunately in-process logging of such things is not available to managed code. – Jeroen Mostert Feb 07 '20 at 15:13
  • @PanagiotisKanavos "tried" is a key word. Because the attempt to write to an invalid memory location failed, the memory state should still be exactly as it was. – Sparr Apr 25 '23 at 23:56
  • @Sparr what do you mean by `memory state`? In a buffer overflow, the application may be trying to write 10KB when only 8KB were owned by the application, and only 2KB of those were actually part of the buffer. The 8KB would get overwritten before the OS faulted. You'd need a language with a [transactional memory model](https://en.wikipedia.org/wiki/Software_transactional_memory) to get all-or-nothing semantics. Few if any languages do this. There was an [experimental design for .NET](https://www.microsoft.com/en-us/download/details.aspx?id=52594) back in 2005 but was abandoned. – Panagiotis Kanavos Apr 26 '23 at 10:10
  • While it might not be true for every example, I'm pretty sure that attempting to write to address zero will segfault before writing anything. – Sparr May 03 '23 at 17:54

0 Answers0