Fixed OSD runs out of resource

Dec 29, 2009
30
0
Atlanta, GA
#1
Version where observed:
TCC 15.00.29 Windows XP [Version 5.1.2600]
TCC Build 29 Windows XP Build 2600 Service Pack 3

Description:
If you use OSD with the /N option and rely on the /C[=n] option to clear the on-screen display before it expires in order to post an updated display, it runs out of some resource (a handle, mutex, or something). On my system, this consistently happens after 90 updates.

How to reproduce:
Run the script shown below (also available as an attached file).
If you don't want to wait on it, comment out the delay.

Code:
@echo off
*setlocal
*unalias *
break on
on errormsg goto cleanup
on break    goto cleanup
unset /q ans

OSD /ID=1 /bottom /left /TIME=2 /N `test     1`
DO i = 2 to 1000
    delay 1
    echo %@FORMATN[5.0,%i]
    OSD /C=1
    OSD /ID=1 /bottom /left /TIME=2 /N `test `%@FORMATN[5.0,%i]
    inkey /w0 %%ans
    if "%ans" != "" LEAVE
ENDDO

:cleanup
on error rem ignore
on break rem ignore
OSD /C=1
quit
 

Attachments

#2
I made the following change to the BTMfile.
Code:
if %@eval[%i %% 20] == 0 echo %@FORMATN[5.0,%i] Workset = %@pstat[%_pid,w]
I see memory use climb steadily (though not at a particularly constant rate as might be expected). I'm on Win7/32 and I get a lot more than 90 iterations. Below, worksets are in KB.
Code:
v:\> failOSD.btm
  20 Workset = 28228
  40 Workset = 28720
  60 Workset = 28792
  80 Workset = 29172
  100 Workset = 29596
  120 Workset = 29752
  140 Workset = 30152
  160 Workset = 30452
  180 Workset = 30724
  200 Workset = 31260
  220 Workset = 31348
  240 Workset = 31656
  260 Workset = 32004
  280 Workset = 32320
  300 Workset = 32532
  320 Workset = 32972
  340 Workset = 33240
  360 Workset = 33452
  380 Workset = 33916
  400 Workset = 33988
  420 Workset = 34304
  440 Workset = 35000
  460 Workset = 35072
  480 Workset = 35136
  500 Workset = 35956
  520 Workset = 36324
  540 Workset = 36496
  560 Workset = 36576
 
Dec 29, 2009
30
0
Atlanta, GA
#3
Interesting.

How many iterations before it fails for you?

Once it has failed for me, any attempt at using the /C flag results in an error.
Attempts to show messages just silently fail and don't display.
I can still issue other commands in that console session, but "exit" just hangs, and stopping a session by closing the tab results in the "Windows cannot end this program" dialog.

Seems to be some kind of memory leak caused by either the /C or /N flags, or by an interaction between the two.

What's odd is that the failure point (at least for me) is VERY consistently 90 iterations regardless of whatever else may be going on in the system.
 
Jan 19, 2011
581
10
Norman, OK
#5
TCC 15.01.40 Windows XP [Version 5.1.2600]
TCC Build 40 Windows XP Build 2600 Service Pack 3

Failed at 93.
 
#6
I sped it up. Aha! ... it finally failed, but like this:
Code:
v:\> failOSD.btm
1000 Workset = 36048
2000 Workset = 51612
3000 Workset = 66264
4000 Workset = 80976
5000 Workset = 95740
6000 Workset = 111748
7000 Workset = 126820
8000 Workset = 141828
9000 Workset = 156400
TCC: (Sys) V:\failOSD.btm [13]  Class already exists.
TCC: (Sys) V:\failOSD.btm [13]  Class already exists.
TCC: (Sys) V:\failOSD.btm [13]  Class already exists.
Line 13 creates the OSD.
 
#7
For what it's worth, I have an ODS plugin that I don't tout since it's now built-in. When used in place of the built-in one, It fares better.
Code:
 1000 Workset = 20376
2000 Workset = 20380
(snip)
99000 Workset = 21080
100000 Workset = 21080
It doesn't do much in deleting an instance of the ODS class ...
Code:
OSD::~OSD()
{
    PostMessage(hwnd, WM_QUIT, 0, 0);
    ReleaseDC(hwnd, hdc);
    DeleteObject(hFont);
    DestroyWindow(hwnd);
    delete [] szText;
    // timers go automatically
    // linked list stuff
    if ( pNext ) pNext->pPrev = pPrev;
    else pLast = pPrev;
    if ( pPrev ) pPrev->pNext = pNext;
    else pFirst = pNext;
}
 

rconn

Administrator
Staff member
May 14, 2008
10,588
97
#8
Description:
If you use OSD with the /N option and rely on the /C[=n] option to clear the on-screen display before it expires in order to post an updated display, it runs out of some resource (a handle, mutex, or something). On my system, this consistently happens after 90 updates.
Not reproducible here -- I ran it 5,000 times without a failure (Windows 7 x64). I'll try it in an XP box; it could be a XP-specific problem.

