How do I suspend all threads after my program crashes? - c#

I have an unhandled exception handler. It shows a nice GUI and allows users to send an error report. Users can even leave their name and phone number and things, and our support department calls them back. Works well, looks good, makes customers less angry. In theory, anyway.
The problem is that my application uses background threads, and the threads don't seem to care if an exception was thrown on, say, the GUI thread (which makes sense), and just continue their work. That eventually results in a WER dialog poping up if the user lets my custom exception handler window stay open long enough, making it look like the error handler itself crashed.
I don't have access to the thread objects in the scope of the exception handler, so I can't suspend them. Making the thread objects globally accessible is not a solution either. My workaround for now is to use something like Globals.Crashed = true; in my exception handler, and to have my thread methods check that property at every loop iteration. Not perfect, but it minimizes the damage.
Does anyone know a less-hacky method? Is my approach wrong? Do I have to do it like WER does and launch an external program that suspends the main program and shows the error UI?

If you have an unhandled, unknown exception, you can assume that ANYTHING has happend and that your program might fail to do even the most simple thing. Consider e.g. the case that it has consumed all available memory - then you won't be able to send the error report either, because it probably requires memory to be allocated.
A good approach is to write a separate small application that just does the error reporting. That application can pick up the details to report from a file. That way your unknown exception handler would:
Dump the info to a file in the temp directory.
Start the error reporting app with the file name as an argument.
Terminate the failing process, before it does something stupid.
The temp file should be removed by the error reporting app.

You could track all your threads in a global Collection object, so that when your handler executes, it could simply iterate through the collection object and abort the threads there.

Take a look at the code in this question, Suspend Process in C#, you'll need to tweak it so as to not suspend your GUI thread and any that aren't background ones you've started, but it should do the trick.
The better option, however, is to try and launch your error report GUI as a separate process, passing any required information to it, and then kill the original process from your unhandled exception handler, rather than allowing anything to run in a potentially corrupt state.

Related

JetBrain Rider: viewing List<> during debugging

I'm trying to view the content of a List<> during debugging. Unfortunately I can't see them, cause I get the following message within the variables window:
corvalue.GetExactTypeSafe(out type). The object is in a
zombie state. (Exception of HRESULT: 0x8013134F). The error code is
CORDBG_E_OBJECT_NEUTERED, or 0x8013134F.
Does someone know what this means and how I can view the List<>? It's no compilation error cause I can normally run through the code.
sounds like you are using multi-threading. lets start with zombie state.
zombie state is when a thread that was previously started (by another thread) finally finished it work. and additionally this thread didn't return the control to the calling thread. hence, this thread is currently ain't doing anything although it wasn't terminated.This is the source of the name, the thread ain't alive and ain't dead. For more information you can check this post.
You need to simply free up all allocated resources by restarting your program or kill the parent thread\process.
If you keep having the issue in the "interesting code" You can also try to run your program with out multi threading to ensure you wouldn't encounter any zombies along the way. (:

Is it possible for a thread to just die without throwing an exception?

