On Android, I'm running an application using the NDK that runs a series of tests in C++. If ever one of the tests fails, which most likely means a crash, I'd like the application to relaunch itself and start at the next test.
I wish I could use exceptions but the NDK doesn't support them.
Is this possible?
Why does your application have to crash? Why not catch any exception being thrown? Even the compiler doesn't enforce you to add a try..catch block, RuntimeExceptions might still be thrown.
You can also use Thread.setDefaultUncaughtExceptionHandler. Note that this must be called per thread.
If, for some reason, the solutions above are not suitable for you, you could create a background service that acts as a watchdog timer.
EDIT: Check this link: for a custom version of the NDK that supports C++ exceptions. I found it in this thread.
Related
I'm working on a suite of plugins for a certain host application, targeting both Windows and Mac (OSX+). The plugins are written in C++. I would like to add crash & exception report handling to them in case the plugin goes rogue. This in order to not bring the whole host app down in case the plugin misbehaves, but get some feedback instead and just skip that one plugin call (and making follow-up plugin calls a sort of no-op). Think logging some state and slapping an error code + text on it. From then on the plugin switches into an error state where requesting details returns this state.
This is a big legacy code base which has been improved greatly over time, but there are still some rough edges here and there, so answers like "just don't crash" is not what I'm looking for :) It also doesn't help I'm much more of a Windows developer than a macOS developer, so I might have overlooked something completely obvious.
I've covered unhandled C++ exceptions in a cross-platform way by wrapping each host->plugin callback in a big C++ try/catch block right at the plugin entry points.
I'm also handling crashes, div-by-zero, access violations etc. for Windows at that same spot by using __try/__except and registering a SEH handler.
Now I want to do the latter as well for Mac. But here I'm struggling with finding out what my options are, if any.
I looked into signal handlers, but what I glean from that is that they are process-wide. I.e.: not plugin-friendly, especially when multiple of these plugins can be used by the host concurrently (who will catch and thus handle the signals first?). And the host app already has it's own crash handler, possibly using a signal handler, so installing our own would make it a fight over who's in charge I think? Plus that my reporting options are extremely limited in such handlers; if possible I'd like to have a bit more freedom here (like using std::strings with the new/delete they imply).
Then there's also Mach exception handling. But I totally fail to get informative results when googling this in combination with 'plugin'...
Does anyone have any advice on what route to go, or which option is better in my situation?
The only options on macOS are signal handlers and Mach exception handlers.
Both of these mechanisms are process-wide, so would report problems wherever they occurred.
If a new signal handler is installed, the old one will not be run. The sigaction() API does return the previously installed one, so it's possible to have it run as well as your new one. Then again another signal handler might get installed and replace yours.
There's a very useful post here that goes into detail about implementing a signal handler - https://developer.apple.com/forums/thread/113742
The situation with Mach exception handlers is pretty much the same, calling task_set_exception_ports() will override the previously set handlers, so these have to be restored once your new handler has run if you want to propagate the exception. One big advantage of Mach exception handlers is that they can be run in a separate process, in which you're free to use std::strings etc. at the expense of it being more difficult to examine the crashed process's state.
There is little documentation around Mach exception handling, the best references are the various open-source crash reporting frameworks.
Overall it's difficult to properly implement crash detection, and I'd advise against doing it in a plugin. It's a LOT more complicated than SEH.
I am not a Windows developer(!) in any way, but I currently work on a Windows only project.
The project is very old and a lot of people have been working on it. It looks like the original development team took the big old book of anti-patterns and applied all of them wherever they saw it possible. Fixing bugs is hard. Much much harder than it should be. There are plenty of crashes and just general slowing down of stuff. When stuff crash, some resources still has to be cleaned up. In particular, the program may reserve some screen space for a tool bar -- not cleaning up that space means a part of the screen won't be available to other programmes.
I've tried several approaches, based on various other peoples attempts:
using c-style signals (<csignal> -- setting signal handlers on all defined signals)
using std::set_terminate
using DllMain to set signals/terminate
using __try/__except
using system to invoke a copy of the program and communicating resources (a HWND) through the registry. This one was a long shot, but I had to try it.
None of them worked as hoped -- except the system bit, I couldn't get any of the error handling code to run at all.
We're using Visual Studio 2012, so we have C++(ish)11(ish) available.
As the comments note, drop C++. You can't trust the C++ library anymore once your program has corrupted memory all over the place.
The first step is to figure out the event you're reacting to. "SegFault" is POSIX. Windows has Access Violations (the famous C0000005). This might also be why you were misled by signal. It's a bit of POSIX that ended up in C. Windows simply does not use signal.
The next step is how you react to them. My preference is a Vectored Exception Handler. Structured Exception Handling assumes the stack is somewhat sane, and that too is a guess. A vectored Exception Handler in effect is a hard jump. We're not going to return, just doing cleanup before calling TerminateProcess. Same pattern again: ExitProcess is what you would use if the state of your program could be trusted, but we don't.
In your Vectored Exception Handler, you'll query the OS about the existence of that toolbar. Don't believe your own program: you can't trust it, and besides, if the OS doesn't think there's a toolbar, then there isn't one. Use the handle returned by the OS, and destroy that toolbar. Then commit suicide by TerminateProcess
I have a DLL that's being injected into very old, buggy and now unsupported by it's developer application. Sometimes that application crashes, and I need some way to catch literally all unhandled exceptions (from DLL) that may occur to save data and only then allow the app to crash. How can I achieve that?
For now, there is an external debugger for that purpose, but it's just too slow and also buggy to keep it that way.
You have to start a new process which hosts the DLL. If the DLL is going to crash, it's going to bring down the process, whether you like it or not. Sure, you could attempt to catch an exception or something like that, but if the exception is being thrown, that means memory is corrupted. It is better to crash catastrophically than to have the program continuing to run in an inconsistent state.
The windows shell is a program which actually does this -- it launches some plugins in a surrogate process, so that if the plugin crashes, it doesn't bring down the whole shell. You'd need to use interprocess communication to communicate between yourself and the surrogate you start.
In my C++ application i use an activeX component that runs its own thread (or several I don't know). Sometimes this components throws exceptions. I would like to catch these exceptions and do recovery instead of my entire application crashing. But since I don't have access to its source code or thread I am unsure how it would be done.
The only solution I can think of is to run it in its own process. Using something like CreateProcess and then CreateRemoteThread, unsure how it could be implemented.
Any suggestion on how to go about solving this?
If the ActiveX component is launching its own threads, then there isn't a lot that you can do. You could set a global exception handler and try to swallow exceptions, but this creates a high likelihood that your program state will become corrupted and lead to bizarre "impossible" crashes down the road.
Running the buggy component in a separate process is the most robust solution, as you'll be able to identify and recover from fatal errors without compromising your own program state.
Try setting up an exception filter with SetUnhandledExceptionFilter().
Our application is using mshtml. That dll is causing our application to exit ungracefully due to well known problems in mshtml since we don't install newer browsers on users' machines. We just use what they have already.
The SetUnhandledExceptionFilter() does not handle this, nor does a try/catch block around the calls into mshtml. The exception filter does catch other exceptions.
The exception settings are /EHa.
When I remote debug the crash I see:
unhandled exception - access violation
In mshtml but if I don't attach to the process with a debugger, the application just exits.
What do we need to do to catch the exception?
Edit:
This is an old version of IE6.
Seems to be that MSHTML functions passes necessary data to a separate thread. That separate thread processes your request and the exception takes place. That's why you cannot catch exception via try/catch block. You should check it in the debugger. If that is true the only way to catch exceptions from other threads is to set hooks for TerminateThread and TerminateProcess functions. Check out CApiHook class by Jeffrey Richter for that purpose(or other implementations). But it will make your program to be incompatible with /NXCOMPAT compiler flag.
Your second option is to install all important OS updates.
Almost there. It's not SetUnhandledExceptionFilter() but AddVectoredExceptionHandler you want. With that said, you can get the first shot at this exception.
Of course I'm wondering what you're going to do afterwards. TerminateThread is probably the only option you have, but that may very well deadlock MSHTML. So that needs killing too.