Closed Olby2000 closed 4 years ago
You have many ways. For example, for SEH handling more like:
unmanaged C++
int filter(unsigned int code, struct _EXCEPTION_POINTERS* ptr) {
...
return EXCEPTION_EXECUTE_HANDLER;
}
...
__try
{
lib.call<int>("ThrowUnhandledCLRException");
}
__except(filter(GetExceptionCode(), GetExceptionInformation()))
{
//... yey!
}
However, I recommend wrapping for CLR side. If pointwise is difficult to cover lot of procs, well, you can also try with ~GetLastError model through wrapping all unhandled exceptions via existing domains, for example:
~
C#
AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) =>
{
SetLastError(
...
);
};
unmanaged C++
try
{
...
throwIfError();
}
catch(const UnhandledCLRException& ex)
{
...
}
Or some other pre-processing via CLR side.
etc.
My bad! It was a silly typo :) In my catch block I had this:
[DllExport(CallingConvention = CallingConvention.StdCall)]
public static uint Test()
{
try
{
MessageBox.Show("test1"); // ok
throw new Exception();
}
catch (Exception e)
{
MessageBox.Show($"{e.Message}" +
$"\n{e.InnerException.Message}"); // fails here
return 1;
}
return 0;
}
The $"\n{e.InnerException.Message}"); // fails here
line was missing a null check so it should be $"\n{e.InnerException?.Message}"); // fails here
. It was causing the NullReference error and crashing the CLR.
Thanks for the info. Here are a few clarifications, first of all I do not have access to the C++ source code - it's a third party application which can work with plugin DLLs. I wrote the DLL in C# and exported the functions using DllExport.
I would like to have a blanket approach where if I did not catch a specific error in my code I have a general catch all unhandled exceptions code which would at least log the error or show a message. I tried the following code but it does not seem to work. Could you please advise. Thanks.
[DllExport(CallingConvention = CallingConvention.StdCall)]
public static void TestFunc()
{
AppDomain.CurrentDomain.UnhandledException +=
(object sender, UnhandledExceptionEventArgs e)
=> MessageBox.Show($"UnhandledException");
Application.ThreadException +=
(object sender, ThreadExceptionEventArgs e)
=> MessageBox.Show($"ThreadException: {e?.Exception?.Message}");
MessageBox.Show("exception incoming");
throw new Exception();
// The host kills the DLL thread and the message boxes do not pop up
}
@Olby2000 Try to force route the exceptions via UnhandledExceptionMode.CatchException if you're using System.Windows.Forms.
Also note, MessageBox.Show can cause a deadlocks for different MTA/STA models. Here, I already mentioned about this:
Hi, This is not as much an issue with the dllexport it self as with how the produced libraries work within a C++ host.
Basically I wrote an extension DLL for an un-managed C++ application. Everything works great, however when an exception is thrown in the managed code (e.g. throw new Exception();) the calling thread is terminated before any of the catch block code is executed. VS debugger will say something like The thread 0x3d8 has exited with code 0 (0x0). and anything I do in the catch block like calling hosts's API commands, displaying a message box or log the error will not work because the host application has moved on and the debugger will display Exception thrown: 'System.NullReferenceException' in ManagedPlugin.dll
Any ideas how to fix this? Thank you.