I have a situation on a production machine where a thread in my Windows Service appears simply to die, without throwing an exception. To date my logging hasn't been verbose enough to pinpoint the exact line of code where it is dying; I've deployed a new version with more verbose logging for this purpose. But until I get a smoking gun, my suspicion falls on the line of code where I create a new DB context.
The error is not predictable, except that it tends to happen during periods of high activity, and is often correlated with other threads throwing DB timeout exceptions (hence my suspicion above). Exceptions I can handle. Dead threads I can't.
Any ideas why a thread might die silently, or otherwise simply freeze? Or what to do about it?
EDIT: To be clear, the code is surrounded by a try-catch block, and the catch does some logging (using log4net). So does the "finally". I know it's working because other threads have left logs when they threw exceptions. All that I see in my log is that thread x hits a certain debug point, then is never seen or heard from again, and the work it was supposed to do remains not done.
No, not really (but kind of). Threads don't die, they finish. A thread can finish successfully or by failure--if a thread fails then its exception is stored until it is handled. Depending on how you instantiate the thread it's possible that you "fire and forget", meaning that if an exception occurs you have no code to handle and retrieve it. This is doubly bad, as it results in unreleased resources (they're waiting for you to retrieve and handle the exception).
However, you haven't provided any details of what you've diagnosed. What threading approach/framework are you using (there's quite a few)? Are you watching the processes threads and seeing it suddenly disappear? Are you taking heap snapshots, or attaching to the running process after it appears to have died?
If you have access to the system i would debug it with: Visual Studio 2013 Remote Debugger. This is often a good choice if you can't reproduce the error in your development environment.
Threads do not silently freeze or crash, check whether you have some empty catch blocks in your code or it runs into an infinite loop (or very long timeout at any point).
Maybe you have some code for us.

Get the owner of thread that is executing

when I run the project I receive the famous "Calling thread cannot access..." exception. Now, first I would like to see why is this happening, since my code should not be creating this new thread at this stage, so I would like to know who created this thread.
When exception occurs, StackTrace reports that the method was called from external code (only two items in StackTrace).
Threads window reports its Priority only (no explanation in Name).
How can I get more information about the current thread running? Like which library created it? Is it external code or mine?
Thread.CurrentThread should tell you all what you need to know about a managed thread. If "Threads window" doesn't shows name means, there is no name specified.
Also there is no way you could find which library created the thread. No such information stored anywhere.

Terminate a Thread running code I can't control

I am doing a project where I am loading several assemblies during runtime, for each of those assemblies I use reflection to find some specific classes, instantiate them and calling their methods. All this is working fine, but for some of the calls the process encounters a stack overflow which terminates my entire program. I don't have any control over the source code of the assemblies I am loading so I cant change the code I'm executing.
What I have tried to solve the problem:
I assign a thread to do the invocation of the methods and tried to
abort the thread after a timeintervall(I know that this is bad
practice but I cant change the code to terminate friendly). This
however doesn't work, I think the thread is to busy "stackoverflowing"
to handle the Abort-call.
Ive tried reducing the actual memory the thread has access to, this is not even a solution because you cant catch the stackoverflow-exception so my program terminates anyway (just quicker)
Questions:
Can a thread be to busy to be aborted? Is there some way to abort a thread that is having this behaviour?
How can we call code (that we don't have any control over) in a good way?
Thanks in advance!
The recommended procedure in case of "opaque code" is to actually fork a new process and start it. That way you gain two benefits:
If it fails by itself, it's isolated and won't take your main application down as well.
You can safely kill it and it won't cause as much trouble as an aborted thread.

How to recover gracefully from TargetInvocationException in multi thread?

I got TargetInvocationException while doing long process in another thread caused by a windows control on UI thread (Progress Bar). This exception leads my app to crash (goes to main method in debugging) and could not be caught by try catch.
I figured out what made this exception, and fix it (that was trying to assign “Value” property by a value that exceeds the maximum). But it made me wondering how I can catch exception like this (in production code) so I have an option to recover my application instead of terminating the application.
Chances are you aren't going to be able to recover very much. In terms of your operation, the state of a good number of stack frames (and objects referenced from those stack frames) is probably invalid because of the error.
Because of that, at best you can recover at a very high level and try the operation again.
If the resources you are accessing are able to be contained in a transaction, then I would suggest doing that, so that you don't have to worry about inconsistencies in persisted data.
Also, you might want to check out this thread on SO:
Best Practice for Exception Handling in a Windows Forms Application?
As well as the Exception Handling Application block from Microsoft:
http://msdn.microsoft.com/en-us/library/cc309505.aspx
You can 'handle' exceptions (really, you're just receiving notification of them) on the GUI thread via the static event Application.UnhandledException.
When you attach a handler to this event, it will be invoked for all unhandled exceptions on the WinForms UI (message pump) thread. The fact that you have this handler attached means that the Application won't exit. Without it, WinForms shuts down your application.
Catch the exception and find a mechanism to pass it back to the main or calling code.
Not sure what version of .net you are using if its 3.0+ you can do something along these lines.
private void UpdateValue(int newValue)
{
Action myAction = () => progressBar.Value = newValue;
if (progressBar.InvokeRequired)
progressBar.Invoke(myAction);
else
myAction();
}
Call this method with the new value for the progress bar it will check if the call needs marshalling and make the appropriate call. Be careful InvokeRequired is relatively expensive, so use it only where needed. You could make this into an extension method to make generic use of this pattern for other controls if needed.
Hope this helps.

Categories