(The current version is 15.01.41; you might want to update.)
 
Dec 29, 2009
30
0
Atlanta, GA
#9
Got the update (thanks for reminding me!) -- but it still fails at the same number of iterations.
For me, it fails on the OSD /C=1 line.
For Vince (on Win7/32) it fails on the OSD /ID=1 line at a much later number of iterations.

32 bit problem?
 
#10
Got the update (thanks for reminding me!) -- but it still fails at the same number of iterations.
For me, it fails on the OSD /C=1 line.
For Vince (on Win7/32) it fails on the OSD /ID=1 line at a much later number of iterations.
And there's pretty clearly a memory leak of about 15KB per OSD.
 
Dec 29, 2009
30
0
Atlanta, GA
#11
Decided to do some unscientific reversion testing at my end.
Revised the .BTM so it can work with earlier versions of TakeCommand.
File is attached for your convenience.

Fails for me on versions 13 and 11, but in different places.
Line #13 is the OSD /C line.

In version 13:
TCC 13.04.63 Windows XP [Version 5.1.2600]​
TCC Build 63 Windows XP Build 2600 Service Pack 3​
Code:
  .
  .
  91
  92
C:\JTB\TCmd_v13\failOSDv13.btm [13]  Usage : OSD [/C /FONT=n /N /POS=n,n /RGB=r,g,b /TIME=n /TOP /LEFT /BOTTOM /RIGHT /HCENTER /VCENTER /V] text
 
▓▒░ C:\JTB\TCmd_v13 ▓▒░
p6100 (sh0) 13:02:33 #3>
In version 11:
TCC 11.00.52 Windows XP [Version 5.1.2600]​
TCC Build 52 Windows XP Build 2600 Service Pack 3​
Code:
  .
  .
  . 
  194
  195
C:\JTB\TCmd_v13\failOSDv13.btm [13]  Usage : OSD [/C /FONT=n /N /POS=n,n /RGB=r,g,b /TIME=n /TOP /LEFT /BOTTOM /RIGHT /HCENTER /VCENTER /V] text
 
▓▒░ C:\JTB\TCmd_v11 ▓▒░
p5920 (sh0) 12:48:15 #2>
The next oldest version that I could find in short order was really ancient, version 8! It doesn't have the /C flag, so it really isn't a true regression test.

Hope this helps!
--- forbin (johnb in atlanta)
 

Attachments

#14
When I test with this BTM,
Code:
echo Workset=%_workset
do forever
    osd /id=1 /n foo
    osd /c=1
    echo %_do_loop^tWorkSet = %_workset
enddo
TCC's working set increases (gradually) about 11 MB over the first 100 iterations and thereafter remains pretty stable (see below). Is that expected behavior?
Code:
Workset=19705856
1      WorkSet = 20246528
2      WorkSet = 20422656
3      WorkSet = 20533248
4      WorkSet = 20643840
5      WorkSet = 20770816
6      WorkSet = 20893696
7      WorkSet = 21024768
8      WorkSet = 21147648
9      WorkSet = 21270528
10      WorkSet = 21393408
(SNIP)
91      WorkSet = 31371264
92      WorkSet = 31371264
93      WorkSet = 31371264
94      WorkSet = 31383552
95      WorkSet = 31387648
96      WorkSet = 31424512
97      WorkSet = 31424512
98      WorkSet = 31424512
99      WorkSet = 31424512
100    WorkSet = 31424512
(SNIP)
5111    WorkSet = 31424512
5112    WorkSet = 31428608
5113    WorkSet = 31424512
5114    WorkSet = 31424512
5115    WorkSet = 31424512
5116    WorkSet = 31424512
5117    WorkSet = 31424512
5118    WorkSet = 31424512
5119    WorkSet = 31424512
5120    WorkSet = 31428608
I'm up to about 7000 now and there's little change.
 

rconn

Administrator
Staff member
May 14, 2008
10,588
97
#15
Not reproducible with Windows 7 x64, but I'm not surprised (or worried) about it. OSD has to create the font, which is going to use some (varying) amount of memory. There is definitely *not* a leak in the OSD code (as you can see with the repeated runs), but Windows likes to cache resources for future use.
 
Dec 29, 2009
30
0
Atlanta, GA
#16
This is a Windows x86 bug; I've worked around it for 15.01.42 (already uploaded).
Not surprising... I've rarely seen an actual flaw in Take Command or its predecessors. Thanks for the very rapid response!

BTW, I'd like to suggest that in future versions, the OSD /C[=#] option should just fail silently if there is nothing being displayed, since the visual result would be the same after clearing. If there's a reason for having the error generated, then how about allowing OSD /C[=#] /Q specify the silent option?