Author: njn Date: 2007-09-21 06:05:45 +0100 (Fri, 21 Sep 2007) New Revision: 6886
Log: Handle zero size snapshots better throughout. Added a couple of test cases for them. Added: branches/MASSIF2/massif/tests/zero.c branches/MASSIF2/massif/tests/zero1.post.exp branches/MASSIF2/massif/tests/zero1.stderr.exp branches/MASSIF2/massif/tests/zero1.vgtest branches/MASSIF2/massif/tests/zero2.post.exp branches/MASSIF2/massif/tests/zero2.stderr.exp branches/MASSIF2/massif/tests/zero2.vgtest Modified: branches/MASSIF2/massif/ms_main.c branches/MASSIF2/massif/ms_print branches/MASSIF2/massif/tests/Makefile.am Modified: branches/MASSIF2/massif/ms_main.c =================================================================== --- branches/MASSIF2/massif/ms_main.c 2007-09-21 04:33:36 UTC (rev 6885) +++ branches/MASSIF2/massif/ms_main.c 2007-09-21 05:05:45 UTC (rev 6886) @@ -1245,6 +1245,7 @@ } VG_(HT_add_node)(malloc_list, hc); + // Do a snapshot! take_snapshot(" alloc"); return p; @@ -1490,14 +1491,18 @@ return mbuf; } -// Does the xpt account for >= 1% of total memory used? +// Does the xpt account for >= 1% (or so) of total memory used? static Bool is_significant_XPt(XPt* xpt, SizeT curr_total_szB) { // clo_threshold is measured in hundredths of a percent of total size, // ie. 10,000ths of total size. So clo_threshold=100 means that the - // threshold is 1% of total size. + // threshold is 1% of total size. If curr_total_szB is zero, we consider + // every XPt significant. We also always consider the alloc_xpt to be + // significant. tl_assert(xpt->curr_szB <= curr_total_szB); - return (xpt->curr_szB * 10000 / curr_total_szB >= clo_threshold); + return xpt == alloc_xpt || 0 == clo_threshold + (0 != curr_total_szB && + xpt->curr_szB * 10000 / curr_total_szB >= clo_threshold); } static void pp_snapshot_XPt(Int fd, XPt* xpt, Int depth, Char* depth_str, Modified: branches/MASSIF2/massif/ms_print =================================================================== --- branches/MASSIF2/massif/ms_print 2007-09-21 04:33:36 UTC (rev 6885) +++ branches/MASSIF2/massif/ms_print 2007-09-21 05:05:45 UTC (rev 6886) @@ -77,6 +77,13 @@ my $fancy = '-' x 80; my $fancy_nl = $fancy . "\n"; +# Returns 0 if the denominator is 0. +sub safe_div_0($$) +{ + my ($x, $y) = @_; + return ($y ? $x / $y : 0); +} + #----------------------------------------------------------------------------- # Argument and option handling #----------------------------------------------------------------------------- @@ -148,31 +155,36 @@ return equals_num_line($line, $fieldname); } -sub is_significant_XPt($$) +sub is_significant_XPt($$$) { - my ($xpt_szB, $total_szB) = @_; + my ($is_top_node, $xpt_szB, $total_szB) = @_; ($xpt_szB <= $total_szB) or die; - return ( $xpt_szB * 100 / $total_szB >= $threshold ? 1 : 0 ); + # Nb: we always consider the alloc-XPt significant, even if the size is + # zero. + return $is_top_node || 0 == $threshold || + ( $total_szB != 0 && $xpt_szB * 100 / $total_szB >= $threshold ); } # Forward declaration, because it's recursive. -sub read_heap_tree($$$$$); +sub read_heap_tree($$$$$$); # Return pair: if the tree was significant, both are zero. If it was # insignificant, the first element is 1 and the second is the number of # bytes. -sub read_heap_tree($$$$$) +sub read_heap_tree($$$$$$) { # Read the line and determine if it is significant. - my ($print, $this_prefix, $child_midfix, $arrow, $mem_total_B) = @_; + my ($print, $is_top_node, $this_prefix, $child_midfix, $arrow, + $mem_total_B) = @_; my $line = get_line(); (defined $line and $line =~ /^\s*n(\d+):\s*(\d+)(.*)$/) or die("Line $.: expected a tree node line, got:\n$line\n"); my $n_children = $1; my $bytes = $2; my $details = $3; - my $perc = 100 * $bytes / $mem_total_B; - my $is_significant = is_significant_XPt($bytes, $mem_total_B); + my $perc = safe_div_0(100 * $bytes, $mem_total_B); + # Nb: we always print the alloc-XPt, even if its size is zero. + my $is_significant = is_significant_XPt($is_top_node, $bytes, $mem_total_B); # We precede this node's line with "$this_prefix.$arrow". We precede # any children of this node with "$this_prefix$child_midfix$arrow". @@ -190,7 +202,8 @@ # If child is the last sibling, the midfix is empty. my $child_midfix2 = ( $i+1 == $n_children ? " " : "| " ); my ($is_child_insignificant, $child_insig_bytes) = - read_heap_tree($print, $this_prefix2, $child_midfix2, "->", + # '0' means it's not the top node of the tree. + read_heap_tree($print, 0, $this_prefix2, $child_midfix2, "->", $mem_total_B); $n_insig_children += $is_child_insignificant; $total_insig_children_szB += $child_insig_bytes; @@ -200,7 +213,7 @@ # If this was significant but any children were insignificant, print # the "in N places" line for them. if ($print && $n_insig_children > 0) { - $perc = 100 * $total_insig_children_szB / $mem_total_B; + $perc = safe_div_0(100 * $total_insig_children_szB, $mem_total_B); printf("%s->%05.2f%% (%dB) in %d+ places, all below " . "ms_print's threshold (%05.2f%%)\n", $this_prefix2, $perc, $total_insig_children_szB, @@ -277,8 +290,9 @@ if ($heap_tree eq "empty") { # do nothing } elsif ($heap_tree eq "...") { - # Depth in the heap tree. '0' means the tree should not be printed. - read_heap_tree(0, "", "", "", $mem_total_B); + # Depth in the heap tree. '0' means the tree should not be + # printed. '1' means it's the top node of the tree. + read_heap_tree(0, 1, "", "", "", $mem_total_B); } else { die("Line $.: expected 'empty' or '...' after 'heap_tree='\n"); } @@ -337,9 +351,6 @@ } } - my $detailed_char = '@'; - my $normal_char = ':'; - # Write snapshot bars into graph[][]. # # Each row represents K bytes, which is 1/GRAPH_Yth of the peak size @@ -362,7 +373,9 @@ my $normal_full_char = ':'; my $half_char = '.'; - # Work out how many bytes each row represents. + # Work out how many bytes each row represents. If the peak size was 0, + # make it 1 so that the Y-axis covers a non-zero range of values. + if (0 == $peak_mem_total_szB) { $peak_mem_total_szB = 1; } my $K = $peak_mem_total_szB / $GRAPH_Y; for (my $i = 0; $i < $n_snapshots; $i++) { @@ -376,14 +389,13 @@ # want to overwrite detailed snapshot's bars with non-detailed # snapshot's bars. my $should_draw_column = - ($is_detaileds[$i] or $graph[$x][0] ne $detailed_char - ? 1 : 0); + ($is_detaileds[$i] or $graph[$x][0] ne $detailed_full_char); if ($should_draw_column) { # If it's detailed, mark the X-axis. Also choose the full-slot # char. my $full_char; if ($is_detaileds[$i]) { - $graph[$x][0] = $detailed_char; + $graph[$x][0] = $detailed_full_char; $full_char = $detailed_full_char; } else { $full_char = $normal_full_char; @@ -533,8 +545,9 @@ # do nothing } elsif ($heap_tree eq "...") { # Depth in the heap tree. '1' means the tree should be printed. - # Then reprint the header. - read_heap_tree(1, "", "", "", $mem_total_B); + # '1' means it's the top node of the tree. Then reprint the + # header. + read_heap_tree(1, 1, "", "", "", $mem_total_B); # XXX: don't print the header if there are no more snapshots! # (see tests/thresholds.c for an example) print($header); Modified: branches/MASSIF2/massif/tests/Makefile.am =================================================================== --- branches/MASSIF2/massif/tests/Makefile.am 2007-09-21 04:33:36 UTC (rev 6885) +++ branches/MASSIF2/massif/tests/Makefile.am 2007-09-21 05:05:45 UTC (rev 6886) @@ -17,7 +17,9 @@ thresholds_5_0.post.exp thresholds_5_0.stderr.exp thresholds_5_0.vgtest \ thresholds_5_10.post.exp thresholds_5_10.stderr.exp thresholds_5_10.vgtest \ thresholds_10_10.post.exp thresholds_10_10.stderr.exp thresholds_10_10.vgtest \ - toobig-allocs.stderr.exp toobig-allocs.vgtest + toobig-allocs.stderr.exp toobig-allocs.vgtest \ + zero1.post.exp zero1.stderr.exp zero1.vgtest + zero2.post.exp zero2.stderr.exp zero2.vgtest AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g $(AM_FLAG_M3264_PRI) @@ -25,6 +27,7 @@ alloc-fns \ basic \ basic_malloc \ - culling1 culling2 - thresholds + culling1 culling2 \ + thresholds \ + zero Added: branches/MASSIF2/massif/tests/zero.c =================================================================== --- branches/MASSIF2/massif/tests/zero.c (rev 0) +++ branches/MASSIF2/massif/tests/zero.c 2007-09-21 05:05:45 UTC (rev 6886) @@ -0,0 +1,19 @@ +// Test zero-size allocations -- shouldn't cause division by zero, that kind +// of thing. + +#include <stdlib.h> + +int main(void) +{ + free(malloc(0)); + free(malloc(0)); + free(malloc(0)); + free(malloc(0)); + free(malloc(0)); + free(malloc(0)); + free(malloc(0)); + free(malloc(0)); + free(malloc(0)); + free(malloc(0)); + return 0; +} Added: branches/MASSIF2/massif/tests/zero1.post.exp =================================================================== --- branches/MASSIF2/massif/tests/zero1.post.exp (rev 0) +++ branches/MASSIF2/massif/tests/zero1.post.exp 2007-09-21 05:05:45 UTC (rev 6886) @@ -0,0 +1,68 @@ +-------------------------------------------------------------------------------- +Command: ./zero +Data file: massif.out +Options: XXX +-------------------------------------------------------------------------------- + + +1.0 | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + 0 [EMAIL PROTECTED] + + +Number of snapshots: 21 + Detailed snapshots: [9, 19] +-------------------------------------------------------------------------------- + n time(B) total(B) useful-heap(B) admin-heap(B) stacks(B) +-------------------------------------------------------------------------------- + 0 0 0 0 0 0 + 1 0 0 0 0 0 + 2 0 0 0 0 0 + 3 0 0 0 0 0 + 4 0 0 0 0 0 + 5 0 0 0 0 0 + 6 0 0 0 0 0 + 7 0 0 0 0 0 + 8 0 0 0 0 0 + 9 0 0 0 0 0 +00.00% (0B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. +->00.00% (0B) in 5 places, all below massif's threshold (01.00%) + +-------------------------------------------------------------------------------- + n time(B) total(B) useful-heap(B) admin-heap(B) stacks(B) +-------------------------------------------------------------------------------- + 10 0 0 0 0 0 + 11 0 0 0 0 0 + 12 0 0 0 0 0 + 13 0 0 0 0 0 + 14 0 0 0 0 0 + 15 0 0 0 0 0 + 16 0 0 0 0 0 + 17 0 0 0 0 0 + 18 0 0 0 0 0 + 19 0 0 0 0 0 +00.00% (0B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. +->00.00% (0B) in 10 places, all below massif's threshold (01.00%) + +-------------------------------------------------------------------------------- + n time(B) total(B) useful-heap(B) admin-heap(B) stacks(B) +-------------------------------------------------------------------------------- + 20 0 0 0 0 0 Added: branches/MASSIF2/massif/tests/zero1.stderr.exp =================================================================== --- branches/MASSIF2/massif/tests/zero1.stderr.exp (rev 0) +++ branches/MASSIF2/massif/tests/zero1.stderr.exp 2007-09-21 05:05:45 UTC (rev 6886) @@ -0,0 +1,2 @@ + + Added: branches/MASSIF2/massif/tests/zero1.vgtest =================================================================== --- branches/MASSIF2/massif/tests/zero1.vgtest (rev 0) +++ branches/MASSIF2/massif/tests/zero1.vgtest 2007-09-21 05:05:45 UTC (rev 6886) @@ -0,0 +1,4 @@ +prog: zero +vgopts: --stacks=no --heap-admin=no --time-unit=B +post: perl ../../massif/ms_print --threshold=0 massif.out +cleanup: rm massif.out Added: branches/MASSIF2/massif/tests/zero2.post.exp =================================================================== --- branches/MASSIF2/massif/tests/zero2.post.exp (rev 0) +++ branches/MASSIF2/massif/tests/zero2.post.exp 2007-09-21 05:05:45 UTC (rev 6886) @@ -0,0 +1,68 @@ +-------------------------------------------------------------------------------- +Command: ./zero +Data file: massif.out +Options: XXX +-------------------------------------------------------------------------------- + + +1.0 | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + 0 [EMAIL PROTECTED] + + +Number of snapshots: 21 + Detailed snapshots: [9, 19] +-------------------------------------------------------------------------------- + n time(B) total(B) useful-heap(B) admin-heap(B) stacks(B) +-------------------------------------------------------------------------------- + 0 0 0 0 0 0 + 1 0 0 0 0 0 + 2 0 0 0 0 0 + 3 0 0 0 0 0 + 4 0 0 0 0 0 + 5 0 0 0 0 0 + 6 0 0 0 0 0 + 7 0 0 0 0 0 + 8 0 0 0 0 0 + 9 0 0 0 0 0 +00.00% (0B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. +->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%) + +-------------------------------------------------------------------------------- + n time(B) total(B) useful-heap(B) admin-heap(B) stacks(B) +-------------------------------------------------------------------------------- + 10 0 0 0 0 0 + 11 0 0 0 0 0 + 12 0 0 0 0 0 + 13 0 0 0 0 0 + 14 0 0 0 0 0 + 15 0 0 0 0 0 + 16 0 0 0 0 0 + 17 0 0 0 0 0 + 18 0 0 0 0 0 + 19 0 0 0 0 0 +00.00% (0B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. +->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%) + +-------------------------------------------------------------------------------- + n time(B) total(B) useful-heap(B) admin-heap(B) stacks(B) +-------------------------------------------------------------------------------- + 20 0 0 0 0 0 Added: branches/MASSIF2/massif/tests/zero2.stderr.exp =================================================================== --- branches/MASSIF2/massif/tests/zero2.stderr.exp (rev 0) +++ branches/MASSIF2/massif/tests/zero2.stderr.exp 2007-09-21 05:05:45 UTC (rev 6886) @@ -0,0 +1,2 @@ + + Added: branches/MASSIF2/massif/tests/zero2.vgtest =================================================================== --- branches/MASSIF2/massif/tests/zero2.vgtest (rev 0) +++ branches/MASSIF2/massif/tests/zero2.vgtest 2007-09-21 05:05:45 UTC (rev 6886) @@ -0,0 +1,4 @@ +prog: zero +vgopts: --stacks=no --heap-admin=no --time-unit=B +post: perl ../../massif/ms_print massif.out +cleanup: rm massif.out ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Valgrind-developers mailing list Valgrind-developers@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/valgrind-developers