Home > Archive > PerlTk > August 2004 > Tk afterIdle memory leak
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Tk afterIdle memory leak
|
|
| Jason Adams 2004-08-25, 3:57 pm |
| This is a multi-part message in MIME format.
--------------020005080805070607090501
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
I found a memory leak related $widget->afterIdle() in Tk-804.027. Though
I can't manage to figure out why. The leak does not seem to occur with
normal $widget->after(). Again no real clue as to why, so I've decided
to pass it off and see if anyone else has any ideas.
On with the details. I've attached 2 programs. 'test2.pl' is a small
script which illustrates the bug. 'autoDebug.pl' runs gdb on Debian's
debugperl running test2.pl. BTW test2.pl quits after 1200 iterations so
it's hard to see if you just run it. If you break it so it doesn't quit
then the leak is obvious with either top or the windows process manager.
'autoDebug.pl' spews a lot of stuff so I processed it's output to get a
rough count of how many unfreed allocations there are of which sizes.
jadams@fuzball:~$ ./autoDebug.pl | tee alloclog.txt
< a bunch of stuff skipped >
jadams@fuzball:~$ grep Size alloclog.txt | sort | uniq -c | sort -n
1 Size: 1
1 Size: 496
1 Size: 6
1 Size: 64
2 Size: 32
5 Size: 14
6 Size: 13
6 Size: 9
10 Size: 11
10 Size: 281
25 Size: 8
40 Size: 992
41 Size: 48
41 Size: 52
58 Size: 24
151 Size: 968
195 Size: 1008
Allocations of 968 byte chunks always seem to have back traces that loot
like.
Size: 968
#0 0x080ec436 in S_more_xpvav (my_perl=0x81aa008) at sv.c:977
#1 0x080ec3e6 in S_new_xpvav (my_perl=0x81aa008) at sv.c:952
#2 0x080ece4e in Perl_sv_upgrade (my_perl=0x81aa008, sv=0x8495ed8,
mt=10) at sv.c:1454
#3 0x080dbbd8 in Perl_av_make (my_perl=0x81aa008, size=5,
strp=0x82aa884) at av.c:382
#4 0x0811a72b in Perl_pp_anonlist (my_perl=0x81aa008) at pp.c:3994
#5 0x080c4c9f in Perl_runops_debug (my_perl=0x81aa008) at dump.c:1442
#6 0x080666ed in S_call_body (my_perl=0x81aa008, myop=0xbffff210,
is_eval=0) at perl.c:2285
#7 0x08066242 in Perl_call_sv (my_perl=0x81aa008, sv=0x8371d38,
flags=4) at perl.c:2203
#8 0x401f401c in LangCallCallback (sv=0x8495da0, flags=4) at
pTkCallback.c:200
#9 0x401ed87e in XS_Tk__Callback_Call (my_perl=0x81aa008, cv=0x820ec08)
at Event.xs:1171
#10 0x080e9cf8 in Perl_pp_entersub (my_perl=0x81aa008) at pp_hot.c:2854
#11 0x080c4c9f in Perl_runops_debug (my_perl=0x81aa008) at dump.c:1442
#12 0x080666ed in S_call_body (my_perl=0x81aa008, myop=0xbffff520,
is_eval=0) at perl.c:2285
#13 0x08066242 in Perl_call_sv (my_perl=0x81aa008, sv=0x841a648,
flags=70) at perl.c:2203
#14 0x08065b00 in Perl_call_method (my_perl=0x81aa008,
methname=0x8496268 "once", flags=6) at perl.c:2097
#15 0x401f40e2 in LangCallCallback (sv=0x8495e9c, flags=6) at
pTkCallback.c:210
#16 0x4023c8aa in LangDoCallback (interp=0x81c12dc, sv=0x8495e9c,
result=0, argc=0) at tkGlue.c:1948
#17 0x40251334 in AfterProc () from /usr/local/lib/perl/5.8.4/auto/Tk/Tk.so
#18 0x401f6e63 in TclServiceIdle () at tclTimer.c:723
#19 0x401f5a1f in Tcl_DoOneEvent (flags=34) at tclNotify.c:948
#20 0x4026f4ef in MapFrame () from /usr/local/lib/perl/5.8.4/auto/Tk/Tk.so
#21 0x401f6e63 in TclServiceIdle () at tclTimer.c:723
#22 0x401f5a1f in Tcl_DoOneEvent (flags=-3) at tclNotify.c:948
#23 0x4022f9f0 in XS_Tk_DoOneEvent (my_perl=0x81aa008, cv=0x82dcb70) at
Tk.xs:1063
#24 0x080e9cf8 in Perl_pp_entersub (my_perl=0x81aa008) at pp_hot.c:2854
#25 0x080c4c9f in Perl_runops_debug (my_perl=0x81aa008) at dump.c:1442
#26 0x080656b8 in S_run_body (my_perl=0x81aa008, oldscope=1) at perl.c:1916
#27 0x0806513b in perl_run (my_perl=0x81aa008) at perl.c:1840
#28 0x0805fd98 in main (argc=2, argv=0xbffffa64, env=0xbffffa70) at
perlmain.c:86
Allocations of size 1008 seem to be all over the board :-(.
It's seems to be somewhat independent of which version of Perl I run.
I've used ActiveState's Perl 5.8.4 , a hand compiled 5.8.5 on Windows
2k, and Debian Sarge's normal and debugging versions. However I know it
doesn't occur with Tk 800.025-2 in Debian Sarge.
jadams@fuzball:~$ apt-cache policy perl perl-debug
perl:
Installed: 5.8.4-2
Candidate: 5.8.4-2
Version Table:
*** 5.8.4-2 0
990 http://http.us.debian.org sarge/main Packages
500 http://http.us.debian.org sid/main Packages
100 /var/lib/dpkg/status
5.6.1-8.7 0
500 http://security.debian.org woody/updates/main Packages
5.6.1-8.3 0
500 http://http.us.debian.org woody/main Packages
perl-debug:
Installed: 5.8.4-2
Candidate: 5.8.4-2
Version Table:
*** 5.8.4-2 0
990 http://http.us.debian.org sarge/main Packages
500 http://http.us.debian.org sid/main Packages
100 /var/lib/dpkg/status
5.6.1-8.7 0
500 http://security.debian.org woody/updates/main Packages
5.6.1-8.3 0
500 http://http.us.debian.org woody/main Packages
You have new mail in /var/mail/jadams
jadams@fuzball:~$
Jason Adams
--------------020005080805070607090501
Content-Type: application/x-perl;
name="test2.pl"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="test2.pl"
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
my($pause)=1;
my($count)=0;
my($win)=MainWindow->new();
$win->Button(
-text => "Quit",
-command => sub {
$win->destroy();
}
)->pack;
tick();
sub tick {
#print "tick $count\r";
warn "Trigger debugger\n" if(!$count);
$count++;
if($count < 1200) {
$win->afterIdle(\&tick);
} else {
$win->destroy();
}
}
MainLoop;
--------------020005080805070607090501
Content-Type: application/x-perl;
name="autoDebug.pl"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="autoDebug.pl"
#!/usr/bin/perl
#
use warnings;
use strict;
use Devel::GDB;
my $gdb = Devel::GDB->new(-file => '/usr/bin/debugperl');
my($res);
$res=$gdb->get('break Perl_warn');
#print($res);
$res=$gdb->get('run test2.pl');
$res=$gdb->get('break Perl_safesysmalloc');
$res=$gdb->get('break Perl_safesysfree');
#print($res);
my($bt);
my($tmp);
my($addr);
my($size);
my(%allocs);
do {
$res=$gdb->get('cont');
$res=~s/[\s\n\r]+/ /g;
if($res=~/Perl_safesysmalloc/) {
#print "Alloc\n";
($size)=$res=~/size=([x\da-f]+)/;
$tmp=$gdb->get('finish');
if($tmp=~/Value returned is \$\d+ = \(void \*\) ([x\da-f]+)/) {
$addr=$1;
$bt=$gdb->get('bt');
$allocs{$addr}="Size: $size\n".$bt;
print "Allocated $addr $size\n";
}
}elsif($res=~/Perl_safesysfree/) {
($addr)=$res=~/where=([x\da-f]+)/;
warn "not allocated $addr\t$res\n" unless(exists($allocs{$addr}));
delete $allocs{$addr};
print "Freed $addr\n";
} else {
}
}while($res!~/exited/);
$res=$gdb->get('quit');
print("$res");
print "\n\nMISSES\n\n";
foreach (values %allocs) {
print;
print "\n";
}
--------------020005080805070607090501--
-++**==--++**==--++**==--++**==--++**==--++**==--++**==
This message was posted through the Stanford campus mailing list
server. If you wish to unsubscribe from this mailing list, send the
message body of "unsubscribe ptk" to majordomo@lists.stanford.edu
| |
| Nick Ing-Simmons 2004-08-26, 4:01 pm |
| Jason Adams <jadams@nyscul.org> writes:
>I found a memory leak related $widget->afterIdle() in Tk-804.027. Though
>I can't manage to figure out why. The leak does not seem to occur with
>normal $widget->after(). Again no real clue as to why, so I've decided
>to pass it off and see if anyone else has any ideas.
>
>On with the details. I've attached 2 programs. 'test2.pl' is a small
>script which illustrates the bug. 'autoDebug.pl' runs gdb on Debian's
>debugperl running test2.pl. BTW test2.pl quits after 1200 iterations so
>it's hard to see if you just run it. If you break it so it doesn't quit
>then the leak is obvious with either top or the windows process manager.
sub tick
{
...
$w->afterIdle(\&tick);
}
One upon a time \&subname as a callback leaked, but [\&subname] didn't.
In theory former is now turned to latter internally.
Does changing code to
$w->afterIdle([\&tick]);
fix (or rather avoid) the problem?
-++**==--++**==--++**==--++**==--++**==--++**==--++**==
This message was posted through the Stanford campus mailing list
server. If you wish to unsubscribe from this mailing list, send the
message body of "unsubscribe ptk" to majordomo@lists.stanford.edu
| |
| Jason Adams 2004-08-26, 4:01 pm |
| No it still leaks at about the same rate.
>sub tick
>{
> ...
> $w->afterIdle(\&tick);
>}
>
>One upon a time \&subname as a callback leaked, but [\&subname] didn't.
>In theory former is now turned to latter internally.
>Does changing code to
>
>
> $w->afterIdle([\&tick]);
>
>fix (or rather avoid) the problem?
>
>
-++**==--++**==--++**==--++**==--++**==--++**==--++**==
This message was posted through the Stanford campus mailing list
server. If you wish to unsubscribe from this mailing list, send the
message body of "unsubscribe ptk" to majordomo@lists.stanford.edu
|
|
|
|
|