I've been using Google Chrome for a while now and I noticed that it features very elegant crash control.
Just before crashing, google chrome gave a message saying "Woah! Google Chrome has crashed. Restart now?". And right after, I'd get a standard Windows XP "This program has encountered a problem and needs to close." with the "Debug", "Don't send" and "Send Error Report" buttons.
My question is how can you program your compiled application to detect a crash condition in advance? If you have knowledge of how to do it in any programming language / platform would be great.
Thanks
Google Chrome uses a technique (often called process separation) where the 'host' UI manages child processes that it can detect becoming unresponsive (or worse, throwing an error and closing). It starts a new process for each tab you open.
Here's an article describing this in a bit more detail.
Using .net's Process class, you can start processes, check if they're responsive and even kill them.
If you want to embed a process' window within your own, you can use platform functions such as SetParent to move one window within another. I'm afraid I'm not aware of a managed alternative to SetParent when working with Forms, but I suspect one exists so it's worth searching for that before using SetParent.
If the host process crashes, simply using something like AppDomain.CurrentDomain.UnhandledException will allow you to receive a notification that a top-level exception has occurred, but by this stage you're unlikely to be able to predict the state of objects within your app and restarting (along with some logging and a notification to the user) is probably your only sensible option.
Handling top-level exceptions is covered in detail here.
I don't know Google's code so I am speculating. Google Chrome probably isn't predicting that it will crash, but detecting that it has crashed.
In Windows you can do this by providing a handler for all unhandled exceptions. In this handler you might do things such as restart the application, create a minidump file, etc.
Take a look at SetUnhandledExceptionFilter Function for one method.
In .NET, you can hook up to the System.AppDomain.CurrentDomain.UnhandledException event. Your code would look something like this:
using System;
using System.Windows.Forms;
public class Program
{
public static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += MyUnhandledExceptionHandler;
// start rest of application
}
private static void MyUnhandledExceptionHandler(object sender, EventArgs args)
{
MessageBox.Show("Your app is crashing. Watch out!");
}
}
There is a restart API. Daniel Moth has blogged about it here and here. Please note I am not saying this is the way Google Chrome works, just that it is something you might want to look into.
I believe you could also load bits of the app in seperate App Domains. I believe this is what the .NET 3.5 Addin framework uses, though I can't say I've ever used it (merely read about it). Looks like Daniel has blogged about this too.
Related
I'm writing my first Windows Store app (windows 8.1) and I notice that when I run it in debug mode, and I close the app (by clicking the x in the top right, or by dragging from the top of the screen to the bottom), it is still running in Visual Studio. My first question is, is this a problem? It seems like it's a problem.
I started from a template, I'm not doing anything with threads, and there is only one page (MainPage.xaml) at the moment. I have looked at questions which seem similar, in particular this one:
WPF App Doesn't Shut Down When Closing Main Window
but I am unable to get their suggestions to work.
When I add ShutdownMode="OnExplicitShutdown" to my app.xaml, I get these errors in my Error List:
The member "ShutdownMode" is not recognized or is not accessible.
The property 'ShutdownMode' was not found in type 'Application'.
Also I notice that there is no StartupUri specified, nor can I add one (same errors as above.)
The other suggestion was to override OnClosed in MainWindow.xaml.cs and close the application there. I have no MainWindow.xaml.cs; I have MainPage.xaml.cs instead, and it does not have an OnClosed.
The Application class is of type Windows.UI.Xaml.Application.
If I pause VS after closing the app, it takes me to this (generated) code:
#if !DISABLE_XAML_GENERATED_MAIN
public static class Program
{
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
static void Main(string[] args)
{
global::Windows.UI.Xaml.Application.Start((p) => new App()); //<==here
}
}
#endif
Can anyone tell me what's going on?
This is entirely normal, the debugger tells you what is really going on. All Modern UI apps work this way. Just check it out with Task Manager, Details tab. Observe how dismissing the window doesn't terminate the process, it just suspends it.
You don't just have a modern UI, you have modern operating system behavior as well. A user doesn't have enough information available to judge if terminating a process is actually useful. If the machine has plenty of resources then there isn't any point. Better to keep the process running so that when the user starts it again, it instantly wakes up. Which is nice, users like that.
Conversely, if the OS requires resources for another process and not enough are available than it will automatically terminate a process without the user's assistance. The life-cycle for Modern UI apps supports this. Nothing particularly revolutionary btw, mobile operating systems like Android do this as well. Also the way I use my desktop apps these days, I just leave them running. Until I run out of taskbar space, cleanup then. Annoying :)
Truly stopping the process is easy, just click the Red Button on the VS toolbar.
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.
}
}
}
Is there a way to monitor processes starting in the system before they start?
Example:
On programs like ZoneAlarm or Antivirus programs, when you run a program it asks you if you allow running this program or not before it runs...
There's a few ways to do this. If you only need to track process creation coming from a specific program (or a few programs), the EasyHook/Detours method mentioned here will work pretty well, but you effectively need to install a hook on CreateProcess into each program, so it's not a great solution if you want to track all process creation in the system.
There's a specific API for this in NT-based Windows variants (NT/2000/XP/Vista) called PsSetCreateProcessNotifyRoutine(). Unfortunately, you can only call this function from ring0, so it needs to be done in a driver. There's a handy explanation (and code) in this CodeProject article: http://www.codeproject.com/KB/threads/procmon.aspx.
AFAIK, this is just a notification, and does not by itself allow you to tell the system whether the process should be created or not. However, if you needed to do this, you could pause the process (e.g. by attaching to it as a debugger) while your code decides whether to kill it or not.
You should check out the easyhook-continuing-detours project, which is a .NET port of the Microsoft Detours project. It will allow you to hook unmanaged APIs (such as CreateProcess). Check out code examples for a simple FileMon-like program here.
You can find out when processes start via using a real-time ETW consumer - however, to be able to take some action that could possibly cancel the process from starting, you'll have to do something shady / undocumented, like hooking CreateProcess, or using a kernel filter driver to block reads to the EXE.
Just use process creation notifications .
It's included in Windows.
You don't need to hook anything.
I'm developing a commercial Windows 7 desktop application (somewhat shrink wrap, but not quite). The application has both Windows Service and a WPF User Interface components. In the event that our application fails at a customer site we want to be able to capture information about the runtime environmnent, including a crash dump of our processes to a dump location. That information could then be forwared to our support personnel upon request for further investigation. We also want to turn off any Windows Error Reporting and Send To Microsoft dialogs that might popup as a result of the failure.
The important thing is that we only want this to affect our application processes. We don't want to affect some global setting that will change the way all other applications on the customers desktop report fatal errors.
I'm looking for some suggestions and best practices for doing this sort of thing in a shrink wrap application.
The best way I know how to do this is by subscribing to the AppDomain.CurrentDomain.UnhandledException event. There you will be able to use the Win32 API function MiniDumpWriteDump to create your own minidump file. Check out this blog post to see a good example. Also, there is the ClrDump library.
Before you exit from your UnhandledException handler, call Environment.Exit() and you shouldn't see any more Windows error dialogs.
I have not actually used these minidump libraries myself yet, but I will soon. Hopefully this answer will at least give you a few keywords that you can plug into Google.
I am writing a windows form application in .net using C#.
I am running into a problem that if my program is running when the computer goes into the sleep and/or hibernate state (I am not sure at this time which one, or if both, cause the problem), when the machine wakes up again the program just hangs. The only way to exit out of it is to kill the process from the task manager.
This is, for obvious reasons, not the way I want the program to function. Even if I just shut the program down when it goes into these states, that would be fine, but I am not quite sure how to do this or if there is a more graceful way altogether of handling this.
You need:
using Microsoft.Win32;
And this is the code:
void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
if(e.Mode == PowerModes.Suspend)
{
this.GracefullyHandleSleep();
}
}
This is what I went with.
Handling those events may be a work-around. But before applying this kind of work-around I'd try to figure out what the application was doing when the OS went into hibernate.
Occurs hanging although application was just idle?
Is the application doing some kind of low-level work (communication with device drivers or external hardware) that should not be interrupted?
Does the application use some kind of network connection?
This article covers listening for those events. You'll have to do something like override WndProc and listen for PBT_APMSUSPEND events.