I have a Perl Tk GUI application that sometimes crashes after it exceeds 4GB of RAM usage. I can exceed 4GB of RAM usage in some cases using Perl Tk, and I have no issues exceeding 4GB when running tests in a console application.
- Operating system: Microsoft Windows [Version 10.0.19044.2006]
- Perl version: v5.30.3
- Tk version: 804.036 (latest available on CPAN)
Perl spits out this error almost every time it crashes, but sometimes it crashes without an error:
Free to wrong pool 678ea0 not e228dd0 at .\common\GUI_TESTS\test_memory_hog_gui.pl line 41.
When searching for this error, everything I could find was multi-threading related, and our application does not use multi-threading.
I thought it may be because we have something configured as 32-bit instead of 64-bit, so I followed the instructions in this question and found that everything is configured as 64-bit.
perl -V:ivsize # ivsize='8';
perl -V:ptrsize # ptrsize='8';
perl -V:archname # archname='MSWin32-x64-multi-thread';
Below is an example GUI application that crashes after the memory exceeds 4GB. I have boiled this down from our application and the crashing behavior is the same. The data structure that we use is obviously much larger, so I am cloning a simplified version of ours many times to pass the 4GB threshold.
use strict;
use warnings;
use Tk;
use Tk::LabFrame;
use Clone;
my $MAIN_WINDOW = MainWindow->new;
$MAIN_WINDOW->minsize(400, 400);
my @dataStructureClones = ();
my $textBox;
my $button_frame = $MAIN_WINDOW->LabFrame(-label => "Test", -relief => 'groove', -borderwidth => 2)->pack();
$button_frame->Button(
-text => 'Run Crashing Operation',
-command => sub {
my $dataStructureThatCrashes = {
NETLIST_INFO => {
EXTRA_PROPERTIES => {
C_SIGNAL => {},
NET => {},
},
NET_LIST => [
# omitting this call will allow the program to exceed 4GB until after it finishes the loop
{ NL_INDEX => 0, }
]
},
};
my $lastUpdate = time();
push @dataStructureClones, $dataStructureThatCrashes;
for (1 .. 5000000) {
if (time() - $lastUpdate > 1) {
# omitting this call will allow the program to exceed 4GB
$textBox->insert("end", "Cloning hash ($_)...\n");
$MAIN_WINDOW->update();
$lastUpdate = time();
}
push @dataStructureClones, Clone::clone($dataStructureThatCrashes);
}
}
)->grid(-row => 0, -column => 0);
$textBox = $MAIN_WINDOW->Scrolled(
'Text',
-relief => 'groove',
-background => 'light grey',
-foreground => 'black',
-wrap => 'char',
-scrollbars => 'osoe',
-width => 110,
-height => 24,
)->pack(-side => 'top', -fill => 'both', -expand => 1);
MainLoop;
Things to note:
- Commenting out line 28 makes the program run properly.
- Commenting out line 38 makes the cloning loop finish executing, but then it crashes with a similar error about 15 seconds after the cloning has finished.
The similar error:
Free to wrong pool 1008ea0 not fcedf7a8 at C:/Strawberry/perl/site/lib/Tk.pm line 424.
I tried this on a Linux VM that we have (CentOS 7) and the issue does not happen.
perl
+perltk
. So the problem might be with window'sperl
/perltk
. I have no idea howperl
works but is it possible thatperltk
is 32 bit even ifperl
itself is 64 bit? I think that might cause the same issue. – ChivyVMMap
. This for 99% caused by 32bit limit of some kind. You use the Process Explorer also from sysinternals to see what is actually running. – Stringer