Handle unhandled exception from c++ dll in WPF - c#

My WPF app uses external DLL's method (c++, nothing with UI, just logic) like this:
[DllImport("myExternDll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern int externalMethod(string str);
int SomeWPFMethod()
{
int res;
try
{
res = externalMethod(str);
}
catch(Exception e)
{
LogError(e)
return -1;
}
return res;
}
Note, that SomeWPFMethod called in separate from UI thread (if this matter).
When there is something wrong inside dll I've got
An unhandled exception of type 'System.AccessViolationException'
occurred
exception.
A have unhanded exception method set for app, but this does nothing:
Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
e.Handled = false;
return;
}
ShowUnhandledException(e);
}
Is there possible somehow to handle the exception to prevent application from crash?
If extern method fails, I don't want to do anything, but app should still work. Now it's crashed.

Since SomeWPFMethod is called in a thread separate from the UI thread,
Application.Current.DispatcherUnhandledException
will not be able to catch this exception since it catches unhandled exceptions only from the main UI thread created by WPF.
Seems you need to use
AppDomain.CurrentDomain.UnhandledException
It catches unhandled exceptions generated from all threads running under the context of a specific application domain.
You can refer to the following articles that cover proper way to handle unhandled exceptions in WPF at great depth -
https://dzone.com/articles/order-chaos-handling-unhandled
https://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
Hope this solves your problem.

Related

Global exception handler with UnhandledExceptionEventArgs not working

After reading this MSDN page, I've created a global exception handler in my .net class library, for logging purposes, which looks like this:
static void OnException(object sender, UnhandledExceptionEventArgs args)
{
Exception ex = (Exception)args.ExceptionObject;
Logging.LogException(ex);
}
But then if I throw new UnauthorizedAccessException() or throw new Exception() from a method, this does not catch it at all.
The MSDN page says:
UnhandledExceptionEventArgs provides access to the exception object
and a flag indicating whether the common language runtime is
terminating. The UnhandledExceptionEventArgs is one of the parameters
passed into UnhandledExceptionEventHandler for the
AppDomain.UnhandledException event
I believe what I'm doing falls under the AppDomain (and not ThreadException)? What am I doing wrong here?
PS. I'm trying to avoid a try-catch block, since apparently it's bad practice. This class library is called from a windows service which runs periodically so I'd rather not let it 'crash' to avoid memory leaks due to unforeseen exceptions and would prefer to monitor the event logs regularly.
You will need to install the exception handler in the current app domain in order for it to fire:
AppDomain.CurrentDomain.UnhandledException += OnException;
Otherwise its just a method declaration that will never be called.
You mention that you are trying to avoid a try catch, but inside your handler, that wouldn't be a bad idea:
static void OnException(object sender, UnhandledExceptionEventArgs args)
{
try
{
Exception ex = (Exception)args.ExceptionObject;
Logging.LogException(ex);
}
catch
{
// do nothing to silently swallow error, or try something else...
}
}
...Because you don't want to explode in your error handler. Either swallow if stability is of primary importance, or try a secondary (more basic) logging method to insure that no exception falls through the cracks.
Normally, swallowing an exception silently is a poor practice, but this is inside an error handling block where failure means crashing an app.

Get more error information from unhandled error

