How can I create a separate crash handler like GoogleCrashHandler?
This is appropriate for unmanaged code (all of Google's code is). The usual scenario is that an app opens a named pipe to talk to the crash handler and tells it to start watching the app. The crash handler then adds a named event to a list it watches. When the app crashes, an exception filter inside the app, installed with SetUnhandledExceptionFilter() will gain control. That exception filter then turns on the named event. The crash handler immediately notices and it takes a minidump of the crashed app and uploads it. And terminates the app.
A crash handler like this is necessary because a crashed app cannot be trusted to still be able to function correctly when it suffered a heart attack. Microsoft has one too, it is built in Windows. Called WER, Windows Error Reporting. That's the source of the dialog you see when a crashed app asks you if it is okay to let Microsoft know about the crash.
This is approach is unnecessary for managed apps. They almost never die from the kind of hardware exceptions (like AccessViolation) that unmanaged apps die from. Just write code for the AppDomain.UnhandledException event.
The Google Crash Handler seems to be an application that gets notified when certain things occur in other applications.
"GoogleCrashHandler.exe runs continuously on your computer if you've selected to send anonymous usage statistics and crash reports to Google for certain Google software, like Google Chrome. It helps send crash details to Google when your Google software unexpectedly shuts down. We use this data to help determine how to prevent these errors from happening in the future."
I would create a Windows service, that runs in the background, that you communicate with through named pipes, tcp, file drop, or any other good method.
The service would then send a notification to a specific server ( or list of servers),
with the information it collects. It can act as a buffer, so you dont have to send a notification to the server every time you get notified internally.
I would let the service call a web service on a server, when its ready to spill its beans.
Every application you create after that should be able to check if your "crash handler" is running and notify it whenever appropriate about errors or exceptions etc.
However since this behavior will probably trip some local firewall programs, and users might question what data is being sent and when, you will want to document this well, and be very upfront with what data you are collecting, why you are collecting it, and where it is being sent.
Related
My WPF app uses Log4Net to record messages to the event viewer. This is working great on most machines. However, there are two machines in my office where there are problems. One is a physical Windows 7 machine with 2 GB of ram, the other is a virtual machine running XP, which also has 2 GB of ram.
The problem is that even though the users are logged in using accounts with administrator rights, the system won't let them create the custom event log that I set up for my application. This is causing my program to die.
I can add error handling on all of the Log calls, but my feeling on this is I shouldn't. The messages are being logged in the catch handler for another error that already occurred. Just what am I going to do with the error information if it can't be logged?
In any event, I tried to create the custom event log on the XP virtual machine yesterday and it still wasn't created. What exactly do I need to do to get the custom event log created on these two machines?
Tony
It turns out that the problem wasn't in the logging code at all. My program uses WPF for the GUI. It's start-up sequence does the minimum amount of work on the UI Thread so it can display the UI as soon as possible.
The rest of the initialization is done on a background thread. I knew that an error was occurring, but I couldn't find the custom error log in the list of logs in the Event Viewer. It turns out that my code didn't find some data in the database that it needs and was trying to report the error. This is a 2 step process which involves first recording the error to the log and then displaying a custom MessageBox dialog. I was getting a XamlParseException when the program was trying to display this dialog.
To make a long story short, the problem that was crashing the program was the XamlParseException. This was thrown because I was calling the custom MessageBox's Show method on the background thread, not on the UI thread. Because I couldn't find the custom event source in the event viewer, I couldn't find the error, so I assumed that the error was a permisions issue.
By the way, I did try to create the event log manually at one point, and yesterday I checked the registry and did find the entry for the custom event source.
There is one other machine here that is having the same problem. I'm sure it's the same exact issue. I'm adding logic to the error handling to make sure that the custom MessageBox is always called on the UI Thread so the program won't bomb like that if the same issue recurs.
We would need to see how you tried creating the event log on the XP machine...
Generally, you need to read this: http://msdn.microsoft.com/en-us/library/49dwckkz(v=vs.80).aspx
Particularly the note discussing when to create your custom event log:
"In general, create the new event source during the installation of your application. This allows time for the operating system to refresh its list of registered event sources and their configuration. If the operating system has not refreshed its list of event sources and you attempt to write an event with the new source, the write operation will fail. If creating the source during installation is not an option, then try to create the source well ahead of the first write operation, perhaps during your application initialization. If you choose this approach, be sure your initialization code is running with administrator rights on the computer. These rights are required for creating new event sources."
Try creating the custom log in advance of the first logging event to use it.
I have a program in C# for Windows Phone. It does some really CPU-heavy stuff with IsolatedStorage and cameras and images.
Occasionally, my app crashes. It happens about 1 in 50 times, and each time it does, I end up making some minor modification to the code. I mostly always prevent the app from exiting with try-catch.
But after ~3 months of working on the app, I think it's ready to be released to the public. However, I still want to be notified about crashes so I know how to fix them.
How could I send an email to myself without forcing the user to press Send?
As far as I can tell, users don't really want to report the errors, and as such are likely to press Cancel if they see such a dialog.
EDIT: This crash would only contain the words "Crash at line " and the line number(s) that caused the crash.
EDIT II: Oops, meant a crash every 500-1000 times. Thanks #Andrei.
EDIT III: Using all my data, it seems that this app has only crashed five times out of the 18000+ times I've debugged it. That gives my app a one-in-36000 chance of crashing if the user uses my app for 3 months on an average usage estimate of 20 launches per day, which, in my extremely biased opinion, quite good for an app that makes heavy use of sounds, images, and sensors.
Transmitting info without the user's knowledge is evil. Use reverse psychology:
Fixing crashes by using try-catch is not really fixing them. Treat the cause, not the symptom.
Sending emails without the user's consent in wrong and, since it may contain personal information, might be also illegal. Since it also might cost the user to send data it also makes it commercially less viable as it increases cost for the user without bringing him real benefits.
Sending the crash report to a website instead of an email address looks more professional.
If you don't want the user to have to click to send each crash report you might try to ask the user when he installs the application whether he wants to submit the crash info.
A google search for "silverlight upload file" provided this link. May it help you well.
Can you just upload the crash info with a POST request to a website? It's probably easier to do that and then let the website send an email than it is to send (random) emails in the user's name...
Unless Silverlight for WP7 supports the SmtpClient, there won't be a way to send mail outside of the email app.
There are a few work arounds however:
Create a web service to capture the data, that your wp7 can attempt to make a request to,
Just use the Email function and hope users hit send (you'd be surprised)
Use a service like Flurry that has OnError event logging, and put that in your unhandled exception handler.
Use an email web service proxy to send the email to you.
Well, there is the WPAppManifest.xml in this file you can specify what the user needs to accept.
Here is the EMail thing: http://www.ginktage.com/2011/04/how-to-send-email-in-windows-phone-7-using-c/
I think this would solve your problem.
This is i think the right thing for you: http://www.preemptive.com/products/runtime-intelligence/compare-editions
For WP7 Developer its free.
You can track the application usage from the users. You'll see how many people how long your application are using, and i think also if it crashs...
As others have said, you luckily can't send emails as the user without him knowing - but you can just use a web service.
To improve this, I create the MD5 hash of the stacktrace and first check if the crash happened before and only if it hasn't happened before, I send the crash report.
But I stopped asking the users as well. They just won't do it then. I simply remove all personal data first.
I doubt this is even possible. So your app is running and user decides to End Process via Task Manager. Is there a method/action to save data during process.kill? I doubt there is but I had to ask.
Also, if a user shuts down/restarts PC (as in windows update/manual restart), what action would the app execute? Window_Unloaded? On this second question, I would like to find a way to ensure my app does not show up as a 'if you want to restart, kill this app' situation and want to save needed data.
Your two cents is greatly appreciated!
It's not possible to do what you want unless you have two processes; one monitoring the other one's status and do some stuff upon its termination. The watchdog process might be a Windows Service Application without GUI.
Windows sends a quit message to every opened application when normal shutdown occurs. You can run some code (usually housekeeping stuff) upon receiving the message and exit the application. It shouldn't take long or Windows will automatically ask user if they want to kill the application.
Force shutdown kills all processes immediately (in no particular/predictable order). So you can't (easily) detect it.
I suggest you to save everything needed as soon as possible to prevent data loss when the application process gets killed.
If something terminates your running app, then you don't get an opportunity to do anything, just die. You modify your app such that all data is always saved to some persistent location, so if the app dies, the persisted data remains. Obviously you have to design for this. Then if the user does a "save", you commit to the "real" datastore.
If Windows is going to reboot, it should send a message to your app, which you can handle. Not sure if this works for all GUI/console/service -type apps however.
We are in the process of setting up surround scm as our source control program. We created a trigger which will run when changing the state of a file/repository. When we run it on many files the server gets several werfault.exe processes in the process list. I realize its windows error reporting, however, there is no popup. I'm trying to determine the cause of the error... is there a specific log I can check, or a debugging technique I can use? I don't believe it will be possible to debug directly on the server it runs on.
Thanks
WER faults end up in the Event Log, so that might give you a tiny clue, though it's usually not enough info to tell what went wrong. Maybe you want to add more logging to your trigger application, or have it run userdump.exe when it's about to crash (see AppDomain.UnhandledException event) to a specific folder - that way you can open up the crash dumps later to figure out what went pear-shaped.
What was happening was that we set a trigger on certain events and the trigger calls the handling exe simultaneously, which was swamping the server. We're now using an alternate solution with a windows service so we can control the max amount of simultaneous trigger executions.
I have a WPF application that occasionally crashes, and say "not responding". Is there a way to detect if the program is not responding? And if so, restart the WPF application?
This will be a temporary fix until the bugs are fixed.
You could use the Application Recovery & Restart Manager API, which was introduced in Windows Vista. This is an unmanaged (C) API, however there are managed wrappers available in the Windows API Code Pack.
This is a good feature to add to your application anyway, as it provides the user with a nicer experience if (when!) you application crashes. You can even write a callback that persists information about what the user was doing, and then restore that state when the application restarts.
The most basic use of the API would be to just add the following line somewhere in application startup:
ApplicationRestartRecoveryManager.RegisterForApplicationRestart( new RestartSettings( "restart", RestartRestrictions.None ) );
Because this is a temporary fix while you debug the app, one possibility is to cheat and use a bootstrapper/startup app whose sole job is to monitor the problematic app. Start the problematic application via the System.Diagnostics.Process class's Start method, then occasionally monitor the returned Process' Responding property. If not responding, do what you need to do.
It's important that this only be done as a stopgap while you fix the real problem, of course. There are lots of little issues with doing something like this long-term.