Fault tolerant application? How can I catch elusive exceptions?

I have a program written in C # that runs on a Windows CE device (on Compact Framework). It handles minimal user actions (button clicks), uses a serial port and TCP / IP communication.

Sometimes the problem is that the software shuts down on its own. In the background, the application (or parts of the application) seems to still be working (at least in one documentary case it was) because it uses a serial port, so reloading the application does not help. I can’t reproduce the problem, because this happens in most cases when there is no user interaction, there is no communication with the serial port, and network communication is all the messages “I'm still alive”, the software just crashes, apparently without a reason. (I'm trying to do this in debug mode to know at least where the problem is in the code, if it is a software bug, but so far I'm out of luck.)

As I run out of ideas, the question arises: what kind of error or exception or OS action or hardware malfunction can cause this behavior?

The problem is observed on different devices of the same type, so this should not be a hardware error. (Or all of my equipment has the same error.) Exceptions are handled, so this should not be an exception. Unhandled exceptions are handled too, so it should not be an unhandled exception either. (I assume this is caused by a StackoverflowException because I don't know of any other exceptions that cannot be caught, but there is no recursion in the code, at least not willingly, so there shouldn't be an opportunity either.)

+9
c # windows-ce compact-framework
Jul 27 '10 at 7:34 on
source share
3 answers

Quite a few exceptions cannot be caught and that differ from the .NET version to the .NET version. And some exceptions can be caught and logged, but cannot be recovered from (memory exceptions). However, they can be debugged (they are called the first chance exceptions , the first chance is always for the debugger, the second chance for the code, thanks to JeroenH for pointing this out). Here's a post in CodeProject that explains this principle .

What you need to do is select some exceptions for the candidate in Visual Studio that you suspect might occur and attach the debugger to the running instance.

Having unmanaged resources like yours (serial port), you can have unmanaged leaks (not using IDisposable + using ) and unmanaged exceptions. These exceptions can only be caught with an empty catch (i.e., without specifying an even Exception that is not the parent of unmanaged exceptions) in the try / catch block.

PS: undefined behavior can occur when exceptions are thrown in finally blocks or in finalizers / destructors. In addition, not all exceptions propagate along the boundaries of a thread and terminate all threads.

Edit

To make things a little clear, there are a few exceptions that the CLR (and its specification) define as unattractive. In principle, these are all exceptions that cross the boundaries of flows. These asynchronous exceptions that occur during a lock will corrupt the state. The most famous are OutOfMemoryException , ThreadAbortException and StackOverflowException . When an OutOfMemoryException or StackOverflowException occurs in synchronous code, it is unlikely that you can fix the state and the CLR will terminate your application.

In addition, there are ExecutionEngineException and BadImageFormatException , which should not be executed in the code being checked and should not be caught. Exceptions, such as TypeLoadException and MissingMemberException , can sometimes be caught and sometimes not (if there is no related assembly, they will be difficult to catch, but you shouldn't, but if you use reflection, you have to catch these).

In short: exceptions must be caught in the thread in which they occur. You cannot catch exceptions if they occur in another thread because they are not propagated (with the exception of ThreadAbortException ). Your application remains alive after the exception (at least you think), so it’s logical to assume that the exception does not occur in the thread where you are trying to catch it. Using the Debug> Exceptions window, you can select any exception and break the code when they occur.

Exception note

Added note on managed and unmanaged exceptions. You cannot catch an unmanaged exception using catch (Exception e) , because an unmanaged exception is not inherited from Exception . Instead, use an empty catch that will catch any unmanaged exception for you. Wrap this around your applications and stream entry point methods, and you should catch most of the perceptible exceptions.

+10
Jul 27 '10 at 7:44
source share

You probably have your own exception or access violation (which usually manifests itself as an exception from the first chance). No handling of managed exceptions can block one of them - the key should not cause an exception in the first place.

Do you p / make or make unsafe calls? If you call the API and call something like a buffer or stack overflow, you will see this behavior (although often you get a message about the OS dialog.

Tracking them is often tough. This is a CE device - does it have a debug port (usually a serial port)? It is very likely that the exception will throw a message there, so if you have access to one, this is a good starting point. If you have KITL, starting the OS in debug during application startup can also trap what happens.

+3
Jul 27 '10 at 14:29
source share

If you start secondary threads using the Thread class and do not indicate that they are background threads, they will support your process until they exit, even if the main thread is completed (i.e. the main form is closed and the Main method returned .)

If you had a StackOverflowException, your process would have been completely destroyed by Windows, so it is not.

+2
Jul 27 '10 at 7:47 a.m.
source share



All Articles