Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++/CLI: Catching all (.NET/Win32/CRT) exceptions

I know this is frowned upon, but I'm out of options here. I'm developing a C++/CLI app that has a bug that I'm unable to track down - mainly because it's bypassing my current crash handler:

AppDomain::CurrentDomain->UnhandledException += gcnew UnhandledExceptionEventHandler(&LogAndExit);
Application::ThreadException += gcnew ThreadExceptionEventHandler(&LogAndExit);
Application::SetUnhandledExceptionMode(UnhandledExceptionMode::CatchException);
try 
{ 
    Application::Run(gcnew frmMain()); 
} 
catch (Exception^ ex) 
{ 
    LogAndExit(ex); 
} 
catch (...) 
{ 
    LogAndExit(); 
}

Standard .NET crash handling, I suppose. MSDN reports that some of the CRT exceptions will blow over the managed stack and silently abort the app.

I've been reading up on _set_invalid_parameter_handler, but even though I'm getting a LNK2001 error, it seems it can't be used with /clr:pure. Am I right, or am I just PEBKACing it up and missing a lib file?

like image 799
hb. Avatar asked Jul 08 '11 17:07

hb.


2 Answers

Can you run in /clr mode? If you can then try this:

#include <exception>

Then:

try
{
    try
    {
        Application::Run(gcnew frmMain()); 
    }
    catch(const exception& ex)
    {
        throw gcnew System::Exception(gcnew System::String(ex.what()));
    }
} 
catch (Exception^ ex) 
{ 
    LogAndExit(ex); 
} 
catch (...) 
{ 
    LogAndExit(); 
}

Another thing to note: if your application is multi-threaded, then you will only catch an exception from the thread in which frmMain() is running. So doing a catch-all on your entire application is impossible in that case!

like image 109
Kiril Avatar answered Sep 29 '22 13:09

Kiril


First of all, this doesn't work for forms.

In applications that use Windows Forms, unhandled exceptions in the main application thread cause the Application.ThreadException event to be raised. If this event is handled, the default behavior is that the unhandled exception does not terminate the application, although the application is left in an unknown state. In that case, the UnhandledException event is not raised. This behavior can be changed by using the application configuration file, or by using the Application.SetUnhandledExceptionMode method to change the mode to UnhandledExceptionMode.ThrowException before the ThreadException event handler is hooked up. This applies only to the main application thread. The UnhandledException event is raised for unhandled exceptions thrown in other threads.

Second, there might be an unmanaged exception (which is not of type System::Exception).

try { Application::Run(gcnew frmMain()); } 
catch (Exception^ ex) { LogAndExit(ex); }
catch (...) { LogAndExit(new Exception("Some Unmanage exception"));

msdn- How to catch exceptions in Visual C++

like image 33
Yochai Timmer Avatar answered Sep 29 '22 12:09

Yochai Timmer