How can I monitor an application crash from a separate process - c#

I have a certain .net application that occasionally crashes with one of the following windows errors:
[application name] has encountered a problem and needs to close. We are sorry for the inconvenience.
or
[application name] has stopped working
I want to monitor this app from another .net process, prevent showing the default windows error report dialog, and do my own error processing.
Is there a way I can detect that the other app has crashed?
And can I prevent or hide the default error dialog?
Some background information: I do have the code for the crashing app, and I can change it if necessary. However the crash is caused by a third party unmanaged assembly, which overwrites some memory and leaves the app in an unrecoverable state. A simply try-catch block is not enough to prevent the crash. This is why I want to monitor and handle the error from a separate process.

If the app writes to the windows event log, your other program could check there for errors

Can AppDomain.UnhandledException help?

The dialog box is a function of Windows Error Reporting (WER).
Is there a way I can detect that the other app has crashed?
There are plenty of options, from a service that requires some kind of heartbeat message from the process, to enabling catching of corrupted state exceptions, to enabling a corporate WER server. (link below)
[C]an I prevent or hide the default error dialog?
The WER configuration documentation has information about excluding a process from the automatic dialog.
Specifically the registry key:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\
Windows Error Reporting\ExcludedApplications\[Application Name]
(HKCU has a similar key)
Unfortunately, if it's an access violation, you're pretty well hosed. By the time that the exception has made it to WER the entire stack is blown, and the memory is already corrupt.
Disabling the built in error reporting for your application, will also prevent the automated creation of minidumps, which may be helpful, if not in solving the direct issue, providing ammunition for use convincing the vendor to fix their dll.
If the vendor is unwilling or unable to fix the problem, you could copy the way Explorer handles shell extensions, and host the component in a separate process. That way, when it crashes, it only trashes the memory of the other process. You'd have to write a wrapper to allow you to communicate with it.

Related

Program works on dev machine, but won't start on test machine

I've been writing this program for a while now, and I'm finally ready to start testing it. It works 100% on my dev machine, but I wanted to try it on a machine it's never run on. So, I get my program over to a test computer. When I double-click the exe, nothing happened. I opened up task manager, and tried again. I saw the process start, but after about 5 seconds, it disappeared. No errors, no exceptions, no nothing. How would I go about trying to figure out what is going wrong? I'm still fairly new, and I've never had this happen. Thanks for any and all help!
EDIT
Sorry for not mentioning before. This is a winforms application.
EDIT 2
So, turned out what was going on is that I was trying to a dll meant for 64-bit OS into a 32-bit OS. In Windows XP, this threw a BadImageFormatException. However, in Windows 7, as I stated, it threw no exception at all.
This is a pickle, no doubt about it. I've had to debug this type of thing before.
The first bit of useful information is that no exception is being thrown out. This tells me that somewhere in your actual code is the key to solving the problem. You are either trapping an exception and closing silently, or your code is hitting what it considers to be a "normal" exit condition and is closing in what it would consider the normal way.
To figure out where and why it's exiting, I would add debug logging at key points in your application, and attach a listener to the Debug/Trace listener collection that writes out to a file. "Key points" are places where the application is supposed to exit (or the main form of the window is supposed to close), and within any "catch" block or error event handler. Run this new version on the test computer and see what it gives you. That should tell you the basic flow of the program behind the scenes, and through what mechanism it's shutting down.
If you're running a console application, it is possible that it runs and then closes itself.
Trying opening a command prompt, and then executing the application from there.
If your program has output, then you would see it in that command window.
Have you checked the application event log?
Do you have the necessary version(s) of .Net installed?
Perhaps you should put more exception handling with calls to MessageBox.Show("I failed here") through out your application.

How to debug a hanging WPF application?

I have a WPF application that is hanging on one user's machine. Other users aren't affected. The app hangs both running natively out of the development environment and whilst running under debug. The problem can be reproduced reliably - it simply hangs whatever the user attempts to do. Running under debug offers no clues, no exception is thrown, the app simply stops responding.
What options do I have for debugging this? Are there any external tools - things like sysinternals suite for example - that can help? Are there any Visual Studio debugger tricks or tips that might provide a bit more info?
Yes, you can use mdbg.exe to attach to the hanging process (a PID) and when you are there press w to see the stack trace.
btw. the hanging could possibly be caused by the corrupted font cache so before you try the mdbg try to find the instruction on how to clear the WPF's font cache.
Since this is a rather general description only general pointers:
hit "pause" in the debugger and see where it hangs
patch the system + drivers to the latest "stable level"
check any 3rd-party assemblies you are using
perhaps there is some quirk regarding version and/or configuration and/or dependency
use sysinternal processmon to check what the app does (which files are accessed etc.)
check network connectivity and configuration (proxy, DNS, firewall etc.) if your app uses anything (like a network share or DB or internet access etc.)
check RAM (perhaps the machine is paging like crazy...)
if your app is multi-threaded there can be exceptions "lurking" => try adding global handlers to get a clue (see here)
Font problems can be another issue to account for... see here
check for antivirus etc. => these can sometimes create strange behaviour
anything of the above could give you a clue what's going on.
Check your hardware acceleration for the machine. Remember WPF uses direct hardware access for rendering when available. You can try reducing your acceleration, updating your video drivers, etc.
What operating system is this running under? If Windows 7 - is Aero enabled?