I am using C# in a desktop application.
I am calling a DLL written in C that I do not have the source code for.
Whenever I call this DLL I get an untrapped error which I trap in an UnhandledException event/delegate.
object reference not set to an instance of an object
But the stack trace is empty.
When I Googled this the info back was that the error was being hanlded eleswhere and then rethrown. But this can only be in the DLL I do not have the source code for.
So, is there anyway I can get more info about this error?
This is my code...
in program.cs...
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
Exception _ex = (Exception)e.ExceptionObject;
//the stact trace property is empty here..
}
finally
{
Application.Exit();
}
}
My DLL...
[DllImport("AutoSearchDevice.dll", EntryPoint = "Start", ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
public static extern int Start(int ASD_HANDLE);
An I call it like so:
public static void AutoSearchStart()
{
try
{
Start(m_pASD);
}
catch (Exception ex)
{
}
}
My recommendation would be to look at integrating ELMAH
https://code.google.com/p/elmah/
ELMAH will log exceptions in the back ground while an application runs. It is used most often for Web Sites and Services where it is more difficult to see unhandled exceptions but here is a SO article on using it with console and desktop applications.
Using ELMAH in a console application
It should be able to see able to write out all pertinent data from an exception. It is also available through a Nuget package for easy installation, there are many good articles on setting up ELMAH like this one, so try gogling if you have setup questions http://www.hanselman.com/blog/ELMAHErrorLoggingModulesAndHandlersForASPNETAndMVCToo.aspx
Word of Caution: you might not be seeing a stack trace if the dll developers we're baddies and caught an exception and threw a new one like so
try
{
//code
}
catch(Exception ex)
{
throw new Exception;
}
If they have done that, or created a new exception and just copied the message over they will have effectively swallowed the details you're looking for. And that stinks, ELMAH may still be able to snipe the exception from the dll, but i don't know that for sure. Good Luck.

How can I get WinForms to stop silently ignoring unhandled exceptions?

This is getting extremely irritating. Right now I have a winforms application, and things were not working right, but no exceptions were being thrown as far as I could tell. After stepping through almost all pieces of relevant code, it turns out that an exception was being thrown at the start of my application.
Long story short, in WinForms, being as awesome as it is, if an exception occurs the WinForms library ignores it. No "an unhandled exception has occurred" JIT message is thrown, it just stops processing the current event and goes back to the GUI.
This is causing random bugs, because code to load data isn't being called due to the exception occurring prior to this data being loaded.
To see this in action I created a brand new WinForms application, and entered the following code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string blah = null;
blah.Trim();
}
}
Press F5 and the form loads without any errors showing, even though a null reference is being thrown.
I then tried to go to my Program.cs main method and add Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); to it. Still my form loads without causing any errors to be thrown.
Even though I know that I can tell VS to break on all exceptions, I find this situation really bad. It causes really wierd issues that are hard to debug in production, and as this is an internal tool I really want to have it so it actually errors out when an exception occurs, and not silently disregards it.
Does anyone know how to do this?
Update: Just to update on things I have learned from the comments.
This does appear to be a 64-bit issue with windows, as I learned from this question which I did not see before posting. In that question it pointed to a Microsoft bug report about this, which had this to say:
Hello,
This bug was closed as "External" because this behavior results from how x64 version of Windows handle exceptions. When a user mode exception crosses a kernel transition, x64 versions of Windows do not allow the exception to propagate. Therefore attached debuggers are unaware of the fact that an exception occured resulting in the debugger failing to break on the unhandled exception.
Unfortunately where is nothing that the Visual Studo team can do to address this, it is the result of operating system design. All feedback regarding this issue should be addressed to the Windows team; however the Windows team considers this to be the "correct" operating system design, and considers the x86 behavior to be "incorrect".
Best Regards,
Visual Studio Debugger
That being said, builds not run through visual studio (or using Ctrl+F5 to run) does seem to show the JIT exception message box EXCEPT if you have the following code in your Program.cs:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
That code will cause windows to ignore the exception.
However, if you (instead) subscribe to the Application.ThreadException event, not only will your exceptions be caught, visual studio's debugger will break on unhandled exceptions!
In your Program.cs' Main function you should also ensure that you've wrapped your call to open the form in a try/catch. Additionally use the AppDomain.UnhandledException to catch exceptions. We also add Application.ThreadException too.
I believe the following will give you hooks into all the exceptions that can be thrown...
static void Main()
{
try
{
System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
System.Windows.Forms.Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(OnGuiUnhandedException);
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
var form = new MainForm();
form.ShowDialog();
}
catch (Exception e)
{
HandleUnhandledException(e);
}
finally
{
// Do stuff
}
}
private static void HandleUnhandledException(Object o)
{
// TODO: Log it!
Exception e = o as Exception;
if (e != null)
{
}
}
private static void OnUnhandledException(Object sender, UnhandledExceptionEventArgs e)
{
HandleUnhandledException(e.ExceptionObject);
}
private static void OnGuiUnhandedException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
HandleUnhandledException(e.Exception);
}
Try the following.
Handle exceptions in your main application entry point.
Also, manage unhandled thread exceptions using a ThreadExceptionEventHandler
This is the code snippet:
[STAThread]
public static void Main(string[] args)
{
try
{
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
//your program entry point
}
catch (Exception ex)
{
//manage also these exceptions
}
}
private void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
ProcessException(e.Exception);
}
An easy fix is not to run under the debugger.
The debugger is masking the exception for some reason. If you run your app normally (Ctrl+F5), you'll get the usual "Unhandled exception has occurred in your application... Continue/Quit?" dialog.
Having experienced this often and identified the issue regarding 64 bit OS and the Form.Load event, I always just make a point of doing all my start up functions in the Form.Shown event. For all practical purposes this is the same thing (aside from a few rare, exceptional circumstances), and the JIT message is produced in the Shown event.

