We run a C# console application that starts multiple threads to do work. The main function looks something like this:
try
{
DoWork();
}
catch (Exception err)
{
Logging.Log("Exception " + err.ToString());
}
Logging.Log("Finished");
The DoWork() function reads new jobs from a database, and spawns threads to process one work item each. Since last week, the application has started disappearing mysteriously. It disappears from the processes list and there is no entry in the event logs. The log file shows work up to a certain point: it does not log an exception, or the "Finished" line.
Any clue(s) on how a C# application can vanish like that?
EDIT: Threads are created like:
new Thread(SomeObj.StartFunc).Start();
Some of the disappearances occur when no threads are running.
P.S. We installed DebugDiag with a rule to create a crash dump whenever our program crashed. It did not create any dump files when the process disappeared.
You need to have a similar catch block at the top level of the function that every thread works. If there is an uncaught exception on a thread it will kill the application, and the catch block on the main thread is not going to help.
What's the identity that you're using to run the console application?
Also, you might want to use SetConsoleCtrlHandler to capture the console events. Look at this blog post for more details. We had a similar issue when the console application was run under a service account, and it would occasionally get terminated. I'm not sure if this is what you're running into. Let me know I can post some code.
UPDATE: It looks like your scenario resembles what we had experienced. In your console event handler, you need to check for the LogOff event and return true. Look at this KB article.
public static void inputHandler(ConsoleCtrl.ConsoleEvent consoleEvent)
{
if (ConsoleEvent == ConsoleCtrl.ConsoleEvent.CtrlLogOff)
return true;
return false;
}
It's possible that one of the threads that the DoWork method is spawning is throwing an exception. The default behavior in this case is for the process to terminate. You can stop this from happening by using the AppDomain.UnhandledException event to override the default behavior.
A console program quits when the main function exits. Since DoWork just spawns a few threads it's returning control to main right away, and since Main has nothing else to do it exits and the program ends. At this time the threads spawned by DoWork are also killed.
That it worked before means either there was something in DoWork() to wait on those threads that now returns right away (is broken) or that part still works but a thread that used to take a long time to return now aborts and returns right away.
It could perhaps be the Logging.Log function that throws your exception.
I have managed to make programs disappear without a trace in a similar fashion to you (no exception traces and no termination log messages) in the past. Almost all the time it was related to killing the stack (the name of this website always reminds me).
It is possible that you are suddenly trying to process far more data than usual, or using re-entrant routines, or being 'clever' with pointers.
DISCLAIMER: My experience was with a Win32 C++ application, not C#.
It could be a memory leak. If your application takes too much memory, Windows will kill it. You can check how much memory you are using: if it grows over time, you may have a memory leak.
Another possibility is that somewhere, you have code calling Environment.Exit(). Try a full text search through your code to double-check. You never know!
Be careful; there are some exceptions that cannot be caught: OutOfMemoryException and StackOverflowException.
Therefore your program will die terribly, but silently.
Related
I am developing a .net cf application for a windows mobile device - the Motorola ES400.
The application maintains a log file which logs all handled exceptions and the unhandled global exception which was registered in global scope of the application in the Main method.
For some reason, while I was running the application on the phone, the application just froze - which means that I was not able to click on any buttons on the application or perform any other actions with the stylus. The application was totally unresponsive. When I went back to the phone Windows Mobile OS Start menu->Task Manager and tried to close the application, I could not. The task manager would not close the application. When I checked the logs, I could not see any unhandled exception logged through the registeres unhandled global exception routine.
I don't understand what might be the problem here.
Does anyone have any idea on what might have happened based on your experience with .NET CF? Anywhere I could start looking or analyzing?
Thanks in advance for any help.
Subbu
There can be many reasons. In my experience, I suppose there is some infinite looping or call to some locked resource is happening. In such scenarios, try using CLR Profiler for .NET CF. CLR Profiler can show you what is going wrong and where.
You can get it from here: http://www.microsoft.com/en-us/download/details.aspx?id=13442
And about how to use it, there is series of blog posts, visit: http://blogs.msdn.com/b/stevenpr/archive/2008/05/08/the-clr-profiler-for-the-net-compact-framework-series-index.aspx
I hope it helps.
If you get a hard fault (OS-level error like memeory access violation) then I've seen the system freeze while the Dr Watson logs are getting created.
On the ES400 I don't recall if there is a control panel applet to confugure the error reporting feature or not, but check there.
If it was creating such a log, bu default I think it goes in a subfolder under \windows. But the whole process if configurable via the registry so you might want to look there.
See here for the topic in general:
http://msdn.microsoft.com/en-us/library/ee481217(v=winembedded.60).aspx
And here specifically for the registry settings:
http://msdn.microsoft.com/en-us/library/ee480226(v=winembedded.60).aspx
I had some problems similar to this a while ago. I was was using a barcode scanner driver that created a separate thread and looped until a barcode was scanned. When I tried to exit the application it would wait for the thread to stop, causing the application to freeze until a barcode was scanned. Task manager could not end the application either.
I believe if you have a foreground thread (Thread.IsBackground = false) this will prevent the process from terminating until it has ended - http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx
Therefore your problem may be from a secondary thread that you have started up. If you are waiting for a thread, through a lock or something like that, and that thread is in an infinite loop, then this could be the cause of your problem. My most common cause for an accedental infinite loop is having a property getter referencing the property instead of the backing variable.
I hope this is of some help.
If you simply want to catch and log this error, then put a try...catch around your code in the main function of your program.
In C#, this would be simply editing Program.cs from something like this:
static void Main() {
Application.Run(new Form1());
}
To something like this:
private static Form1 m_form;
static void Main() {
try {
m_form = new Form1();
Application.Run(m_form);
} catch (Exception err) {
// log error
if ((m_form != null) && !m_form.IsDisposed) {
// you might want to save data on your form before it goes Bye-Bye.
}
}
}
I know this won't work in all scenarios, but please keep in mind the following 3 scenarios:
An IIS reset - if the code is running inside IIS
A Server restart or shut down
User closes the app (if its a Windows form or Console App).
Lets say I have a code block that runs a loop. Is there a way to ensure at least that the current loop item gets processed before the app shuts down.
Like this...
Loop runs: 100 items, app gets shutdown (for reasons above), app is busy with item in loop 53 for example. It first finishes all code for that item between the foreach... and then allows the app to gracefully shutdown.
Is this type of thing possible?
Nothing I would do but If it is ok to abuse the system you might be able to use the CriticalFinalizerObject
It is guaranteed to execute
even in situations where the CLR forcibly unloads an application domain or aborts a thread
I really don't think so. You are stuck in front of windows. Windows take that kind of decisions for you.. IF somebody is shutting down the pc, then you are just shut down. This is the same scenario as if they where a power failure. What will you do in that case?
For a normal application: While your code is running in a foreground thread (not ThreadPool or Thread.IsBackground == true) it will not be aborted mid-execution, unless the user forcibly quits the process.
If you are running your loop in a background thread, you can try handling the exit event of the application, waiting for the loop to finish or at least reach a stable state before being aborted.
In most apps you can handle close event and not allow it but you can't do anything when user decides to kill your process. So i would say that its not possible.
How about doing this. using a try catch and finally in the static void Main
Here even if you end task the application, finally will run. not sure about power failure.
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
try
{
Application.Run(new Form1());
}
finally
{
MessageBox.Show("I run always.");
}
}
Hope it helps
I'm currently writing quite a simple app, but it makes a change to the OS which gets changed back when the program is closed.
The worry of course, is if the program crashes. I can do everything in my power to prevent it from crashing, or handling things if it does crash - but I can't stop someone from force closing the process (unless I can?)
Is there a way to catch that event and run just a very quick cleanup before the process exits?
I don't think there is anything you can do if your process gets killed - one approach would be to have your app spawn a helper process that is just there for this case. When your app terminates that process can detect that and "fix" the OS setting as desired before it shuts down itself - obviously this only would work if that other process doesn't get killed first.
You can hook UnhandledException. You can't stop the application terminating, but you can log or do some clean up. This allows you to handle the case of application crashes.
It terms of someone actually just killing the process there's nothing you can do about that.
Program defensively.
Write the original settings to a file. Delete the file when closing. When starting, check whether the file is there - if it is, your process was killed and you know what to return the settings to.
Programming 201 - the basics of transactions, applied to system settings wit hthe program runtime as transaction boundary.
If you don't mind a little interop to C or C++ code, and if you're running on Windows Vista or newer, you could make use of the Application Recovery and Restart APIs. These APIs tell Windows to intercept your process when something catastrophic happens, so that you can perhaps call a little cleanup code before Windows kills the process completely.
See http://msdn.microsoft.com/en-us/library/cc948909.aspx.
I have a pretty large project that just recently started crashing on exit. I am not the greatest C# coder but everything generally works as intended. In this case however, when I close my console application, it crashes but is not caught by the MSVC Debugger.
1) When I build it in Release and run it, it generally always crashes when I exit.
2) When I build it in Debug and run it, it seems to only crash on exit every 1 out of 3-5 times.
I did manage to get the error though when it didn't exit properly, but unfortunately the Exit Code doesn't match anything I can find online.
The program '[11108] MCDaemon.vshost.exe: Managed (v4.0.30319)' has exited with code -1073741510 (0xc000013a).
From what I have read on other people's questions, this is generally caused by Unmanaged Code acting up. Is there any way I can actually find out what the issue is short of a massive amounts of debug lines?
EDIT
From an answer below, this is the code causing the Exit code, but I don't really see anything issue with it.
public static Boolean Handler(MyWin32.CtrlTypes CtrlType)
{
// A switch to handle the event type.
switch (CtrlType)
{
case MyWin32.CtrlTypes.CTRL_C_EVENT:
Program.TerminateProcess();
break;
case MyWin32.CtrlTypes.CTRL_CLOSE_EVENT:
Program.TerminateProcess();
break;
}
return true;
}
public static void TerminateProcess()
{
// Stop the Poll Timer from Running
PollTimer.Stop();
log.LogMessage("Process is being Shutdown.");
log.LogMessage("Requesting Process to Stop....");
SendProcessCmd("stop");
// Wait and make sure it has exited
Thread.Sleep(5000);
if (!myProcess.HasExited)
{
log.LogMessage("My Process did not stop on its own, forcing Process to quit.");
myProcess.Kill();
}
log.LogMessage("My Process has been Shutdown.");
}
// Wait and make sure it has exited
Thread.Sleep(5000);
That's the problem statement. You are pinvoking SetConsoleCtrlHandler() in your code to get your Handler method called. Windows requires the control handler to be responsive and not take too long to return from the callback. The timeout for the CTRL_CLOSE_EVENT is exactly 5 seconds, explaining why it sometimes works. If it takes longer then Windows pulls the plug on the process.
You'll need to implement TerminateProcess differently. Killing a process is fairly arbitrary, you ought to be better off just not doing this. Or start another guard process. I can't make that call though.
0xC000013A: The application terminated as a result of a Ctrl+C.
This is because you closed the console window, and the application wasn't expecting you to, so Windows terminated it for you.
Sorry, but I don't know how to catch a console window close event in managed code.
I have some clean up code that I would like to execute at the end of execution even if my C# application crashes (delete temp files, etc). Is that possible to do in C#?
Thanks!
It depends on what you mean by "crash".
If you want to deal with any unhandled exceptions that would otherwise bring down an application, you can attach an event handler to the AppDomain.UnhandledException event and then handle any errors in the event handler.
Additionally, in .Net 4.0 there is an AppDomain.FirstChanceException that is called before any catch blocks are executed when an exception occurs.
It is possible however that a real crash can occur (such as an exception being thrown from a finalizer) that causes a fatal application exit that cannot easily be handled, but in most cases the AppDomain.UnhandledException event will probably suffice.
If your application crashes then it isn't safe to try and execute cleanup code, you don't know what has been corrupted and until your application actually exits, files may be locked, etc.
So I would suggest that you put this cleanup code on application startup. Have your application look for temp files etc on startup before it gets around to creating it's normal temp files, if it finds them, then it can either delete them or attempt to fix/re-use them.
To facilitate this, you can have your application write a log of temp files that it creates and delete that log file when it shuts down successfully. That way when you find the log file on startup, you know that the last run was a crash and that you have to do your cleanup.
Of course, this gets more complicated if you allow several instances of your application to run at once, but the same goes for cleaning things up on crash as well.
There are several events that you can subscribe to in order to get notification of exceptions.
AppDomain.UnhandledException - Triggered by unhandled exceptions in the app domain.
Dispatcher.UnhandledException - Triggered by unhandled exceptions on a WPF dispather thread.
Application.ThreadException - Triggered by unhandled exceptions on background threads.
Also, as others have mentioned, a finally block around a single entry point will be hit for any exceptions on the main thread.
[I wouldn't recommend trying to recover your application from these handlers though. Particularly in the case of the AppDomain.UnhandledException event, your app is already on the way out, you should just let it shut down. Only use these handlers for doing last minute clean up or logging.]
If it is critical that your app cleans up, you can create a monitor app that would be what the user actually launches. It would launch your main app and then monitor its process handle. If your main app crashes, its process handle will signal and your monitor app can clean up and even restart the main app if you wish. I usually combine this with a named mutex that is used to signal back to the monitor app that the main app wishes to shut down, so that it won't restart it.
It depends on what you mean by "crash." If you mean an unhandled exception you can create a handler for Application.ThreadException. If the crash is caused outside of managed code, there's nothing you can do.
That's what try {} finally {} is for. Wrap all your code in your main method in it, that should do it.