The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: jj2007 on January 09, 2011, 02:06:02 AM

Title: Post mortem exception
Post by: jj2007 on January 09, 2011, 02:06:02 AM
I am testing some macros and stumbled over something strange: an access violation at 7c920de3 after a successful ExitProcess. Has anybody seen this phenomenon? The exe is attached.

Note that
invoke GetProcessHeap
invoke HeapValidate, eax, 0, 0

just before ExitProcess detects heap corruption (eax=0, surprise surprise...), and makes the exit a bit softer - no nasty box. Even the return value of ExitProcess is set correctly, but then the proggie crashes somewhere in no man's land...
Title: Re: Post mortem exception
Post by: hutch-- on January 09, 2011, 04:00:14 AM
I have seen it occasionally and its usually a memory page fault that occurred earlier in the application. They are genuine fun to track down.  :P Its worth making sure you handle register preservations correctly all the way through the app, I have been bitten by this one occasionally in the past.
Title: Re: Post mortem exception
Post by: jj2007 on January 09, 2011, 11:26:34 AM
Hutch,

registers are ok, it's a buffer overflow, and I know where it happens. Still, fun to see that you can exit an application and afterwards you get banged over the head... :bg
Title: Re: Post mortem exception
Post by: dedndave on January 09, 2011, 11:52:46 AM
could it be the use of HeapReAlloc ???
Title: Re: Post mortem exception
Post by: BogdanOntanu on January 09, 2011, 01:30:20 PM
Quote from: jj2007 on January 09, 2011, 11:26:34 AM
. Still, fun to see that you can exit an application and afterwards you get banged over the head... :bg

That is normal for any program that does not free all of it's allocated memory buffers and relies on the OS to do that for the process after ExitProcess is called.

If you free you allocated memory buffers yourself then you would probably (if you are lucky) get an exception when you try to free the buffer that was overwritten.

HeapAlloc and GLobalAlloc usually keep a small control structure at the start of the buffer that is allocated.

Hence if you have buffer_01 and then buffer_02 in memory and you write over the end of buffer_01... THEN you will destroy the control structures for buffer_02 and you might get an exception when you try to GlobalFree or HeapFree on buffer_02
Title: Re: Post mortem exception
Post by: jj2007 on January 09, 2011, 04:53:14 PM
Quote from: BogdanOntanu on January 09, 2011, 01:30:20 PM
That is normal for any program that does not free all of it's allocated memory buffers and relies on the OS to do that for the process after ExitProcess is called.

My programs do free all of their allocated memory buffers, but if you have a different programming style, Bogdan, you are absolutely free to rely on the OS.
Title: Re: Post mortem exception
Post by: BogdanOntanu on January 09, 2011, 05:47:25 PM
Quote from: jj2007 on January 09, 2011, 04:53:14 PM
Quote from: BogdanOntanu on January 09, 2011, 01:30:20 PM
That is normal for any program that does not free all of it's allocated memory buffers and relies on the OS to do that for the process after ExitProcess is called.

My programs do free all of their allocated memory buffers, but if you have a different programming style, Bogdan, you are absolutely free to rely on the OS.

I usually do free all of the allocated memory buffers before ExitProcess in my applications and I do recommend this style to other programmers exactly because you will get an exception in your application when you try to free an buffer that was overwritten by mistake.

If you already did this in your application then they only way to get an "post mortem" exception is if your application code did overwrite one of the memory buffers allocated by the OS API on the behalf of your application.

Those kind of buffers are released by the OS after ExitProcess is called.

Title: Re: Post mortem exception
Post by: jj2007 on January 09, 2011, 05:54:04 PM
Quote from: BogdanOntanu on January 09, 2011, 05:47:25 PM
I usually do free all of the allocated memory buffers before ExitProcess
So do I, so we have something in common :bg