c# debugging windows crash

I have an app, and after about 20 minutes of idle time the program just crashes. ("Windows has encountered an error and needs to close...")
I have no idea why this is happening. What is the best way to go about debugging something like this?
Generally crashes in .Net applications are caused by an unhandled exception - i.e. an exception in a thread in that application that was not caught in a try-catch block of some sort:
try
{
// Some code that may throw an exception
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
A good first place to check for information about this exception is the application event log, often however you will find that the .Net framework posts only minimal information about the crash - if this is the case then you need to catch and handle the exception yourself, recording enough information to allow you to diagnose the error.
Typically there are two way that you might do this:
1. Ensure that the code for each thread of your application is contained in a try-catch block.
This is the easiest method - unless your application has multiple user threads (you will know if it has), this simply requires that you place a try-catch block around the entry point of your application, for example in a Windows Forms application:
// Probably found somewhere in Program.cs
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
If you are working on a console application then you will need to use something other than MessageBox (see the first example).
If you spawn multiple threads then the entry point method for each thread should also catch all exceptions in a similar way.
2. Handle the UnhandledException event of the current App Domain
This event will be fired whenever any thread throws an unhandled exception in the current App Domain. Generally speaking it is best to use the first method instead, however this event is still useful in some situations.
Example:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
// The rest of your application
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine(e.ExceptionObject.ToString());
}
Of course it is worth pointing out that the error still might not be caught by either of the above two methods (which is possible if the error is caused by a native module loaded in the same process), however this should probably do the trick.
Finally - Good luck!

.Net Equivalent of set_unexpected()

Is there a .net equivalent to the C++ unexpected()/set_unexpected() functionality?
Edit: Sorry--I omitted some details previously:
Language: C# 2.0
I have some legacy apps that seem to be throwing some unhandled exception somewhere. I just want to put something in place to stop the customer's pain until I can trace the actual source of the problem. In C++, the function pointed at by set_unexpected() gets called, as far as I know, when an otherwise unhandled exception bubbles to the main routine. Hence my question about a .net equivalent functionality.
There 3 possible scenarios for handling unhandled exceptions, based on the type of the application:
For windows forms application, hook an event handler to Application.ThreadException
For commandline applications, hook an event handler to AppDomain.UnhandledException
For ASP.NET applications, in Global.asax, create:
protected void Application_Error(Object sender, EventArgs e)
DISCLAIMER: I'm not c++ developer, but from what I read, this should answer your question.
These handlers should catch most unexpected exceptions in your mixed-mode application.
private delegate long UnhandledExceptionFilter(IntPtr exception);
[DllImport("KERNEL32.DLL", SetLastError = true)]
private static extern IntPtr SetUnhandledExceptionFilter([MarshalAs(UnmanagedType.FunctionPtr)] UnhandledExceptionFilter filter);
// put these in your bootstrapper
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
Application.ThreadException += ApplicationThreadException;
SetUnhandledExceptionFilter(UnhandledExceptionFilter);
void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
...
}
void ApplicationThreadException(object sender, ThreadExceptionEventArgs e)
{
...
}
long UnhandledExceptionFilter(IntPtr exception)
{
....
}

Categories

Resources