flat assembler
Message board for the users of flat assembler.

Index > Heap > Resource leaks in examples

Author
Thread Post new topic Reply to topic
ProMiNick



Joined: 24 Mar 2012
Posts: 392
Location: Russian Federation, Sochi
ProMiNick
Examples should teach newbies to clean used resurces properly:
request resorces:
Code:
invoke  DirectDrawCreate,NULL,DDraw,NULL
cominvk DDraw,SetDisplayMode,640,480,8
cominvk DDraw,CreateSurface,ddsd,DDSPrimary,NULL
cominvk DDSPrimary,GetAttachedSurface,ddscaps,DDSBack 
cominvk DDraw,CreateSurface,ddsd,DDSPicture,0
cominvk DDraw,CreatePalette,DDPCAPS_8BIT+DDPCAPS_ALLOW256,buffer+400h,DDPalette,0
    

ugly trying to free them:
Code:
cominvk DDraw,RestoreDisplayMode
cominvk DDraw,Release    


what should be:
Code:
cominvk DDraw,RestoreDisplayMode
        cominvk DDSPicture,Release
        cominvk DDPalette,Release
        cominvk DDSPrimary,DeleteAttachedSurface,0,DDSBack
        cominvk DDSPrimary,Release
        cominvk DDraw,Release    

thanks

of coursy granny OS freeing all for us in request ExitProcess, but it is ...

Every could always check is he freeing resources properly:
replace "invoke ExitProcess,exitcode" with "mov eax,exitcode" and "ret" - if process will disapier in taskmanager - all properly.

_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 21 Nov 2019, 09:49
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7489
Location: Kraków, Poland
Tomasz Grysztar
You're right, of course. This is such an old example, that I do not even remember how it came to be. It might have been partially copied from somewhere. The graphics were certainly copied from an example that came with some SDK back then. And this code was then left untouched for years and years...

ProMiNick wrote:
Every could always check is he freeing resources properly:
replace "invoke ExitProcess,exitcode" with "mov eax,exitcode" and "ret" - if process will disapier in taskmanager - all properly.
I believe a generally better way is to use a tool like Memproof.
Post 21 Nov 2019, 11:04
View user's profile Send private message Visit poster's website Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 604
Location: Belarus
DimonSoft
ProMiNick wrote:
Every could always check is he freeing resources properly:
replace "invoke ExitProcess,exitcode" with "mov eax,exitcode" and "ret" - if process will disapier in taskmanager - all properly.

No. It is very OS version dependent. And if one uses some stuff like GetOpenFileName, the trick will not work at all in spite of proper resource freeing.
Post 21 Nov 2019, 19:53
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 392
Location: Russian Federation, Sochi
ProMiNick
tryed on WinXPx64SP2 & Win7Prox86SP1 - without releasing all created COM objects they left in memory & dll internal ServerLockCount remains positive, with releasing COM objects ServerLockCount is zeroed.
Quote:

Every could always check is he freeing resources properly:
replace "invoke ExitProcess,exitcode" with "mov eax,exitcode" and "ret" - if process will disapier in taskmanager - all properly.

