[win32] detect a crashed process

Started by
13 comments, last by the_edd 15 years, 2 months ago
Nope. Windows exception codes follow the following format: Bits 31 and 30 represent the severity code. It should be 00 for success, 01 for informational, 10 for warning and 11 for an error. Bit 29 is set for user exception codes. Bit 28 is reserved and should not be set. Bits 27 to 16 represent a facility code. For example, Windows Update is assigned the facility code of 36, while 0 represents no particular facility. The bottom 16 bits then represent the actual error code. This is why exceptions like access violations start with 0xC: these codes represent non-user error exceptions. Now take a look at the three exit codes I posted above. None of them have any of the top three bits set and any overlap with the lower bits will be coincidental as they have no individual meaning.
Advertisement
Too bad, good to know. =)

For the OP.. does it actually matter if it crashed, or exited some other way?
Reading the post again, it seems as though you only need to know if the process has exited, since the pipe must then no doubt be unusable?
In that case GetExitCodeProcess will return a special error code if the process is still running.
Quote:Original post by Erik Rufelt
For the OP.. does it actually matter if it crashed, or exited some other way?
Reading the post again, it seems as though you only need to know if the process has exited, since the pipe must then no doubt be unusable?
In that case GetExitCodeProcess will return a special error code if the process is still running.


Well the full story is that I'm trying to port a library I have made for UNIX to Windows, that simplifies the creation of processes and interacting with their streams.

I am aiming to provide the same functionality in the Windows port, including the ability to throw an exception when the child crashes, but the clumsiness of some of the Windows APIs are making this port extremely difficult. I accept that I might have to make some concessions, but I'd like to explore all possibilities before giving up.

Another idea I've had would be to attempt to replace the child's entry point (WinMain?) so that the child can acquire an inherited Mutex before calling the real WinMain. This would allow me to look for WAIT_ABANDONED in the parent.

I haven't tried this kind of "static monkey patching" before however, and I'm really not very clued up on the guts of Windows executables or even ASM so I might not have much success in this regard. I don't know if anyone might be able to lend a hand with this or provide some useful articles?
Quote:Original post by the_edd
Another idea I've had would be to attempt to replace the child's entry point (WinMain?) so that the child can acquire an inherited Mutex before calling the real WinMain. This would allow me to look for WAIT_ABANDONED in the parent.

I haven't tried this kind of "static monkey patching" before however, and I'm really not very clued up on the guts of Windows executables or even ASM so I might not have much success in this regard. I don't know if anyone might be able to lend a hand with this or provide some useful articles?


You can use this concept to accomplish that, but it would be more work than it might be worth. There are a lot of things that you could possibly try that route, but the problem is they are all more or less "hacks" that are really specific to the application you are using and it won't always work the same on different Windows operating systems.

In terms of "crashing", there is not much standard behavior that you can go by for the child process. You couldn't use pings to the server because for that to work, you would have to run it in the main thread or a secondary thread. The main thread can be legitimately blocked, screwing up the ping timing and a secondary thread will still run in a crashed application.

You could inject a DLL and set a Vectored Exception Handler, but if the application generates exceptions that it knows how to recover from, then you will be interfering with that.

Consider all the types of crashes there are (I can't list them all but the main ones are):
- Crashes that invoke debuggers (external dialog boxes being shown)
- Crashes that are a result from exceptions not being handled (runtime error dialog box)
- Crashes that are from asserts (assert dialog boxes)
- Crashes that clean exit the application (nothing shown, but process might still be in memory)

Your best bet would be to find something that you can identify from all of them and handle each type separately. In other languages, like Ada for example, problems like these are easily solvable since the language is designed to not allow such meltdowns that you cannot identify and recover from. In C/C++ though, you simply have too much to deal with and thus finding a way that works for everything is quite infeasible. Good luck though!
Quote:Original post by Drew_Benton
You can use this concept to accomplish that, but it would be more work than it might be worth.

Ah that's the article I had in the back of my mind! I didn't have the link, though.

Quote:There are a lot of things that you could possibly try that route, but the problem is they are all more or less "hacks" that are really specific to the application you are using and it won't always work the same on different Windows operating systems.

Yes. I think I will leave this route for a rainy day. There is a lot I would need to understand before I could even begin experimenting.

Quote:
In terms of "crashing", there is not much standard behavior that you can go by for the child process. You couldn't use pings to the server because for that to work, you would have to run it in the main thread or a secondary thread. The main thread can be legitimately blocked, screwing up the ping timing and a secondary thread will still run in a crashed application.

I'm curious as to how Windows can pop up a message box for a last-chance exception without attaching a debugger to the application. Is this something that's baked in to the OS?

Quote:
You could inject a DLL and set a Vectored Exception Handler, but if the application generates exceptions that it knows how to recover from, then you will be interfering with that.

I guess I could also use DLL injection to to load a library that acquires a Mutex in DllMain? But again, I'd hack to look in to the intricacies of DLL injection anyway.

Quote:
Consider all the types of crashes there are (I can't list them all but the main ones are):
- Crashes that invoke debuggers (external dialog boxes being shown)
- Crashes that are a result from exceptions not being handled (runtime error dialog box)
- Crashes that are from asserts (assert dialog boxes)
- Crashes that clean exit the application (nothing shown, but process might still be in memory)

Your best bet would be to find something that you can identify from all of them and handle each type separately.

I keep coming back to this Mutex-in-the-child idea because I think it has a chance of working for most of those cases (even though it won't stop the various crash dialogs from appearing).

This topic is closed to new replies.

Advertisement