Sign in to follow this  
Followers 0
DarkMatter

Free Open Handles

14 posts in this topic

If I do the following, just as an example:

While 1
        $Dll = DllOpen("ADLL.dll")
        Init()
            $var = DllCall($Dll, "str", "SOMETHING", "str", "SOMETHINGELSE", "str", "MOREDATA")
            Sleep(500)
            DllClose($Dll)
        Wend

When I am watching the open handles that my script has, the handle count keeps climbing. Even though I am doing a DLLClose() the handle count never drops. I assume that AutoIT is not dropping the handles it has on the dll. It appears I am gaining about ~10 handles a second. I have actually set and watched the handle climb to around 14,000 open handles before I close the script. Does anyone have ANY idea why it is not release the handles to the DLL even though I am doing DllClose()?


[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

That example doesn't show anything.

For example, what does the Init() function do? Whatever it does, it's more probable to leak handles than that particular DllCall. Because, if you say ~10 handles a second, and common sense tells that this DllCall in your example can't be executed more than 2 times per second.

So in any case, your information is incomplete.

Try harder before jumping to conclusion that some AutoIt function is buggy.

Edited by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

That example doesn't show anything.

For example, what does the Init() function do? Whatever it does, it's more probable to leak handles than that particular DllCall. Because, if you say ~10 handles a second, and common sense tells that this DllCall in your example can't be executed more than 2 times per second.

So in any case, your information is incomplete.

Try harder before jumping to conclusion that some AutoIt function is buggy.

Below is the full code for the script. That was just an example.

Dim $QueryHandle = DllStructCreate("long")
Dim $Counter = DllStructCreate("long")
Dim $lData = DllStructCreate("long")
Dim $Percent
Dim $Dll


Init()

While 1
    
    $Dll = DllOpen("pdh.dll")
    Init()
    DllCall($Dll, "long", "PdhCollectQueryData", "long", DllStructGetPtr($QueryHandle))
    $Percent = DllCall($Dll, "double", "PdhVbGetDoubleCounterValue", "long", DllStructGetPtr($Counter), "long", DllStructGetPtr($lData))
;~    _ArrayDisplay($Percent)
    ConsoleWrite(($Percent[2] - $Percent[1]) / 100 & @CRLF)
    Sleep(5000)
    DllClose($Dll)
WEnd

Func Init()
    DllCall($Dll, "long", "PdhVbOpenQuery", "long", DllStructGetPtr($QueryHandle))
    DllCall($Dll, "long", "PdhVbAddCounter", "long", DllStructGetPtr($QueryHandle), "str", "\Processor(0)\% Processor Time", "long", DllStructGetPtr($Counter))
    DllCall($Dll, "long", "PdhCollectQueryData", "long", DllStructGetPtr($QueryHandle))
    DllCall($Dll, "double", "PdhVbGetDoubleCounterValue", "long", DllStructGetPtr($Counter), "long", DllStructGetPtr($lData))
EndFunc

This is keeping open handles even with the DllClose() there. I also have some other scripts that are doing the same thing now that I went back and checked them too.


[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites

Why would you open and close a DLL that many times? Just open the DLL before the loop and close it after.

Besides that, the script you showed should fail. You call Init() before you initialize the dll open anyway.

Dim $QueryHandle = DllStructCreate("long")
Dim $Counter = DllStructCreate("long")
Dim $lData = DllStructCreate("long")
Dim $Percent
Dim $Dll = DllOpen("pdh.dll")

While 1
    Init()
    DllCall($Dll, "long", "PdhCollectQueryData", "long", DllStructGetPtr($QueryHandle))
    $Percent = DllCall($Dll, "double", "PdhVbGetDoubleCounterValue", "long", DllStructGetPtr($Counter), "long", DllStructGetPtr($lData))
    ConsoleWrite(($Percent[2] - $Percent[1]) / 100 & @CRLF)
    Sleep(5000)
WEnd

Func Init()
    DllCall($Dll, "long", "PdhVbOpenQuery", "long", DllStructGetPtr($QueryHandle))
    DllCall($Dll, "long", "PdhVbAddCounter", "long", DllStructGetPtr($QueryHandle), "str", "\Processor(0)\% Processor Time", "long", DllStructGetPtr($Counter))
    DllCall($Dll, "long", "PdhCollectQueryData", "long", DllStructGetPtr($QueryHandle))
    DllCall($Dll, "double", "PdhVbGetDoubleCounterValue", "long", DllStructGetPtr($Counter), "long", DllStructGetPtr($lData))
EndFunc

Func OnAutoItClose()
    If IsDeclared("Dll") And $Dll Then DllClose($Dll)
EndFunc

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Dim $Dll


Init()

Looks bad. You are calling Init() before you ever set $Dll. You need to fix that first off.

More importantly, why close the dll? The handle is made so you can call dlls repeatedly without having to reload them.

Share this post


Link to post
Share on other sites

Here is the code that I copied from SmOke_N:

Dim $QueryHandle = DllStructCreate("long")
Dim $Counter = DllStructCreate("long")
Dim $lData = DllStructCreate("long")
Dim $Percent
Dim $Dll = DllOpen("pdh.dll")

While 1
    Init()
    DllCall($Dll, "long", "PdhCollectQueryData", "long", DllStructGetPtr($QueryHandle))
    $Percent = DllCall($Dll, "double", "PdhVbGetDoubleCounterValue", "long", DllStructGetPtr($Counter), "long", DllStructGetPtr($lData))
    ConsoleWrite(($Percent[2] - $Percent[1]) / 100 & @CRLF)
    Sleep(500)
WEnd

Func Init()
    DllCall($Dll, "long", "PdhVbOpenQuery", "long", DllStructGetPtr($QueryHandle))
    DllCall($Dll, "long", "PdhVbAddCounter", "long", DllStructGetPtr($QueryHandle), "str", "\Processor(0)\% Processor Time", "long", DllStructGetPtr($Counter))
    DllCall($Dll, "long", "PdhCollectQueryData", "long", DllStructGetPtr($QueryHandle))
    DllCall($Dll, "double", "PdhVbGetDoubleCounterValue", "long", DllStructGetPtr($Counter), "long", DllStructGetPtr($lData))
EndFunc

Func OnAutoItClose()
    If IsDeclared("Dll") And $Dll Then DllClose($Dll)
EndFunc

The only thing I changed was Sleep(). Went from Sleep(5000) to Sleep(500)

The attached images are taken exactly one minute apart.

Within one minute there are 99 handles that were opened.

post-33596-1206467008_thumb.jpg

post-33596-1206467019_thumb.jpg


[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites

Are you sure the DLL isn't creating the handles itself?


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Are you sure the DLL isn't creating the handles itself?

I'm 99% sure because I have seen user32 do this also.

Here is the user32 code:

Func IsDesktopLocked()
    Local $hDesktop
    Local $iRet
    Local $iRC
    Local $sMsg
    $hDesktop = DllCall("User32.dll", "int", "OpenDesktop", "str", "Default", "int", 0, "int", 0, "int", $DESKTOP_SWITCHDESKTOP)
    $iRet = DllCall("User32.dll", "int", "SwitchDesktop", "int", $hDesktop[0])
    If IsArray($iRet) Then
        If $iRet[0] = 0 Then

            $iRC = 1
        ElseIf $iRet[0] = 1 Then

            $iRC = 0
        EndIf
    Else

    EndIf

    $iRet = DllCall("User32.dll", "int", "CloseDesktop", "int", $iRet[0])
    Return($iRC)
EndFunc

This is cycled every 15 seconds. I have tried doing the DllClose() event to, trying to release some handles. This was the code was saying that has been around 10,000 open handles. We use this in the enterprise I work at to see if the box is locked and if it is we then go on to change some DNS settings if they are incorrect...

Edited by MattWise

[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites

You are calling PdhVbOpenQuery many times, yet I don't see you calling PdhCloseQuery, so why shouldn't it leak handles?


"be smart, drink your wine"

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

You are calling PdhVbOpenQuery many times, yet I don't see you calling PdhCloseQuery, so why shouldn't it leak handles?

Just tried doing the PdhCloseQuery and it is still not closing handles. As I said in the above post, user32.dll is doing it also. So I know this isn't just pdh.dll and the way I am calling it. I'm not saying there isn't an issue with the way I am calling user32.dll or pdh.dll, very well could be me. Just trying to verify.

Just in case someone wants to use the same tool I am using for watching the handles its called SystemExplorer

Edited by MattWise

[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites

Dim $QueryHandle = DllStructCreate("long")
Dim $Counter = DllStructCreate("long")
Dim $lData = DllStructCreate("long")
Dim $Percent
Dim $Dll = DllOpen("pdh.dll")

While 1
    Init()
    DllCall($Dll, "long", "PdhCollectQueryData", "long", DllStructGetPtr($QueryHandle))
    $Percent = DllCall($Dll, "double", "PdhVbGetDoubleCounterValue", "long", DllStructGetPtr($Counter), "long", DllStructGetPtr($lData))
    DllCall($Dll, "long", "PdhCloseQuery", "long", DllStructGetData($QueryHandle, 1))
    ConsoleWrite(($Percent[2] - $Percent[1]) / 100 & @CRLF)
    Sleep(500)
WEnd

Func Init()
    DllCall($Dll, "long", "PdhVbOpenQuery", "long", DllStructGetPtr($QueryHandle))
    DllCall($Dll, "long", "PdhVbAddCounter", "long", DllStructGetPtr($QueryHandle), "str", "\Processor(0)\% Processor Time", "long", DllStructGetPtr($Counter))
    DllCall($Dll, "long", "PdhCollectQueryData", "long", DllStructGetPtr($QueryHandle))
    DllCall($Dll, "double", "PdhVbGetDoubleCounterValue", "long", DllStructGetPtr($Counter), "long", DllStructGetPtr($lData))
EndFunc

Func OnAutoItClose()
    If IsDeclared("Dll") And $Dll Then DllClose($Dll)
EndFunc

Doesn't leak for me. Just 1 line with PdhCloseQuery added to your example.

I'm not saying there isn't an issue with the way I am calling user32.dll or pdh.dll, very well could be me.

That's probably the first sensible thing you posted in this topic.

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

In your desktops example, the call which closes desktop handle should be

DllCall("User32.dll", "int", "CloseDesktop", "int", $hDesktop[0]);<-- handle returned by "OpenDesktop"

Why are you trying to pass some boolean value ($iRet[0]) as a handle is beyond me.

With that modification, the leak in your code is stopped.

Edited by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

Thanks, that fixed everything.


[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0