Windows 7 - Disable Close Program/Debug Program Dialog, yet crash dump and notify the user

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.

How to eliminate Unhandled Exception dialog produced by 3rd party application

I'm working with a 3rd party executable that I can't recompile (vendor is no longer available). It was originally written under .Net 1.1 but seems to work fine under later versions as well. I launch it using Process.Start from my own application (I've tried p/invoke CreateProcess as well with the same results so that's not relevant)
Unfortunately this 3rd party app now throws an unhandled exception as it exits. The Microsoft dialog box has a title like "Exception thrown from v2.0 ... Broadcast Window" with the version number relating to the version of .Net it's running under (I can use a .exe.config file to target different .Net versions, doesn't help).
The unhandled exception dialog box on exit doesn't cause any real problems, but is troubling to my users who have to click OK to dismiss it every time. Is there any way (a config file option perhaps) to disable this dialog from showing for an app I don't have the source code to? I've considered loading it in a new AppDomain which would give me access to the UnhandledException event but there's no indication I could change the appearence of the dialog. Maybe someone knows what causes the exception and I can fix this some other way?
You could write a wrapper application that calls the 3rd party application directly and launch your application using Process.Start.
Then in your wrapper application trap the exception so the users won't see the error message.
If it hasn't been obfuscated you may be able to decompile it? This is of course illegal etc. but if the company has actually gone bankrupt then no one is there to pursue it. It is reasonable for you to support the code if you have no other choice.
Reflector might give you a clue as to why the code crashes as well, perhaps you need to do something or call it with a parameter to stop it from doing so?
Next time don't try to use something without source code :)
A workaround is to follow Chris' suggestion. A wrapper application can make use of such code,
http://blog.jtbworld.com/2007/06/windows-live-writer-spell-checking.html
Find the old application executable.
Execute it in an AppDomain object created in the wrapper application.
Bind your application unhandled exception handler to this AppDomain object's UnhandledException event.
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

COM Exception 0x8004005

I have a C# web service that is calling COM objects to access a FileNet imaging system. The service is occasionally encountering the following error when making a call to the FileNet COM objects:
System.Runtime.InteropServices.COMException (0x80040005): Need to run the object to perform this operation (Exception from HRESULT: 0x80040005 (OLE_E_NOTRUNNING))
Any idea on what this means, or how to troubleshoot it? I could find almost nothing when searching with Google, and my experience with COM is very limited. Thanks.
Unfortunately, that HRESULT is the "Something Went Wrong" error code. I would suggest:
Check the system and application event logs to see if there are any better error messages being logged
Check any application specific error logs for your COM component
If neither of those shed any more light on what is going wrong, you may want to consider adding your COM assembly to a Component Services package. This should let you shut it down and restart it much more easily without having to reboot the system.
Depending on the OS (This is from Windows 7, but most are similar):
Start component services (under Administrative tools, usually)
Drill down to Component Services, Computers, My Computer, COM+ Applications.
Right click to add a new application.
Choose to create an empty application. This will let you pick which COM components you want to run in here.
Give the application a name
If you don't know much about your COM component, I would recommend choosing a Server application to start. This will start it out-of-process for the caller. If this doesn't work (e.g. calls fail and such), remove this application and try again as a library application.
Pick the credentials for the service. Network Service is probably the safest choice (e.g. fewest permissions), but I have no idea what your requirements are. You may need to provide a domain account or LocalSystem if it is accessing hardware or other such things.
Finish out the wizard (you may need to revisit these if you need more control).
Drill into your new Application and find the Components folder.
Right click and choose New Component
If the COM controls are already registered, choose Import components. If not, choose Install Components
Now select the components you care about. Note that it is fairly important to get all the inter-related components into the same application. Otherwise, older COM assemblies are unlikely to work correctly
Finish out the wizard. If you go back to the COM+ Application level of the tree view you should see your new application, with a non-animated icon.
There shouldn't be any changes necessary to the calling code. Make a request to your service and go back to the manager... you should see the icon animate once the COM+ Application starts up. You should also be able to re-start it from here, if you desire.
There are a lot of configuration options around spin-down time and pooling, so that may help you to if you find that the COM DLL only gives issues after a certain period of time, for example.
If the problem is truly intermittent, and sometimes happens on one machine, and sometimes doesn't - you could write your code to trap the error, and have it try again.
If there are machines it never works on, it may be due to some other issue, such as UAC, or the component not being properly installed.

Categories

Resources