Welcome to MSDN Blogs Sign in | Join | Help

Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Here's a question that came from a customer. By now, you should already have the necessary psychic powers to answer it.

Our program calls ExitProcess(1) to indicate that it exited unsuccessfully. The process that launched our program waits for the program to exit and then calls GetExitCodeProcess to retrieve the exit code. The function succeeds, but the exit code is zero! How can this be?

Hint: Read about how processes terminate on Windows XP.

Published Tuesday, May 06, 2008 7:00 AM by oldnewthing
Filed under:

Comments

# Cold reading

Tuesday, May 06, 2008 11:00 AM by Nathan_works

From a cold reading of the MSDN, it would appear they are doing it "right"..

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 11:27 AM by pcooper

Wild guess, based on reading the hint article: They see that the exit code is 0 in the debugger, because their debugger is creating a new thread during process termination to be able to debug the process. And the debug thread terminates successfully.

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 11:44 AM by Joel

From MSDN

"Terminating a process does not necessarily remove the process object from the OS. A process object is deleted when the last handle to the process is closed. "

So, they are in a circular loop where they can't retrieve the Exit Code until they close their handle?

Maybe they should call DuplicateHandle with the DUPLICATE_CLOSE_SOURCE flag.

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 12:12 PM by Kujo

(Especially in light of the provided hint article) I would guess they are waiting for the process to end in the wrong way... probably by waiting on a mutex.  Thus they race with the dying process to read the exit code.

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 12:23 PM by A. Skrobov

A guess: a DLL their process is using calls ExitProcess(0) itself as part of its teardown.

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 12:27 PM by El Guapo

If the process were still running, the exit code would be 259 and not 0.

I have no clue what the problem is. They are doing everything right. If they are doing something incredibly stupid like calling ExitProcess from DLL_PROCESS_DETACH, we wouldn't be requested to invoke psychic powers to debug that, that would just be plain dumb.

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 12:39 PM by Bryan

I believe it's involving DLL_PROCESS_DETACH - something they're doing is pooching the exit code.

That's my guess anyway.

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 12:45 PM by Kujo

Joel: You don't want the OS to delete the process object, that's where your exit code is stored.

El Guapo: (rereads documentation) Ah, you're right. d'oh!

Calling RaiseException with 0 doesn't seem like psychic debugging, either.

Maybe we can get to ExitProcess(0) with a better story behind it... something like: DLL_PROCESS_DETACH handler tries to use a critical section, ends up reading something in an inconsistent state, faults, the exception filter runs and ends the process with 0.

Would such an exception be handled by a try/catch block?  The thought of an exception unwinding the stack past ExitProcess is pretty scary.

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 1:34 PM by Greg D

Perhaps the called program is exiting successfully!

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 2:21 PM by gilltots

this is an easy one - it's just an off-by-one error deep in the guts of windows :)

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 2:49 PM by Jack Mathews

Yeah, a crash is probably happening in a DLL_PROCESS_DETACH, which is just causing TerminateProcess to be called on self and thus an exit code of 0.

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 3:24 PM by Brian

I liked how in the referenced article, Raymond actually had FAITH in his readers to not nitpick!  Aaaahhhh Raymond, you sure were foolish in your younger free-wheeling days of a year ago.

(Disclaimer:  Long time reader who was a few shades less upset with the nitpickers as Raymond had to have been.)

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 4:47 PM by John

My psychic powers are weak; my guess is that some loaded DLL is either crashing or calling ExitProcess(0) during DLL_PROCESS_DETACH.

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 5:20 PM by Gwyn

Maybe they aren't checking the return value from GetExitCodeProcess? The process might be racing or hung in which case the return value would be STILL_ACTIVE (259), but they wouldn't know that, since they didn't check it?

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Tuesday, May 06, 2008 5:28 PM by Kujo

I am able to reproduce this with an UnhandledExceptionFilter (using ExitProcess again) and with structured exception handling (returning control to main.)  I imagine there are other permutations of this approach as well.

Kudos to whoever made ExitProcess behave so well in these circumstances.

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Wednesday, May 07, 2008 6:44 PM by Triangle

Q: Why does ExitProcess(1) produce an exit code of zero?

A: Welcome to windows programming.

# re: Psychic debugging: Why does ExitProcess(1) produce an exit code of zero?

Monday, May 12, 2008 2:07 PM by wtroost

My guess is that they're using ShellExecute to launch the program.  Then they're passing the return value of ShellExecute to GetExitCodeProcess.  But since ShellExecute doesn't return a process handle this causes GetExitCodeProcess to return 0 for error.

# The Case of RegSvr32 and the Haunted DLL

Saturday, June 28, 2008 5:19 AM by All Your Base Are Belong To Us

Last week I've resolved a simple "debugging" case by phone, and figured that it might benefit

New Comments to this post are disabled
 
Page view tracker