From 5c0a7502b239c7daaef2244487a22764efbd46be Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 Nov 2025 23:24:42 +0100 Subject: [PATCH] memanalyze.pl: implement "strict" mode, warn on alloc after limit In order to better track down cases where we don't exit cleanly and directly on OOM errors, this mode warns if there is another memory operation found *after* the torture limit was reached. runtests sets this strict mode. --- tests/memanalyze.pl | 44 ++++++++++++++++++++++++++++++++++++++------ tests/runtests.pl | 2 +- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/tests/memanalyze.pl b/tests/memanalyze.pl index f0ebd7fbaf..7e3d560e10 100755 --- a/tests/memanalyze.pl +++ b/tests/memanalyze.pl @@ -43,6 +43,7 @@ my $recvs=0; my $sockets=0; my $verbose=0; my $trace=0; +my $strict=0; while(@ARGV) { if($ARGV[0] eq "-v") { @@ -53,6 +54,10 @@ while(@ARGV) { $trace=1; shift @ARGV; } + elsif($ARGV[0] eq "-s") { + $strict=1; + shift @ARGV; + } elsif($ARGV[0] eq "-l") { # only show what alloc that caused a memlimit failure $showlimit=1; @@ -79,10 +84,11 @@ my $file = $ARGV[0] || ''; if(! -f $file) { print "Usage: memanalyze.pl [options] \n", - "Options:\n", - " -l memlimit failure displayed\n", - " -v Verbose\n", - " -t Trace\n"; + "Options:\n", + " -l memlimit failure displayed\n", + " -v Verbose\n", + " -s Strict - warn on mallocs after memlimit is reached\n", + " -t Trace\n"; exit; } @@ -124,6 +130,7 @@ my $addrinfos = 0; my $source; my $linenum; my $function; +my $memwarn = 0; my $lnum = 0; while(<$fileh>) { @@ -134,8 +141,13 @@ while(<$fileh>) { # new memory limit test prefix my $i = $3; my ($source, $linenum) = ($1, $2); - if($trace && ($i =~ /([^ ]*) reached memlimit/)) { - print "LIMIT: $1 returned error at $source:$linenum\n"; + if($i =~ /([^ ]*) reached memlimit/) { + if($trace) { + print "LIMIT: $1 returned error at $source:$linenum\n"; + } + if($strict) { + $memwarn=1; + } } } elsif($line =~ /^MEM ([^ ]*):(\d*) (.*)/) { @@ -175,6 +187,10 @@ while(<$fileh>) { $size = $1; $addr = $2; + if($memwarn) { + print "WARN:$source:$linenum malloc($size) after limit\n", + } + if($sizeataddr{$addr} && $sizeataddr{$addr}>0) { # this means weeeeeirdo print "Mixed debug compile ($source:$linenum at line $lnum), rebuild curl now\n"; @@ -202,6 +218,10 @@ while(<$fileh>) { my $arg1 = $1; my $arg2 = $2; + if($memwarn) { + print "WARN:$source:$linenum calloc($size) after limit\n", + } + if($sizeataddr{$addr} && $sizeataddr{$addr}>0) { # this means weeeeeirdo print "Mixed debug compile, rebuild curl now\n"; @@ -224,6 +244,10 @@ while(<$fileh>) { elsif($function =~ /realloc\((\(nil\)|0x([0-9a-f]*)), (\d*)\) = 0x([0-9a-f]*)/) { my ($oldaddr, $newsize, $newaddr) = ($2, $3, $4); + if($memwarn) { + print "WARN:$source:$linenum realloc($size) after limit\n", + } + if($oldaddr) { my $oldsize = $sizeataddr{$oldaddr} ? $sizeataddr{$oldaddr} : 0; @@ -261,6 +285,10 @@ while(<$fileh>) { $totalmem += $size; $memsum += $size; + if($memwarn) { + print "WARN:$source:$linenum strdup() after limit\n", + } + if($trace) { printf("STRDUP: $size bytes at %s, makes totally: %d bytes\n", $getmem{$addr}, $totalmem); @@ -281,6 +309,10 @@ while(<$fileh>) { $totalmem += $size; $memsum += $size; + if($memwarn) { + print "WARN:$source:$linenum wcsdup() after limit\n", + } + if($trace) { printf("WCSDUP: $size bytes at %s, makes totally: %d bytes\n", $getmem{$addr}, $totalmem); diff --git a/tests/runtests.pl b/tests/runtests.pl index 226573941d..1f15c0f5dd 100755 --- a/tests/runtests.pl +++ b/tests/runtests.pl @@ -1759,7 +1759,7 @@ sub singletest_check { $ok .= "-"; # problem with memory checking } else { - my @memdata=`$memanalyze "$logdir/$MEMDUMP"`; + my @memdata=`$memanalyze -s "$logdir/$MEMDUMP"`; my $leak=0; for(@memdata) { if($_ ne "") {