Quote... they only way to get an "post mortem" exception is if your application code did overwrite one of the memory buffers allocated by the OS API on the behalf of your application.
That is a bit cloudy, Oberlehrer Bogdan ("the OS API"...?), but I appreciate your willingness to contribute towards solving the mystery.
Title: Re: Post mortem exception
Post by: dedndave on January 09, 2011, 06:10:39 PM
oh - i thought you knew what caused it, Jochen
Quoteregisters are ok, it's a buffer overflow, and I know where it happens. Still, fun to see
that you can exit an application and afterwards you get banged over the head...
Title: Re: Post mortem exception
Post by: jj2007 on January 09, 2011, 06:34:18 PM
Quote from: dedndave on January 09, 2011, 06:10:39 PM
oh - i thought you knew what caused it, Jochen
Quoteregisters are ok, it's a buffer overflow, and I know where it happens. Still, fun to see
that you can exit an application and afterwards you get banged over the head...

Dave,
I do know it's caused by heap corruption, and I do know where exactly it happens. But I also do use HeapFree and test its return value for each allocated buffer, in contrast to the bold assumptions of Oberlehrer Bogdan. If he invested less efforts in chasing the Ballmer Peak, he could have launched Olly, and he would have discovered the HeapFree calls.
Title: Re: Post mortem exception
Post by: redskull on January 09, 2011, 07:31:59 PM
Quote from: jj2007 on January 09, 2011, 11:26:34 AM
Still, fun to see that you can exit an application and afterwards you get banged over the head...

A process doesn't end after you ExitProcess(), only after all the handles have been closed.  A process actually HAS to stay active, so that something else can read the exit code you returned via Exitprocess() in the first place.
Title: Re: Post mortem exception
Post by: BogdanOntanu on January 09, 2011, 08:09:35 PM
Quote from: jj2007 on January 09, 2011, 06:34:18 PM
Dave,
I do know it's caused by heap corruption, and I do know where exactly it happens. But I also do use HeapFree and test its return value for each allocated buffer, in contrast to the bold assumptions of Oberlehrer Bogdan.
...
If he invested less efforts in chasing the Ballmer Peak, he could have launched Olly, and he would have discovered the HeapFree calls.


Sorry jj2007 but I can not obtain an "Balmer Peak" because I do not drink alcohol... not even a tiny drop and not even in holydays ...
I could drink if I wanted (no disease here) but I do not drink because I simply dislike it.

About running your application in Ollydbg in order to find your bugs... If you would like then please do excuse me BUT ... I was kind of busy programming some very intersting personal ASM code and applications and I only have had this small amount of time to take off from my "work" in order to try and help you with some concepts but unfortunately not with your desired level of details.

Besides as a rule of thumb I never run other people's code at home ... not even inside Olly or another debugger... sorry.

Again please excuse IF my try to help you in "my way" and not "your way" has failed ... "mea culpa" ;)

PS.
------
About Balmer Peak : http://xkcd.com/323/ 


Title: Re: Post mortem exception
Post by: jj2007 on January 09, 2011, 09:03:56 PM
Quote from: BogdanOntanu on January 09, 2011, 08:09:35 PM
About running your application in Ollydbg in order to find your bugs...

Bogdan,

No, I would not expect you to run my apps to find my bugs. However, writing, without knowing anything about my code, "That is normal for any program that does not free all of it's allocated memory buffers and relies on the OS to do that", is just extremely arrogant. This is why you got the title "Oberlehrer Bogdan" tonight.
Title: Re: Post mortem exception
Post by: BogdanOntanu on January 09, 2011, 10:17:23 PM
Quote from: jj2007 on January 09, 2011, 09:03:56 PM
However, writing, without knowing anything about my code, "That is normal for any program that does not free all of it's allocated memory buffers and relies on the OS to do that", is just extremely arrogant. This is why you got the title "Oberlehrer Bogdan" tonight.

First of all it was not my intention to be arrogant or proud in any way. In fact I do not know how to be arrogant but unfortunately I am often perceived like that by humans. Please be assured that my only intention was to give you a quick hint based on my experience.

I did not wanted to say that you do did something wrong in your application. I was just saying that this kind of behavior (have an crash/exception right after ExitProcess) is normal for many applications and should not be considered "abnormal" or "strange" since the OS still has some cleanup work to do after ExitProcess was invoked.

Yes I do not know anything about your code and honestly I do not care or even want to know anything about it because I do not have the time or the desire to study it (I have my own projects).