Yes, it works only in virgin OS clean from hooks and when process has launched from explorer by doubleclicking on its icon.
In first release of DDRAW ServerLockCount was at $BAABB100 (time when it wasn`t COM server) founded via analize of DDRAW.SYM file. In modern world ServerLockCount could be found if inspect exported CanUnloadNow code.
no matter OS bitness - CanUnloadNow code usualy looks like:
Code:
        xor     eax,eax
        cmp     eax,[ServerLockCount]
        jz      .locret
        inc     eax
      .locret:
        ret     
Post 22 Nov 2019, 07:32
View user's profile Send private message Send e-mail Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 604
Location: Belarus
DimonSoft
ProMiNick wrote:
Yes, it works only in virgin OS clean from hooks and when process has launched from explorer by doubleclicking on its icon.

Not really convenient way to run a program, right?
Post 22 Nov 2019, 08:25
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 392
Location: Russian Federation, Sochi
ProMiNick
"only" is related to "always".
However, if program successfuly closed with "ret" instead of "ExitProcess" (no matter in what windows version) it means that it perfectly clean used resources. Closed app method could changed back to OS universal ExitProcess.
Post 22 Nov 2019, 12:34
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7489
Location: Kraków, Poland
Tomasz Grysztar
ProMiNick wrote:
However, if program successfuly closed with "ret" instead of "ExitProcess" (no matter in what windows version) it means that it perfectly clean used resources. Closed app method could changed back to OS universal ExitProcess.
Not necessarily.
Out of many possible examples, this one closes correctly on my system, even though it does not free resources properly:
Code:
include 'win32ax.inc'

start:
        invoke  HeapCreate,0,20000h,0
        ret

.end start    
Tools like MemProof catch these kinds of leaks.
Post 22 Nov 2019, 12:48
View user's profile Send private message Visit poster's website Reply with quote
st



Joined: 12 Jul 2019
Posts: 36
Location: Russia
st
ProMiNick wrote:
Every could always check is he freeing resources properly:
replace "invoke ExitProcess,exitcode" with "mov eax,exitcode" and "ret" - if process will disapier in taskmanager - all properly.

As far as I remember this ret instruction will execute NtExitThread (sorry, have no MS Windows to trace with a debugger and check it). If this thread is the last one, OS terminates process. However some calls to DX do create threads, that is why process will continue to run.

ExitProcess just calls NtTerminateThread for every thread (except of current one, which is exited with NtExitThread).

So, suggested trick does not check if other resources (memory, handles, etc) are not freed.
Post 24 Nov 2019, 14:25
View user's profile Send private message Visit poster's website Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 604
Location: Belarus
DimonSoft
st wrote:
As far as I remember this ret instruction will execute NtExitThread (sorry, have no MS Windows to trace with a debugger and check it). If this thread is the last one, OS terminates process. However some calls to DX do create threads, that is why process will continue to run.

ExitProcess just calls NtTerminateThread for every thread (except of current one, which is exited with NtExitThread).

So, suggested trick does not check if other resources (memory, handles, etc) are not freed.

Obligatory note: and even that is just an implementation detail that might change at any moment and thus should not and cannot be relied upon.
Post 24 Nov 2019, 17:41
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7489
Location: Kraków, Poland
Tomasz Grysztar
DimonSoft wrote:
Obligatory note: and even that is just an implementation detail that might change at any moment and thus should not and cannot be relied upon.
Documentation for CreateThread has always been stating that:
Win32 SDK reference wrote:
The thread execution begins at the function specified by the lpStartAddress parameter. If this function returns, the DWORD return value is used to terminate the thread in an implicit call to the ExitThread function. Use the GetExitCodeThread function to get the thread's return value.
So terminating a thread with RET instruction is actually an officially documented behavior.
Post 24 Nov 2019, 17:58
View user's profile Send private message Visit poster's website Reply with quote
guignol



Joined: 06 Dec 2008
Posts: 640
guignol
if resources are not freed properly, it is not a correct process termination
Post 24 Nov 2019, 18:36
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 604
Location: Belarus
DimonSoft
Tomasz Grysztar wrote:
Documentation for CreateThread has always been stating that:
Win32 SDK reference wrote:
The thread execution begins at the function specified by the lpStartAddress parameter. If this function returns, the DWORD return value is used to terminate the thread in an implicit call to the ExitThread function. Use the GetExitCodeThread function to get the thread's return value.
So terminating a thread with RET instruction is actually an officially documented behavior.

Not terminating a process though. I guess, I should have removed the first paragraph of the quotation in my previous post.
Post 25 Nov 2019, 08:40
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7489
Location: Kraków, Poland
Tomasz Grysztar
DimonSoft wrote:
Not terminating a process though. I guess, I should have removed the first paragraph of the quotation in my previous post.
Yes, terminating the process is obviously not guaranteed, unless you can somehow ensure that this is the only remaining thread of the process.
Post 25 Nov 2019, 08:54
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum


Copyright © 1999-2019, Tomasz Grysztar.

Powered by rwasa.