|
From: <sv...@va...> - 2007-09-21 05:05:44
|
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 +@-----------------------------------------------------------------------
+
+
+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 +@-----------------------------------------------------------------------
+
+
+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
|