WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Terminal Server

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Memory leak in wtsQuerySessionInfo


Question:

I am writing a service using WinBatch that potentially calls the "wtsQuerySessionInfo" function in the Terminal Services extender many, many times. If this condition occurs for several days (very likely based on the way my program is designed), I have seen virtual memory used by my program increase to as much as 700 MB (before I killed it)!!!

The "wtsQuerySessionInfo" function appears to be the WinBatch equivalent of the similarly named Win32 API function "WTSQuerySessionInformation". If that specific Win32 API function is indeed the function being called (as I suspect), then the additional Win32 API function "WTSFreeMemory" also needs to be called to free the memory allocated by the "WTSQuerySessionInformation" Win32 API function once the data is extracted. This is the likely source of the memory leak within this WinBatch function.

Sample code demonstrating this condition follows and is easiest viewed using Performance Monitor and monitoring this process (a compiled .EXE for me) for "Page File Bytes". I was told to request assistance on this BBS as the author of the Terminal Services extender would see my message fastest here. To that end, just so he/she knows what's up, I'm using the latest version of WinBatch (2004D) and the latest version of the Terminal Services extender (38008).

#definesubroutine GetConsoleUserName()
ConsoleUserName = ""
if !wtsIsTSEnabled(1) then return
ActiveConsoleSessionID = wtsGetActiveConsoleSessId()
if ActiveConsoleSessionID < 0 then return
PreviousErrorMode = ErrorMode(@OFF)
LastError()
SessionInfo = wtsQuerySessionInfo("",ActiveConsoleSessionID)
ErrorMode(PreviousErrorMode)
if LastError() then return
ConsoleUserName = StrCat(StrTrim(StrUpper(SessionInfo[13])),"\",StrTrim(StrUpper(SessionInfo[14])))
if ConsoleUserName == "\" then ConsoleUserName = ""
#endsubroutine

AddExtender("WWWTS34I.DLL")

while @TRUE
GetConsoleUserName()
BoxOpen("TEST.EXE","ConsoleUserName: %ConsoleUserName%")
TimeDelay(1)
endwhile 

Answer:

I'll look into it. Yes, WTSFreeMemory() is being called in all cases where it needs to be called, but there's some other memory allocation that goes on w/respect to allocating strings & arrays for the return value of the function. There might be a stray string value that is not being deallocated at some point.

Please confirm what version of Windows you are running the script on. That will help me to prioritize the order of the tests on different versions of windows that the WTS extender runs on. Right now, that includes WinNT v4.0 TSE, Win2K Server/Adv.Server w/TS installed in remote admin or application server mode, WinXP w/FUS enabled and Win2K3 [intrinsically enabled].

Note: Current rumors have it that there is a fundamental memory handling issue that required the 34I version of the extender to be somewhat re-written to become a 44I version. This may extend the time it takes to fix the problem significantly.

User Reply:

I'm writing the script on Windows Server 2003 using remote admin mode and I'm testing the script on that OS as well as Windows XP. Both computers are joined to the same domain, so with respect to Windows XP, in my case FUS doesn't apply.

BTW, I also found another memory leak. If you repeatedly call the "wtsIsTSEnabled" Terminal Services extender function, it, too, leaks considerable "regular" (private) memory when monitored with Performance Monitor, not page file memory like the other headache I gave you.

I'm no longer in any kind of rush on this. I've programmed around it for now using DLL calls to the terminal services API directly. Just FYI. I'll periodically check for a new TS extender, though, but no hurry.

Answer:

Turns out there is an underlying problem with the extender interface for passing arrays back from an extender when using the 34I interface specs, and that's where the main memory leak is occurring. *Any* extender function that returns an array that has elements in it that contain string values [allocated from the heap] will cause a memory leak. The updated 44I interface specs eliminate that problem, but it is requiring that the entire extender be converted to use the new specs. In particular, every one of the extender functions that returns an array has to have its code modified & then tested to confirm that it is working properly.

I just looked in on wtsIsTSEnabled(), and it doesn't allocate any memory at all. All it does is return the value of existing global variables that get their values assigned when the extender is initializing itself. I would find it very difficult to believe that wtsIsTSEnabled() could cause any sort of memory leak at all since every variable value that it uses is either static global or is located on the stack.

Have you run it in a tight loop

while(@TRUE)
result = wtsIsTSEnabled(0)
if (IsKeyDown(@SHIFT+@CTRL)) then break
endwhile
to test for certain that a memory leak is occurring while the loop is being executed?

I'll run that test myself, too, but looking at the code I just don't see where a leak could happen - the code is too straight forward and simple to be leaking.

Update:

An FYI update on the memory leak issue....

The update to the 44I interface specs eliminated *one* memory leak issue involving arrays with string elements being allocated in an extender & returned to a script. However, once that problem was resolved further testing showed that there was still some sort of memory leak occurring.

Further testing has shown that WTSQuerySessionInformation(), which is the underlying Win32 API function that gets session information, is actually leaking memory when certain session information items are being requested for session #0 [the console session]. The exact same function call asking for the exact same information from any other session # does not result in the memory leak, and the Win32 Platform SDK docs do not specifically call out any known issues with requesting these information items for the console session.

So far, these testing results are all on Win2K3. Now I need to go back and test on Win2K Server, WinXP Pro and WinNT v4.0 TSE to see if the problem is consistent across all versions of Windows that support terminal services or if it is only occurs on specific versions of Windows.


Article ID:   W16363
File Created: 2005:02:18:12:20:04
Last Updated: 2005:02:18:12:20:04