All I can do is to give you some conceptual hints based on your clear and detailed description of the problem and my experience in similar cases and then I can hope that this puts you an the right track or at least gives you an alternative idea for your own investigation.

After all you have asked for help and I have provided what I can...

I am sorry if I can not provide you with more that that ...

Also please be assured that inside my mind there is no arrogance or humility at all.
Title: Re: Post mortem exception
Post by: donkey on January 09, 2011, 11:21:00 PM
Quote from: BogdanOntanu on January 09, 2011, 10:17:23 PM
In fact I do not know how to be arrogant but unfortunately I am often perceived like that by humans.

:bg
Title: Re: Post mortem exception
Post by: oex on January 10, 2011, 12:20:26 AM
Quote from: donkey on January 09, 2011, 11:21:00 PM
Quote from: BogdanOntanu on January 09, 2011, 10:17:23 PM
In fact I do not know how to be arrogant but unfortunately I am often perceived like that by humans.
:bg

(http://images.juniorslayouts.com/picture/1/b/brain_of_pinky_and_the_brain-4037.jpg)
Title: Re: Post mortem exception
Post by: jj2007 on January 10, 2011, 12:38:05 AM
Quote from: redskull on January 09, 2011, 07:31:59 PM
Quote from: jj2007 on January 09, 2011, 11:26:34 AM
Still, fun to see that you can exit an application and afterwards you get banged over the head...

A process doesn't end after you ExitProcess(), only after all the handles have been closed.  A process actually HAS to stay active, so that something else can read the exit code you returned via Exitprocess() in the first place.

Red,
When launched normally, the exe successfully deallocates with HeapFree, then prints "debug ok" and then crashes with a box.
When run with Olly, it exits fine and terminates at KiFastSystemCallRet, with Olly indicating the correct ExitProcess return code, -111 in this case.
It's pretty futile to argue since heap corruption is the cause, and the bug needs to be fixed anyway. But lessons might be that a) HeapFree returning TRUE is no guarantee that your heap is ok, and b) that there is life after ExitProcess :bg
Title: Re: Post mortem exception
Post by: hutch-- on January 10, 2011, 01:56:21 AM
 :bg

There is a special skill to arrogance based on experience and allowing how long I have been writing software for Windows I can probably safely boast that I have had more GP faults than most other folks around. The flip side of the phukups is I am reasonably good at finding them.  :bdg
Title: Re: Post mortem exception
Post by: redskull on January 10, 2011, 02:13:59 AM
Quote from: jj2007 on January 10, 2011, 12:38:05 AM
b) that there is life after ExitProcess

There's not just life after ExitProcess(), there's an entire advanced civilization of issues that can go awry.  Some examples to cook your brain: The system brings all the other threads to a halt, so anything they are waiting on is stuck in limbo; for instance, image thread B has issued a ReadFile(), and is then signaled by thread A's ExitProcess(); what happens to the resulting APC if the process is gone?  Also, all the DLL's get their DETACH message, so any loaded DLL has a chance to wreak any havoc it likes, and deadlock/crash anything it wants.  Also, if some other program is using WaitForSingleObject() to wait on the process in question to terminate and then plans to use GetExitCodeProcess() to see what went wrong (which requires the handle), how long must the operating system keep the handle valid?

Big Fun!   :toothy

-r
Title: Re: Post mortem exception
Post by: dedndave on January 10, 2011, 05:15:08 AM
i dunno about you having more GP faults than anyone
i thought c0000005 was my name for a while, there
Title: Re: Post mortem exception
Post by: donkey on January 10, 2011, 05:32:27 AM
Quote from: redskull on January 10, 2011, 02:13:59 AM
Also, if some other program is using WaitForSingleObject() to wait on the process in question to terminate and then plans to use GetExitCodeProcess() to see what went wrong (which requires the handle), how long must the operating system keep the handle valid?

Hi RedSkull,

When you open a handle to the target process or create the process as a child process which returns an open handle the system increments the reference count on that process. The system will not clean up the process structures until after your application closes that handle and the reference count drops to zero. As with any object, it is only completely destroyed once ALL handles referencing it are closed, including those in other processes. Once all open handles to the process are closed the system will perform a cleanup of the process structures.

Edgar