]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
- Rewrote documentation.
authorNicholas Nethercote <njn@valgrind.org>
Mon, 26 Nov 2007 21:59:04 +0000 (21:59 +0000)
committerNicholas Nethercote <njn@valgrind.org>
Mon, 26 Nov 2007 21:59:04 +0000 (21:59 +0000)
- Added a new time unit, instructions executed, and made it the default -- it's
  much more reproducible and consistent than milliseconds.  Requires IRSB
  instrumentation and so slows down some programs (malloc-light ones such as
  bzip2) by about 20%, others by less.
- ms_print now doesn't overwrite the x-axis in the graphs.
- Added a test for --detailed-freq and --max-snapshots

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7229

36 files changed:
massif/docs/ms-manual.xml
massif/ms_main.c
massif/ms_print.in
massif/tests/Makefile.am
massif/tests/alloc-fns-A.post.exp
massif/tests/alloc-fns-B.post.exp
massif/tests/basic.post.exp
massif/tests/basic2.post.exp [new file with mode: 0644]
massif/tests/basic2.stderr.exp [new file with mode: 0644]
massif/tests/basic2.vgtest [new file with mode: 0644]
massif/tests/big-alloc.post.exp
massif/tests/custom_alloc.post.exp
massif/tests/deep-A.post.exp
massif/tests/deep-B.post.exp
massif/tests/deep-C.post.exp
massif/tests/deep-D.post.exp
massif/tests/filter_stderr
massif/tests/ignoring.post.exp
massif/tests/insig.post.exp
massif/tests/long-time.post.exp
massif/tests/new-cpp.post.exp
massif/tests/no-stack-no-heap.post.exp
massif/tests/null.post.exp
massif/tests/one.post.exp
massif/tests/overloaded-new.post.exp
massif/tests/peak.post.exp
massif/tests/peak2.post.exp
massif/tests/realloc.post.exp
massif/tests/thresholds_0_0.post.exp
massif/tests/thresholds_0_10.post.exp
massif/tests/thresholds_10_0.post.exp
massif/tests/thresholds_10_10.post.exp
massif/tests/thresholds_5_0.post.exp
massif/tests/thresholds_5_10.post.exp
massif/tests/zero1.post.exp
massif/tests/zero2.post.exp

index c5ae3076705a30e454ae424b9a2a910e63b6fecf..c9eec4d3f303027d3b975e8456ca0f7a3433fcfd 100644 (file)
@@ -7,46 +7,27 @@
 <chapter id="ms-manual" xreflabel="Massif: a heap profiler">
   <title>Massif: a heap profiler</title>
 
-<pre>
- Docs:
- - Mention that complex functions names are best protected with single
-   quotes, eg:
-       --alloc-fn='operator new(unsigned, std::nothrow_t const&amp;)'
-   [XXX: that doesn't work if the option is in a .valgrindrc file or in
-    $VALGRIND_OPTS.  In m_commandline.c:add_args_from_string() need to
-    respect single quotes...]
- - Explain the --threshold=0 case -- entries with zero bytes must have
-   allocated some memory and then freed it all again.
- - Explain that no peak will be taken if no deallocations are done.
- - Explain how the stack is computed -- size is assumed to be zero when
-   code starts executing, which isn't true, but reflects what you have
-   control over in a normal program.
- - file format -- not specified, because it may change in the future to 
-   become more generic
-</pre>
-
+<emphasis>Please note that this documentation describes Massif version 3.3.0
+and later.  Massif was significantly overhauled for 3.3.0;  versions 3.2.3
+and earlier presented the profiling information an a quite different manner,
+and so this documentation only pertains to the later versions.</emphasis>
 
 <para>To use this tool, you must specify
 <computeroutput>--tool=massif</computeroutput> on the Valgrind
 command line.</para>
 
-
 <sect1 id="ms-manual.spaceprof" xreflabel="Heap profiling">
 <title>Heap profiling</title>
 
-<para>Massif is a heap profiler.  It measures how much heap
-memory programs use.  In particular, it can give you information
-about:</para>
+<para>Massif is a heap profiler.  It measures how much heap memory your
+program uses.  This includes both the useful space, as well as extra bytes
+allocated for book-keeping purposes and alignment purposes.  It can also
+measure the size of your program's stack(s), although it does not do so by
+default.</para>
 
-<itemizedlist>
-  <listitem><para>Heap blocks;</para></listitem>
-  <listitem><para>Heap administration blocks;</para></listitem>
-  <listitem><para>Stack sizes.</para></listitem>
-</itemizedlist>
-
-<para>Heap profiling is useful to help you reduce the amount of
-memory your program uses.  On modern machines with virtual
-memory, this provides the following benefits:</para>
+<para>Heap profiling can help you reduce the amount of memory your program
+uses.  On modern machines with virtual memory, this provides the following
+benefits:</para>
 
 <itemizedlist>
   <listitem><para>It can speed up your program -- a smaller
@@ -63,352 +44,423 @@ traditional leak-checkers, such as Memcheck's.  That's because
 the memory isn't ever actually lost -- a pointer remains to it --
 but it's not in use.  Programs that have leaks like this can
 unnecessarily increase the amount of memory they are using over
-time.</para>
-
-
-
-<sect2 id="ms-manual.heapprof" 
-       xreflabel="Why Use a Heap Profiler?">
-<title>Why Use a Heap Profiler?</title>
-
-<para>Everybody knows how useful time profilers are for speeding
-up programs.  They are particularly useful because people are
-notoriously bad at predicting where are the bottlenecks in their
-programs.</para>
-
-<para>But the story is different for heap profilers.  Some
-programming languages, particularly lazy functional languages
-like <ulink url="http://www.haskell.org">Haskell</ulink>, have
-quite sophisticated heap profilers.  But there are few tools as
-powerful for profiling C and C++ programs.</para>
-
-<para>Why is this?  Maybe it's because C and C++ programmers must
-think that they know where the memory is being allocated.  After
-all, you can see all the calls to
-<computeroutput>malloc()</computeroutput> and
-<computeroutput>new</computeroutput> and
-<computeroutput>new[]</computeroutput>, right?  But, in a big
-program, do you really know which heap allocations are being
-executed, how many times, and how large each allocation is?  Can
-you give even a vague estimate of the memory footprint for your
-program?  Do you know this for all the libraries your program
-uses?  What about administration bytes required by the heap
-allocator to track heap blocks -- have you thought about them?
-What about the stack?  If you are unsure about any of these
-things, maybe you should think about heap profiling.</para>
-
-<para>Massif can tell you these things.</para>
-
-<para>Or maybe it's because it's relatively easy to add basic
-heap profiling functionality into a program, to tell you how many
-bytes you have allocated for certain objects, or similar.  But
-this information might only be simple like total counts for the
-whole program's execution.  What about space usage at different
-points in the program's execution, for example?  And
-reimplementing heap profiling code for each project is a
-pain.</para>
-
-<para>Massif can save you this effort.</para>
+time.  Massif can help identify these leaks.</para>
 
-</sect2>
+<para>Importantly, Massif tells you not only how much heap memory your
+program is using, it also gives very detailed information that indicates
+which parts of your program are responsible for allocating the heap memory.
+</para>
 
 </sect1>
 
 
-
 <sect1 id="ms-manual.using" xreflabel="Using Massif">
 <title>Using Massif</title>
 
 
-<sect2 id="ms-manual.overview" xreflabel="Overview">
-<title>Overview</title>
+<para>First off, as for the other Valgrind tools, you should compile with
+debugging info (the <computeroutput>-g</computeroutput> flag).  It shouldn't
+matter much what optimisation level you compile your program with, as this
+is unlikely to affect the heap memory usage.</para>
 
-<para>First off, as for normal Valgrind use, you probably want to
-compile with debugging info (the
-<computeroutput>-g</computeroutput> flag).  But, as opposed to
-Memcheck, you probably <command>do</command> want to turn
-optimisation on, since you should profile your program as it will
-be normally run.</para>
-
-<para>Then, run your program with <computeroutput>valgrind
---tool=massif</computeroutput> in front of the normal command
-line invocation.  When the program finishes, Massif will print
-summary space statistics.  It also creates a graph showing
-the program's overall heap usage in a file called
-<filename>massif.pid.ps</filename>, which can be read by any
-PostScript viewer, such as Ghostview.</para>
-
-<para>It also puts detailed information about heap consumption in
-a file <filename>massif.pid.txt</filename> (text format) or
-<filename>massif.pid.html</filename> (HTML format), where
-<emphasis>pid</emphasis> is the program's process id.</para>
+<para>Then, to gather heap profiling information about the program
+<computeroutput>prog</computeroutput>, type:</para>
+<screen><![CDATA[
+% valgrind --tool=massif prog
+]]></screen>
+
+<para>The program will execute (slowly).  Upon completion, no summary
+statistics are printed to Valgrind's commentary;  all of Massif's profiling
+data is written to a file.  By default, this file is called
+<filename>massif.out.&lt;pid&gt;</filename>, where
+<filename>&lt;pid&gt;</filename> is the process ID.</para>
+
+<para>To see the information gathered by Massif in an easy-to-read form, use
+the ms_print script.  If the output file's name is
+<filename>massif.out.12345</filename>, type:</para>
+<screen><![CDATA[
+% ms_print massif.out.12345]]></screen>
 
-</sect2>
+<para>ms_print will produce (a) a graph showing the memory consumption over
+the program's execution, and (b) detailed information about the responsible
+allocation sites at various points in the program, including the point of
+peak memory allocation.  The use of a separate script for presenting the
+results is deliberate;  it separates the data gathering from its
+presentation, and means that new ones of presenting the data can be added in
+the future.</para>
 
+<sect2 id="ms-manual.anexample" xreflabel="An Example">
+<title>An Example Program</title>
 
-<sect2 id="ms-manual.basicresults" xreflabel="Basic Results of Profiling">
-<title>Basic Results of Profiling</title>
+<para>An example will make things clear.  Consider the following C program
+(annotated with line numbers) which allocates a number of different blocks
+on the heap.</para>
 
-<para>To gather heap profiling information about the program
-<computeroutput>prog</computeroutput>, type:</para>
 <screen><![CDATA[
-% valgrind --tool=massif prog]]></screen>
-
-<para>The program will execute (slowly).  Upon completion,
-summary statistics that look like this will be printed:</para>
-<programlisting><![CDATA[
-==27519== Total spacetime:   2,258,106 ms.B
-==27519== heap:              24.0%
-==27519== heap admin:         2.2%
-==27519== stack(s):          73.7%]]></programlisting>
-
-<para>All measurements are done in
-<emphasis>spacetime</emphasis>, i.e. space (in bytes) multiplied
-by time (in milliseconds).  Note that because Massif slows a
-program down a lot, the actual spacetime figure is fairly
-meaningless; it's the relative values that are
-interesting.</para>
-
-<para>Which entries you see in the breakdown depends on the
-command line options given.  The above example measures all the
-possible parts of memory:</para>
-
-<itemizedlist>
-  <listitem><para>Heap: number of words allocated on the heap, via
-    <computeroutput>malloc()</computeroutput>,
-    <computeroutput>new</computeroutput> and
-    <computeroutput>new[]</computeroutput>.</para>
-  </listitem>
-  <listitem>
-    <para>Heap admin: each heap block allocated requires some
-    administration data, which lets the allocator track certain
-    things about the block.  It is easy to forget about this, and
-    if your program allocates lots of small blocks, it can add
-    up.  This value is an estimate of the space required for this
-    administration data.</para>
-  </listitem>
-  <listitem>
-    <para>Stack(s): the spacetime used by the programs' stack(s).
-    (Threaded programs can have multiple stacks.)  This includes
-    signal handler stacks.</para>
-  </listitem>
-</itemizedlist>
+ 1      #include <stdlib.h>
+ 2
+ 3      void g(void)
+ 4      {
+ 5         malloc(4000);
+ 6      }
+ 7
+ 8      void f(void)
+ 9      {
+10         malloc(2000);
+11         g();
+12      }
+13
+14      int main(void)
+15      {
+16         int i;
+17         int* a[10];
+18
+19         for (i = 0; i < 10; i++) {
+20            a[i] = malloc(1000);
+21         }
+22
+23         f();
+24
+25         g();
+26
+27         for (i = 0; i < 10; i++) {
+28            free(a[i]);
+29         }
+30
+31         return 0;
+32      }
+]]></screen>
 
 </sect2>
 
 
-<sect2 id="ms-manual.graphs" xreflabel="Spacetime Graphs">
-<title>Spacetime Graphs</title>
-
-<para>As well as printing summary information, Massif also
-creates a file showing the overall spacetime behaviour of the 
-program, in a file
-called <filename>massif.pid.ps</filename>, which can be viewed in
-a PostScript viewer.</para>
-
-<para>Massif uses a program called
-<computeroutput>hp2ps</computeroutput> to convert the raw data
-into the PostScript graph.  It's distributed with Massif, but
-came originally from the 
-<ulink url="http://www.haskell.org/ghc/">Glasgow Haskell
-Compiler</ulink>.  You shouldn't need to worry about this at all.
-However, if the graph creation fails for any reason, Massif will
-tell you, and will leave behind a file named
-<filename>massif.pid.hp</filename>, containing the raw heap
-profiling data.</para>
-
-<para>Here's an example graph:</para>
-<mediaobject id="spacetime-graph">
-  <imageobject>
-    <imagedata fileref="images/massif-graph-sm.png" format="PNG"/>
-  </imageobject>
-  <textobject>
-    <phrase>Spacetime Graph</phrase>
-  </textobject>
-</mediaobject>
-
-<para>The graph is broken into several bands.  Most bands
-represent a single line of your program that does some heap
-allocation; each such band represents all the allocations and
-deallocations done from that line.  Up to twenty bands are shown;
-less significant allocation sites are merged into "other" and/or
-"OTHER" bands.  The accompanying text/HTML file produced by
-Massif has more detail about these heap allocation bands.  Then
-there are single bands for the stack(s) and heap admin
-bytes.</para>
-
-<formalpara>
-<title>Note:</title>
-<para>it's the height of a band that's important.  Don't let the
-ups and downs caused by other bands confuse you.  For example,
-the <computeroutput>read_alias_file</computeroutput> band in the
-example has the same height all the time it's in existence.</para>
-</formalpara>
-
-<para>The triangles on the x-axis show each point at which a
-memory census was taken.  These aren't necessarily evenly spread;
-Massif only takes a census when memory is allocated or
-deallocated.  The time on the x-axis is wallclock time, which is
-not ideal because you can get different graphs for different
-executions of the same program, due to random OS delays.  But
-it's not too bad, and it becomes less of a problem the longer a
-program runs.</para>
-
-<para>Massif takes censuses at an appropriate timescale; censuses
-take place less frequently as the program runs for longer.  There
-is no point having more than 100-200 censuses on a single
-graph.</para>
-
-<para>The graphs give a good overview of where your program's
-space use comes from, and how that varies over time.  The
-accompanying text/HTML file gives a lot more information about
-heap use.</para>
+<sect2 id="ms-manual.theoutputpreamble" xreflabel="The Output Preamble">
+<title>The Output Preamble</title>
+
+<para>After running this program under Massif, the first part of ms_print's
+output contains a preamble which just states how the program, Massif and
+ms_print were each invoked:</para>
+
+<screen><![CDATA[
+--------------------------------------------------------------------------------
+Command:            example
+Massif arguments:   (none)
+ms_print arguments: massif.out.12797
+--------------------------------------------------------------------------------
+]]></screen>
 
 </sect2>
 
-</sect1>
 
+<sect2 id="ms-manual.theoutputgraph" xreflabel="The Output Graph">
+<title>The Output Graph</title>
 
+<para>The next part is the graph that shows how memory consumption occurred
+as the program executed:</para>
 
-<sect1 id="ms-manual.heapdetails" 
-       xreflabel="Details of Heap Allocations">
-<title>Details of Heap Allocations</title>
+<screen><![CDATA[
+    KB
+19.63^                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                       #
+     |                                                                      :#
+     |                                                                      :#
+     |                                                                      :#
+     |                                                                      :#
+     |                                                                      :#
+     |                                                                      :#
+   0 +----------------------------------------------------------------------->ki
+     0                                                                   121.8
+
+Number of snapshots: 25
+ Detailed snapshots: [9, 14 (peak), 24]
+]]></screen>
+
+<para>Why is most of the graph empty, with only a couple of bars at the very
+end?  By default, Massif uses "instructions executed" as the unit of time.
+For very short-run programs such as the example, most of the execution
+instructions involved the loading and dynamic linking of the program.  The
+execution of <computeroutput>main</computeroutput> (and thus the heap
+allocations) only occur at the very end.  For a short-running program like
+this, we can use the <computeroutput>--time-unit=B</computeroutput> option
+to specify that we want the time unit to instead be the number of bytes
+allocated/deallocated on the heap and stack(s).</para>
+
+<para>If we re-run the program under Massif with this option, and then
+re-run ms_print, we get this more useful graph:</para>
 
-<para>The text/HTML file contains information to help interpret
-the heap bands of the graph.  It also contains a lot of extra
-information about heap allocations that you don't see in the
-graph.</para>
+<screen><![CDATA[
+    KB
+19.63^                                               #                        
+     |                                               #  .                     
+     |                                               #  : .                   
+     |                                               #  : :  .                
+     |                                      :        #  : :  : .              
+     |                                      :        #  : :  : : .            
+     |                                      :        #  : :  : : :  .         
+     |                                      :        #  : :  : : :  : .       
+     |                            :         :        #  : :  : : :  : :  .    
+     |                            :         :        #  : :  : : :  : :  : .  
+     |                        :   :         :        #  : :  : : :  : :  : : .
+     |                     @  :   :         :        #  : :  : : :  : :  : : @
+     |                   : @  :   :         :        #  : :  : : :  : :  : : @
+     |                :  : @  :   :         :        #  : :  : : :  : :  : : @
+     |              : :  : @  :   :         :        #  : :  : : :  : :  : : @
+     |            : : :  : @  :   :         :        #  : :  : : :  : :  : : @
+     |         :  : : :  : @  :   :         :        #  : :  : : :  : :  : : @
+     |       : :  : : :  : @  :   :         :        #  : :  : : :  : :  : : @
+     |    :  : :  : : :  : @  :   :         :        #  : :  : : :  : :  : : @
+     |  : :  : :  : : :  : @  :   :         :        #  : :  : : :  : :  : : @
+   0 +----------------------------------------------------------------------->KB
+     0                                                                   29.48
+
+Number of snapshots: 25
+ Detailed snapshots: [9, 14 (peak), 24]
+]]></screen>
+
+<para>Each vertical bar represents a snapshot, i.e. a measurement of the
+memory usage at a certain point in time.  The text at the bottom show that
+25 snapshots were taken for this program, which is one per heap
+allocation/deallocation, plus a couple of extras.  Massif starts by taking
+snapshots for every heap allocation/deallocation, but as a program runs for
+longer, it takes snapshots less frequently.  It also discards older
+snapshots as the program goes on;  when it reaches the maximum number of
+snapshots (100 by default, although changeable with the
+<computeroutput>--max-snapshots</computeroutput> option) half of them are
+deleted.  This means that a reasonable number of snapshots are always
+maintained.</para>
+
+<para>Most snapshots are <emphasis>normal</emphasis>, and only basic
+information is recorded for them.  Normal snapshots are represented in the
+graph by bars consisting of ':' and '.' characters.</para>
+
+<para>Some snapshots are <emphasis>detailed</emphasis>.  Information about
+where allocations happened are recorded for these snapshots, as we will see
+shortly.  Detailed snapshots are represented in the graph by bars consisting
+of '@' and '.' characters.  The text at the bottom show that 3 detailed
+snapshots were taken for this program (snapshots 9, 14 and 24).  By default,
+every 10th snapshot is detailed, although this can be changed via the
+<computeroutput>--detailed-freq</computeroutput>option.</para>
+
+<para>Finally, there is at most one <emphasis>peak</emphasis> snapshot.  The
+peak snapshot is detailed, and records the point where memory consumption
+was greatest.  (Actually, recording the true peak is expensive, and so by
+default Massif records a peak whose size is within 1% of the size of the
+true peak.  See the description of the
+<computeroutput>--peak-inaccuracy</computeroutput> option below for more
+details.) The peak snapshot is represented in the graph by a bar consisting
+of '#' and '.' characters.  The text at the bottom show that snapshot 14 was
+the peak.  Note that for tiny programs that never deallocate heap memory,
+Massif will record a peak snapshot.</para>
+
+<para>The following graph is from an execution of Konqueror, the KDE web
+browser.  It shows what graphs for larger programs look like.</para>
+<screen><![CDATA[
+    MB
+3.952^                                                                    #.
+     |                                                                  .@#:
+     |                                                            . .. :@@#:
+     |                                                            @ :: :@@#:.
+     |                                                           .@ :: :@@#::
+     |                                                       . .@@@ :: :@@#:.
+     |                                                      .@ :@@@ :: :@@#::
+     |                                                    : :@ :@@@ :: :@@#::
+     |                                                   .: :@ :@@@ :: :@@#::
+     |                                                 .:@: :@ :@@@ :: :@@#::.
+     |                                                @@:@: :@ :@@@ :: :@@#:::
+     |                         ..:      .::   . .  .::@@:@: :@ :@@@ :: :@@#:::
+     |                       .:@@:   .: ::: ::: @  :::@@:@: :@ :@@@ :: :@@#:::
+     |                    .: ::@@:  ::: ::::::: @  :::@@:@: :@ :@@@ :: :@@#:::
+     |                    @: ::@@:  ::: ::::::: @  :::@@:@: :@ :@@@ :: :@@#::.
+     |                    @: ::@@:  ::: ::::::: @  :::@@:@: :@ :@@@ :: :@@#:::
+     |                  . @: ::@@:: ::: ::::::: @  :::@@:@: :@ :@@@ :: :@@#:::
+     |                ::@ @: ::@@:: ::: ::::::: @  :::@@:@: :@ :@@@ :: :@@#:::
+     |           . :::::@ @: ::@@:: ::: ::::::: @  :::@@:@: :@ :@@@ :: :@@#:::
+     |         ..@ :::::@ @: ::@@:: ::: ::::::: @  :::@@:@: :@ :@@@ :: :@@#:::
+   0 +----------------------------------------------------------------------->Mi
+     0                                                                   626.4
+
+Number of snapshots: 63
+ Detailed snapshots: [3, 4, 10, 11, 15, 16, 29, 33, 34, 36, 39, 41, 42, 43, 44, 49, 50, 51, 53, 55, 56, 57 (peak)]
+]]></screen>
+
+<para>Note that the larger size units are KB, MB, GB, etc.  As is typical
+for memory measurements, these are based on a multiplier of 1024, rather
+than the standard SI multiplier of 1000.  Strictly speaking, they should be
+written KiB, MiB, GiB, etc.</para>
 
+</sect2>
 
-<para>Here's part of the information that accompanies the above
-graph.</para>
 
-<blockquote>
-<literallayout>== 0 ===========================</literallayout>
+<sect2 id="ms-manual.thesnapshotdetails" xreflabel="The Snapshot Details">
+<title>The Snapshot Details</title>
 
-<para>Heap allocation functions accounted for 50.8% of measured
-spacetime</para>
+<para>Returning to our example, the graph is followed by the detailed
+information for each snapshot.  The first nine snapshots are normal, so only
+a small amount of information is recorded for each one:</para>
+<screen><![CDATA[
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+  0              0                0                0             0            0
+  1          1,008            1,008            1,000             8            0
+  2          2,016            2,016            2,000            16            0
+  3          3,024            3,024            3,000            24            0
+  4          4,032            4,032            4,000            32            0
+  5          5,040            5,040            5,000            40            0
+  6          6,048            6,048            6,000            48            0
+  7          7,056            7,056            7,000            56            0
+  8          8,064            8,064            8,000            64            0
+]]></screen>
+
+<para>Each normal snapshot records several things.</para>
 
-<para>Called from:</para>
-<itemizedlist>
-  <listitem id="a401767D1"><para>
-    <ulink url="#b401767D1">22.1%</ulink>: 0x401767D0:
-    _nl_intern_locale_data (in /lib/i686/libc-2.3.2.so)</para>
-  </listitem>
-  <listitem id="a4017C394"><para>
-    <ulink url="#b4017C394">8.6%</ulink>: 0x4017C393:
-    read_alias_file (in /lib/i686/libc-2.3.2.so)</para>
-  </listitem>
-  <listitem>
-    <para>... ... <emphasis>(several entries omitted)</emphasis></para>
-  </listitem>
-  <listitem>
-    <para>and 6 other insignificant places</para>
-  </listitem>
-</itemizedlist>
-</blockquote>
-
-<para>The first part shows the total spacetime due to heap
-allocations, and the places in the program where most memory was
-allocated.  If this program had been compiled with
-<computeroutput>-g</computeroutput>, actual line numbers would be
-given.  These places are sorted, from most significant to least,
-and correspond to the bands seen in the graph.  Insignificant
-sites (accounting for less than 0.5% of total spacetime) are
-omitted.</para>
-
-<para>That alone can be useful, but often isn't enough.  What if
-one of these functions was called from several different places
-in the program?  Which one of these is responsible for most of
-the memory used?  For
-<computeroutput>_nl_intern_locale_data()</computeroutput>, this
-question is answered by clicking on the 
-<ulink url="#b401767D1">22.1%</ulink> link, which takes us to the
-following part of the file:</para>
-
-<blockquote id="b401767D1">
-<literallayout>== 1 ===========================</literallayout>
-
-<para>Context accounted for <ulink url="#a401767D1">22.1%</ulink>
-of measured spacetime</para>
-
-<para><computeroutput> 0x401767D0: _nl_intern_locale_data (in
-/lib/i686/libc-2.3.2.so)</computeroutput></para>
-
-<para>Called from:</para>
-<itemizedlist>
-  <listitem id="a40176F96"><para>
-    <ulink url="#b40176F96">22.1%</ulink>: 0x40176F95:
-    _nl_load_locale_from_archive (in
-    /lib/i686/libc-2.3.2.so)</para>
-  </listitem>
-</itemizedlist>
-</blockquote>
-
-<para>At this level, we can see all the places from which
-<computeroutput>_nl_load_locale_from_archive()</computeroutput>
-was called such that it allocated memory at 0x401767D0.  (We can
-click on the top <ulink url="#a40176F96">22.1%</ulink> link to go back
-to the parent entry.)  At this level, we have moved beyond the
-information presented in the graph.  In this case, it is only
-called from one place.  We can again follow the link for more
-detail, moving to the following part of the file.</para>
-
-<blockquote>
-<literallayout>== 2 ===========================</literallayout>
-<para id="b40176F96">
-Context accounted for <ulink url="#a40176F96">22.1%</ulink> of
-measured spacetime</para>
-
-<para><computeroutput> 0x401767D0: _nl_intern_locale_data (in
-/lib/i686/libc-2.3.2.so)</computeroutput> <computeroutput>
-0x40176F95: _nl_load_locale_from_archive (in
-/lib/i686/libc-2.3.2.so)</computeroutput></para>
-
-<para>Called from:</para>
 <itemizedlist>
-  <listitem id="a40176185">
-    <para>22.1%: 0x40176184: _nl_find_locale (in
-    /lib/i686/libc-2.3.2.so)</para>
-  </listitem>
+  <listitem><para>Its number.</para></listitem>
+
+  <listitem><para>The time it was taken. In this case, the time unit is
+  bytes, due to the use of
+  <computeroutput>--time-unit=B</computeroutput>.</para></listitem>
+
+  <listitem><para>The total memory consumption at that point.</para></listitem>
+
+  <listitem><para>The number of useful heap bytes allocated at that point.
+  This reflects the number of bytes asked for by the
+  program.</para></listitem>
+
+  <listitem><para>The number of extra heap bytes allocated at that point.
+  This reflects the number of bytes allocated in excess of what the program
+  asked for.  There are two sources of extra heap bytes.</para>
+  
+  <para>First, every heap block has administrative bytes associated with it.
+  The exact number of administrative bytes depends on the details of the
+  allocator.  By default Massif assumes 8 bytes per block, as can be seen
+  from the example, but this number can be changed via the
+  <computeroutput>--heap-admin</computeroutput> option.</para>
+
+  <para>Second, allocators often round up the number of bytes asked for to a
+  larger number.  By default, if N bytes are asked for, Massif rounds N up
+  to the nearest multiple of 8 that is equal to or greater than N.  This is
+  typical behaviour for allocators, and is required to ensure that elements
+  within the block are suitable aligned.  The rounding size can be changed
+  with the <computeroutput>--alignment</computeroutput> option, although it
+  cannot be less than 8, and must be a power of two.</para></listitem>
+
+  <listitem><para>The size of the stack(s).  By default, stack profiling is
+  off as it slows Massif down greatly.  Therefore, the stack column is zero
+  in the example.</para></listitem>
 </itemizedlist>
-</blockquote>
-
-<para>In this way we can dig deeper into the call stack, to work
-out exactly what sequence of calls led to some memory being
-allocated.  At this point, with a call depth of 3, the
-information runs out (thus the address of the child entry,
-0x40176184, isn't a link).  We could rerun the program with a
-greater <computeroutput>--depth</computeroutput> value if we
-wanted more information.</para>
-
-<para>Sometimes you will get a code location like this:</para>
-<programlisting><![CDATA[
-30.8% : 0xFFFFFFFF: ???]]></programlisting>
-
-<para>The code address isn't really 0xFFFFFFFF -- that's
-impossible.  This is what Massif does when it can't work out what
-the real code address is.</para>
 
-<para>Massif produces this information in a plain text file by
-default, or HTML with the
-<computeroutput>--format=html</computeroutput> option.  The plain
-text version obviously doesn't have the links, but a similar
-effect can be achieved by searching on the code addresses.  In
-the Vim editor, the '*' and '#' searches are ideal for this.</para>
+<para>The next snapshot is detailed.  As well as the basic counts, it gives
+an allocation tree which indicates exactly which pieces of code were
+responsible for allocating heap memory:</para>
 
+<screen><![CDATA[
+  9          9,072            9,072            9,000            72            0
+99.21% (9,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+->99.21% (9,000B) 0x804841A: main (example.c:20)
+]]></screen>
+
+<para>The allocation tree can be read from the top down.  The first line
+indicates all heap allocation functions such as <function>malloc</function>
+and C++ <function>new</function>.  All heap allocations go through these
+functions, and so all 9,000 useful bytes (which is 99.21% of all allocated
+bytes) go through them.  But how were <function>malloc</function> and new
+called?  At this point, every allocation so far has been due to line 21
+inside <function>main</function>, hence the second line in the tree.  The
+<computeroutput>-></computeroutput> indicates that main (line 20) called
+<function>malloc</function>.</para>
+
+<para>Let's see what the subsequent output shows happened next:</para>
 
-<sect2 id="ms-manual.accuracy" xreflabel="Accuracy">
-<title>Accuracy</title>
-
-<para>The information should be pretty accurate.  Some
-approximations made might cause some allocation contexts to be
-attributed with less memory than they actually allocated, but the
-amounts should be miniscule.</para>
+<screen><![CDATA[
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+ 10         10,080           10,080           10,000            80            0
+ 11         12,088           12,088           12,000            88            0
+ 12         16,096           16,096           16,000            96            0
+ 13         20,104           20,104           20,000           104            0
+ 14         20,104           20,104           20,000           104            0
+99.48% (20,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+->49.74% (10,000B) 0x804841A: main (example.c:20)
+| 
+->39.79% (8,000B) 0x80483C2: g (example.c:5)
+| ->19.90% (4,000B) 0x80483E2: f (example.c:11)
+| | ->19.90% (4,000B) 0x8048431: main (example.c:23)
+| |   
+| ->19.90% (4,000B) 0x8048436: main (example.c:25)
+|   
+->09.95% (2,000B) 0x80483DA: f (example.c:10)
+  ->09.95% (2,000B) 0x8048431: main (example.c:23)
+]]></screen>
+
+<para>The first four snapshots are similar to the previous ones.  But then
+the global allocation peak is reached, and a detailed snapshot is taken.
+Its allocation tree shows that 20,000B of useful heap memory has been
+allocated, and the lines and arrows indicate that this is from three
+different code locations: line 20, which is responsible for 10,000B
+(49.74%);  line 5, which is responsible for 8,000B (39.79%); and line 10,
+which is responsible for 2,000B (9.95%).</para>
+
+<para>We can then drill down further in the allocation tree.  For example,
+of the 8,000B asked for by line 5, half of it was due to a call from line
+11, and half was due to a call from line 25.</para>
+
+<para>In short, Massif collates the stack trace of every single allocation
+point in the program into a single tree, which gives a complete picture of
+how and why all heap memory was allocated.</para>
+
+<para>The final part of the output is similar:</para>
 
-<para>The heap admin spacetime figure is an approximation, as
-described above.  If anyone knows how to improve its accuracy,
-please let us know.</para>
+<screen><![CDATA[
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+ 15         21,112           19,096           19,000            96            0
+ 16         22,120           18,088           18,000            88            0
+ 17         23,128           17,080           17,000            80            0
+ 18         24,136           16,072           16,000            72            0
+ 19         25,144           15,064           15,000            64            0
+ 20         26,152           14,056           14,000            56            0
+ 21         27,160           13,048           13,000            48            0
+ 22         28,168           12,040           12,000            40            0
+ 23         29,176           11,032           11,000            32            0
+ 24         30,184           10,024           10,000            24            0
+99.76% (10,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+->79.81% (8,000B) 0x80483C2: g (example.c:5)
+| ->39.90% (4,000B) 0x80483E2: f (example.c:11)
+| | ->39.90% (4,000B) 0x8048431: main (example.c:23)
+| |   
+| ->39.90% (4,000B) 0x8048436: main (example.c:25)
+|   
+->19.95% (2,000B) 0x80483DA: f (example.c:10)
+| ->19.95% (2,000B) 0x8048431: main (example.c:23)
+|   
+->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
+]]></screen>
+
+<para>The final detailed snapshot shows how the heap looked at termination.
+The 00.00% entry represents the code locations for which memory was
+allocated and then freed (line 20 in this case, the memory for which was
+freed on line 28).  However, no code location details are given for this
+entry;  by default, Massif/ms_print only show the details for code locations
+responsible for more than 1% of useful memory bytes.  The entries that do
+not meet this threshold are aggregated.  This avoids filling up the output
+with large numbers of unimportant entries.  This threshold can be changed
+with the <computeroutput>--threshold</computeroutput> option of both Massif
+and ms_print.</para>
 
 </sect2>
 
@@ -428,9 +480,7 @@ please let us know.</para>
       <option><![CDATA[--heap=<yes|no> [default: yes] ]]></option>
     </term>
     <listitem>
-      <para>When enabled, profile heap usage in detail.  Without it, the
-      <filename>massif.pid.txt</filename> or
-      <filename>massif.pid.html</filename> will be very short.</para>
+      <para>Specifies whether heap profiling should be done.</para>
     </listitem>
   </varlistentry>
 
@@ -439,12 +489,13 @@ please let us know.</para>
       <option><![CDATA[--heap-admin=<number> [default: 8] ]]></option>
     </term>
     <listitem>
-      <para>The number of admin bytes per block to use.  This can only
-      be an estimate of the average, since it may vary.  The allocator
-      used by <computeroutput>glibc</computeroutput> requires somewhere
-      between 4 to 15 bytes per block, depending on various factors.  It
-      also requires admin space for freed blocks, although
-      <constant>massif</constant> does not count this.</para>
+      <para>If heap profiling is on, gives the number of administrative
+      bytes per block to use.  This should be an estimate of the average,
+      since it may vary.  For example, the allocator used by
+      <computeroutput>glibc</computeroutput> requires somewhere between 4 to
+      15 bytes per block, depending on various factors.  It also requires
+      admin space for freed blocks, although Massif does not account
+      for this.</para>
     </listitem>
   </varlistentry>
 
@@ -453,22 +504,23 @@ please let us know.</para>
       <option><![CDATA[--stacks=<yes|no> [default: yes] ]]></option>
     </term>
     <listitem>
-      <para>When enabled, include stack(s) in the profile.  Threaded
-      programs can have multiple stacks.</para>
+      <para>Specifies whether stack profiling should be done.  This option
+      slows Massif down greatly, and so is off by default.  Note that Massif
+      assumes that the main stack has size zero at start-up.  This is not
+      true, but measuring the actual stack size is not easy, and it reflects
+      the size of the part of the main stack that a user program actually
+      has control over.</para>
     </listitem>
   </varlistentry>
 
   <varlistentry id="opt.depth" xreflabel="--depth">
     <term>
-      <option><![CDATA[--depth=<number> [default: 3] ]]></option>
+      <option><![CDATA[--depth=<number> [default: 30] ]]></option>
     </term>
     <listitem>
-      <para>Depth of call chains to present in the detailed heap
-      information.  Increasing it will give more information, but
-      <constant>massif</constant> will run the program more slowly,
-      using more memory, and produce a bigger
-      <filename>massif.pid.txt</filename> or
-      <filename>massif.pid.hp</filename> file.</para>
+      <para>Maximum depth of the allocation trees recorded for detailed
+      snapshots.  Increasing it will make Massif run somewhat more slowly,
+      use more memory, and produce bigger output files.</para>
     </listitem>
   </varlistentry>
 
@@ -477,25 +529,131 @@ please let us know.</para>
       <option><![CDATA[--alloc-fn=<name> ]]></option>
     </term>
     <listitem>
-      <para>Specify a function that allocates memory.  This is useful
-      for functions that are wrappers to <function>malloc()</function>,
-      which can fill up the context information uselessly (and give very
-      uninformative bands on the graph).  Functions specified will be
-      ignored in contexts, i.e. treated as though they were
-      <function>malloc()</function>.  This option can be specified
-      multiple times on the command line, to name multiple
-      functions.</para>
+      <para>Functions specified with this option will be treated as though
+      they were a heap allocation function such as
+      <function>malloc</function>.  This is useful for functions that are
+      wrappers to <function>malloc</function> or <function>new</function>,
+      which can fill up the allocation trees with uninteresting information.
+      This option can be specified multiple times on the command line, to
+      name multiple functions.</para>
+      
+      <para>Note that overloaded C++ names must be written in full.  Single
+      quotes may be necessary to prevent the shell from breaking them up.
+      For example:
+<screen><![CDATA[
+--alloc-fn='operator new(unsigned, std::nothrow_t const&amp;)'
+]]></screen>
+      </para>
+
+      <para>
+      The full list of functions and operators that are by default
+      considered allocation functions is as follows.</para>
+<screen><![CDATA[
+malloc
+calloc
+realloc
+memalign
+__builtin_new
+__builtin_vec_new
+operator new(unsigned)
+operator new(unsigned long)
+operator new[](unsigned)
+operator new[](unsigned long)
+operator new(unsigned, std::nothrow_t const&)
+operator new[](unsigned, std::nothrow_t const&)
+operator new(unsigned long, std::nothrow_t const&)
+operator new[](unsigned long, std::nothrow_t const&)
+]]></screen>
+      </listitem>
+  </varlistentry>
+
+  <varlistentry id="opt.threshold" xreflabel="--threshold">
+    <term>
+      <option><![CDATA[--threshold=<m.n> [default: 1.0] ]]></option>
+    </term>
+    <listitem>
+      <para>The significance threshold for heap allocations, as a
+      percentage.  Allocation tree entries that account for less than this
+      will be aggregated.  Note that this should be specified in tandem with
+      ms_print's option of the same name.</para>
+    </listitem>
+  </varlistentry>
+
+  <varlistentry id="opt.peak-inaccuracy" xreflabel="--peak-inaccuracy">
+    <term>
+      <option><![CDATA[--peak-inaccuracy=<m.n> [default: 1.0] ]]></option>
+    </term>
+    <listitem>
+      <para>Massif does not necessarily record the actual global memory
+      allocation peak;  by default it records a peak only when the global
+      memory allocation size exceeds the previous peak by at least 1.0%.
+      This is because there are many local allocation peaks along the way,
+      and doing a detailed snapshot for every one would be expensive and
+      wasteful, as all but one of them will be later discarded.  This
+      inaccuracy can be changed (even to 0.0%) via this option, but Massif
+      will run drastically slower as the number approaches zero.</para>
+    </listitem>
+  </varlistentry>
+
+  <varlistentry id="opt.time-unit" xreflabel="--time-unit">
+    <term>
+      <option><![CDATA[--time-unit=i|ms|B [default: i] ]]></option>
+    </term>
+    <listitem>
+      <para>The time unit used for the profiling.  There are three
+      possibilities: instructions executed (i), which is good for most
+      cases; real time (ms, i.e. milliseconds), which is useful sometimes;
+      and bytes allocated/deallocated on the heap and/or stack (B), which is
+      useful for very short-run programs, and for testing purposes, because
+      it is the most reproducible across different machines.</para>
+    </listitem>
+  </varlistentry>
+
+  <varlistentry id="opt.detailed-freq" xreflabel="--detailed-freq">
+    <term>
+      <option><![CDATA[--detailed-freq=<n> [default: 10] ]]></option>
+    </term>
+    <listitem>
+      <para>Frequency of detailed snapshots.  With
+      <computeroutput>--detailed-freq=1</computeroutput>, every snapshot is
+      detailed.</para>
+    </listitem>
+  </varlistentry>
+
+  <varlistentry id="opt.max-snapshots" xreflabel="--max-snapshots">
+    <term>
+      <option><![CDATA[--max-snapshots=<n> [default: 100] ]]></option>
+    </term>
+    <listitem>
+      <para>The maximum number of snapshots recorded.  If set to N, for all
+      programs except very short-running ones, the final number of snapshots
+      will be between N/2 and N.</para>
+    </listitem>
+  </varlistentry>
+
+  <varlistentry id="opt.massif-out-file" xreflabel="--massif-out-file">
+    <term>
+      <option><![CDATA[--massif-out-file=<file> [default: massif.out.%p] ]]></option>
+    </term>
+    <listitem>
+      <para>Write the profile data to <computeroutput>file</computeroutput>
+      rather than to the default output file,
+      <computeroutput>massif.out.&lt;pid&gt;</computeroutput>.  The
+      <option>%p</option> and <option>%q</option> format specifiers can be
+      used to embed the process ID and/or the contents of an environment
+      variable in the name, as is the case for the core option
+      <option>--log-file</option>.  See <link
+      linkend="manual-core.basicopts">here</link> for details.
+      </para>
     </listitem>
   </varlistentry>
 
-  <varlistentry id="opt.format" xreflabel="--format">
+  <varlistentry id="opt.alignment" xreflabel="--alignment">
     <term>
-      <option><![CDATA[--format=<text|html> [default: text] ]]></option>
+      <option><![CDATA[--threshold=<m.n> [default: 1.0] ]]></option>
     </term>
     <listitem>
-      <para>Produce the detailed heap information in text or HTML
-      format.  The file suffix used will be either
-      <filename>.txt</filename> or <filename>.html</filename>.</para>
+      <para>The minimum alignment (and thus size) of heap blocks.</para>
     </listitem>
   </varlistentry>
 
@@ -504,4 +662,49 @@ please let us know.</para>
 
 </sect1>
 
+
+<sect1 id="ms-manual.ms_print-options" xreflabel="ms_print Options">
+<title>ms_print Options</title>
+
+<para>ms_print's options are:</para>
+
+<itemizedlist>
+
+  <listitem>
+    <para><computeroutput>-h, --help</computeroutput></para>
+    <para><computeroutput>-v, --version</computeroutput></para>
+    <para>Help and version, as usual.</para>
+  </listitem>
+
+  <listitem>
+    <para><option><![CDATA[--threshold=<m.n>]]></option> [default: 1.0]</para>
+    <para>Same as Massif's <computeroutput>--threshold</computeroutput>, but
+    applied after profiling rather than during.</para>
+  </listitem>
+
+  <listitem>
+    <para><option><![CDATA[--x=<m.n>]]></option> [default: 72]</para>
+    <para>Width of the graph, in columns.</para>
+  </listitem>
+
+  <listitem>
+    <para><option><![CDATA[--y=<n>]]></option> [default: 20]</para>
+    <para>Height of the graph, in rows.</para>
+  </listitem>
+
+</itemizedlist>
+
+</sect1>
+
+<sect1 id="ms-manual.fileformat" xreflabel="fileformat">
+<title>Massif's output file format</title>
+<para>Massif's file format is plain text (i.e. not binary) and deliberately
+easy to read for both humands and machines.  Nonetheless, the exact format
+is not described here.  This is because the format is currently very
+Massif-specific.  We plan to make the format more general, and thus suitable
+for possible use with other tools.  Once this has been done, the format will
+be documented here.</para>
+
+</sect1>
+
 </chapter>
index f940a91440462ec380f39c8d1a4e2d988ecc9d9d..660a7188b749716df53a2b348d713117a94cfcc4 100644 (file)
 // XXX:
 //---------------------------------------------------------------------------
 // Todo -- critical for release:
-// - write documentation
 // - address/close all the bug reports below (after writing docs)
 // - do a graph-drawing test
-// - write a good basic test that shows how the tool works, suitable for
-//   documentation
-// - In cg_annotate, remove the --<pid> option.
 // - Get Josef to update the Callgrind --callgrind-out-file option.
+// - Use '_' instead of '.' for detailed/peak bars?
+// - ms_print -- XXX on line 535
 //
 // Todo -- nice, but less critical:
 // - make file format more generic.  Obstacles:
 //   identified?  [hmm, could make getting the name of alloc-fns more
 //   difficult] [could dump full names to file, truncate in ms_print]
 // - make --show-below-main=no work
+// - Options like --alloc-fn='operator new(unsigned, std::nothrow_t const&amp;)'
+//   don't work in a .valgrindrc file or in $VALGRIND_OPTS. 
+//   m_commandline.c:add_args_from_string() needs to respect single quotes.
+//   
 //
 // Performance:
 // - To run the benchmarks:
@@ -80,8 +82,6 @@
 //   VG_(bsearch) function.  
 //
 // Todo -- low priority:
-// - Consider 'instructions executed' as a time unit -- more regular than
-//   ms, less artificial than B (bug #121629).
 // - In each XPt, record both bytes and the number of allocations, and
 //   possibly the global number of allocations.
 // - (Artur Wisz) add a feature to Massif to ignore any heap blocks larger
@@ -297,6 +297,10 @@ static UInt n_XCon_redos           = 0;
 //--- Globals                                              ---//
 //------------------------------------------------------------//
 
+// Number of guest instructions executed so far.  Only used with
+// --time-unit=i.
+static Long guest_instrs_executed = 0;
+
 static SizeT heap_szB       = 0; // Live heap size
 static SizeT heap_extra_szB = 0; // Live heap extra size -- slop + admin bytes
 static SizeT stacks_szB     = 0; // Live stacks size
@@ -377,11 +381,12 @@ static Bool is_alloc_fn(Char* fnname)
 
 #define MAX_DEPTH       200
 
-typedef enum { TimeMS, TimeB } TimeUnit;
+typedef enum { TimeI, TimeMS, TimeB } TimeUnit;
 
 static Char* TimeUnit_to_string(TimeUnit time_unit)
 {
    switch (time_unit) {
+   case TimeI:  return "i";
    case TimeMS: return "ms";
    case TimeB:  return "B";
    default:     tl_assert2(0, "TimeUnit_to_string: unrecognised TimeUnit");
@@ -398,7 +403,7 @@ static Bool   clo_stacks          = False;
 static UInt   clo_depth           = 30;
 static double clo_threshold       = 1.0;  // percentage
 static double clo_peak_inaccuracy = 1.0;  // percentage
-static UInt   clo_time_unit       = TimeMS;
+static UInt   clo_time_unit       = TimeI;
 static UInt   clo_detailed_freq   = 10;
 static UInt   clo_max_snapshots   = 100;
 static Char*  clo_massif_out_file = "massif.out.%p";
@@ -413,7 +418,6 @@ static Bool ms_process_cmd_line_option(Char* arg)
         VG_BOOL_CLO(arg, "--heap",   clo_heap)
    else VG_BOOL_CLO(arg, "--stacks", clo_stacks)
 
-   // XXX: "--heap-admin= " is accepted!
    else VG_NUM_CLO(arg, "--heap-admin", clo_heap_admin)
    else VG_NUM_CLO(arg, "--depth",      clo_depth)
 
@@ -424,6 +428,7 @@ static Bool ms_process_cmd_line_option(Char* arg)
    else VG_NUM_CLO(arg, "--detailed-freq", clo_detailed_freq)
    else VG_NUM_CLO(arg, "--max-snapshots", clo_max_snapshots)
 
+   else if (VG_CLO_STREQ(arg, "--time-unit=i"))  clo_time_unit = TimeI;
    else if (VG_CLO_STREQ(arg, "--time-unit=ms")) clo_time_unit = TimeMS;
    else if (VG_CLO_STREQ(arg, "--time-unit=B"))  clo_time_unit = TimeB;
 
@@ -446,15 +451,15 @@ static void ms_print_usage(void)
 {
    VG_(printf)(
 "    --heap=no|yes             profile heap blocks [yes]\n"
-"    --heap-admin=<number>     average admin bytes per heap block;"
+"    --heap-admin=<number>     average admin bytes per heap block;\n"
 "                               ignored if --heap=no [8]\n"
 "    --stacks=no|yes           profile stack(s) [no]\n"
 "    --depth=<number>          depth of contexts [30]\n"
 "    --alloc-fn=<name>         specify <fn> as an alloc function [empty]\n"
 "    --threshold=<m.n>         significance threshold, as a percentage [1.0]\n"
 "    --peak-inaccuracy=<m.n>   maximum peak inaccuracy, as a percentage [1.0]\n"
-"    --time-unit=ms|B          time unit, milliseconds or bytes\n"
-"                               alloc'd/dealloc'd on the heap [ms]\n"
+"    --time-unit=i|ms|B        time unit: instructions executed, milliseconds\n"
+"                              or heap bytes alloc'd/dealloc'd [i]\n"
 "    --detailed-freq=<N>       every Nth snapshot should be detailed [10]\n"
 "    --max-snapshots=<N>       maximum number of snapshots recorded [100]\n"
 "    --massif-out-file=<file>  output file name [massif.out.%%p]\n"
@@ -963,7 +968,7 @@ static void update_XCon(XPt* xpt, SSizeT space_delta)
 // limit again, we again cull and then take them even more slowly, and so
 // on.
 
-// Time is measured either in ms or bytes, depending on the --time-unit
+// Time is measured either in i or ms or bytes, depending on the --time-unit
 // option.  It's a Long because it can exceed 32-bits reasonably easily, and
 // because we need to allow negative values to represent unset times.
 typedef Long Time;
@@ -1227,7 +1232,9 @@ static UInt cull_snapshots(void)
 static Time get_time(void)
 {
    // Get current time, in whatever time unit we're using.
-   if (clo_time_unit == TimeMS) {
+   if (clo_time_unit == TimeI) {
+      return guest_instrs_executed;
+   } else if (clo_time_unit == TimeMS) {
       // Some stuff happens between the millisecond timer being initialised
       // to zero and us taking our first snapshot.  We determine that time
       // gap so we can subtract it from all subsequent times so that our
@@ -1774,9 +1781,74 @@ static Bool ms_handle_client_request ( ThreadId tid, UWord* argv, UWord* ret )
 //--- Instrumentation                                      ---//
 //------------------------------------------------------------//
 
+static void add_counter_update(IRSB* sbOut, Int n)
+{
+   #if defined(VG_BIGENDIAN)
+   # define END Iend_BE
+   #elif defined(VG_LITTLEENDIAN)
+   # define END Iend_LE
+   #else
+   # error "Unknown endianness"
+   #endif
+   // Add code to increment 'guest_instrs_executed' by 'n', like this:
+   //   WrTmp(t1, Load64(&guest_instrs_executed))
+   //   WrTmp(t2, Add64(RdTmp(t1), Const(n)))
+   //   Store(&guest_instrs_executed, t2)
+   IRTemp t1 = newIRTemp(sbOut->tyenv, Ity_I64);
+   IRTemp t2 = newIRTemp(sbOut->tyenv, Ity_I64);
+   IRExpr* counter_addr = mkIRExpr_HWord( (HWord)&guest_instrs_executed );
+
+   IRStmt* st1 = IRStmt_WrTmp(t1, IRExpr_Load(END, Ity_I64, counter_addr));
+   IRStmt* st2 =
+      IRStmt_WrTmp(t2,
+                   IRExpr_Binop(Iop_Add64, IRExpr_RdTmp(t1),
+                                           IRExpr_Const(IRConst_U64(n))));
+   IRStmt* st3 = IRStmt_Store(END, counter_addr, IRExpr_RdTmp(t2));
+
+   addStmtToIRSB( sbOut, st1 );
+   addStmtToIRSB( sbOut, st2 );
+   addStmtToIRSB( sbOut, st3 );
+}
+
+static IRSB* ms_instrument2( IRSB* sbIn )
+{
+   Int   i, n = 0;
+   IRSB* sbOut;
+
+   // We increment the instruction count in two places:
+   // - just before any Ist_Exit statements;
+   // - just before the IRSB's end.
+   // In the former case, we zero 'n' and then continue instrumenting.
+   
+   sbOut = deepCopyIRSBExceptStmts(sbIn);
+   
+   for (i = 0; i < sbIn->stmts_used; i++) {
+      IRStmt* st = sbIn->stmts[i];
+      
+      if (!st || st->tag == Ist_NoOp) continue;
+      
+      if (st->tag == Ist_IMark) {
+         n++;
+      } else if (st->tag == Ist_Exit) {
+         if (n > 0) {
+            // Add an increment before the Exit statement, then reset 'n'.
+            add_counter_update(sbOut, n);
+            n = 0;
+         }
+      }
+      addStmtToIRSB( sbOut, st );
+   }
+
+   if (n > 0) {
+      // Add an increment before the SB end.
+      add_counter_update(sbOut, n);
+   }
+   return sbOut;
+}
+
 static
 IRSB* ms_instrument ( VgCallbackClosure* closure,
-                      IRSB* bb_in,
+                      IRSB* sbIn,
                       VexGuestLayout* layout,
                       VexGuestExtents* vge,
                       IRType gWordTy, IRType hWordTy )
@@ -1788,7 +1860,11 @@ IRSB* ms_instrument ( VgCallbackClosure* closure,
       have_started_executing_code = True;
       maybe_take_snapshot(Normal, "startup");
    }
-   return bb_in;
+
+   if      (clo_time_unit == TimeI)  { return ms_instrument2(sbIn); }
+   else if (clo_time_unit == TimeMS) { return sbIn; }
+   else if (clo_time_unit == TimeB)  { return sbIn; }
+   else                              { tl_assert2(0, "bad --time-unit value"); }
 }
 
 
@@ -1816,7 +1892,7 @@ static Char* make_perc(ULong x, ULong y)
 
 //   tl_assert(x <= y);    XXX; put back in later...
 
-// XXX: I'm not confident that VG_(percentify) works as it should...
+   // XXX: I'm not confident that VG_(percentify) works as it should...
    VG_(percentify)(x, y, 2, 6, mbuf);
    // XXX: this is bogus if the denominator was zero -- resulting string is
    // something like "0 --%")
@@ -2103,7 +2179,7 @@ static void ms_pre_clo_init(void)
 {
    VG_(details_name)            ("Massif");
    VG_(details_version)         (NULL);
-   VG_(details_description)     ("a space profiler");
+   VG_(details_description)     ("a heap profiler");
    VG_(details_copyright_author)(
       "Copyright (C) 2003-2007, and GNU GPL'd, by Nicholas Nethercote");
    VG_(details_bug_reports_to)  (VG_BUGS_TO);
index 95a6e8cd45683d2dad932306ff8020e980c3c19e..4b13f3c70598da7daa6b4be1924f491d9fb35dc8 100755 (executable)
@@ -275,6 +275,27 @@ sub max_label_2($$)
     else                       { return sprintf("%5.1f", $szB_scaled); }
 }
 
+# Work out the units for the max value, measured in instructions.
+sub i_max_label($)
+{
+    my ($nI) = @_;
+
+    # We repeat until the number is less than 1000.
+    my $nI_scaled = $nI;
+    my $unit = "i";
+    # Nb: 'k' is the "kilo" (1000) prefix.
+    if ($nI_scaled >= 1000) { $unit = "ki"; $nI_scaled /= 1024; }
+    if ($nI_scaled >= 1000) { $unit = "Mi"; $nI_scaled /= 1024; }
+    if ($nI_scaled >= 1000) { $unit = "Gi"; $nI_scaled /= 1024; }
+    if ($nI_scaled >= 1000) { $unit = "Ti"; $nI_scaled /= 1024; }
+    if ($nI_scaled >= 1000) { $unit = "Pi"; $nI_scaled /= 1024; }
+    if ($nI_scaled >= 1000) { $unit = "Ei"; $nI_scaled /= 1024; }
+    if ($nI_scaled >= 1000) { $unit = "Zi"; $nI_scaled /= 1024; }
+    if ($nI_scaled >= 1000) { $unit = "Yi"; $nI_scaled /= 1024; }
+
+    return (max_label_2($nI, $nI_scaled), $unit);
+}
+
 # Work out the units for the max value, measured in bytes.
 sub B_max_label($)
 {
@@ -284,6 +305,9 @@ sub B_max_label($)
     # each scaling.
     my $szB_scaled = $szB;
     my $unit = "B";
+    # Nb: 'K' or 'k' are acceptable as the "binary kilo" (1024) prefix.
+    # (Strictly speaking, should use "KiB" (kibibyte), "MiB" (mebibyte), etc,
+    # but they're not in common use.)
     if ($szB_scaled >= 1000) { $unit = "KB"; $szB_scaled /= 1024; }
     if ($szB_scaled >= 1000) { $unit = "MB"; $szB_scaled /= 1024; }
     if ($szB_scaled >= 1000) { $unit = "GB"; $szB_scaled /= 1024; }
@@ -508,6 +532,7 @@ sub read_input_file()
     if (0 == $end_time          ) { $end_time           = 1; }
     my $K = $peak_mem_total_szB / $graph_y;
 
+# XXX: remove this?  see 10 lines down...
     # If we leave end_time as is, the final snapshot will spill over past
     # the last column.  So we add a small epsilon to it to prevent this from
     # happening.
@@ -533,9 +558,9 @@ sub read_input_file()
         #   detailed column. 
         my $should_draw_column = 
             (($i == $peak_num) or                            
-             ($is_detaileds[$i] and $graph[$x][0] ne $peak_full_char) or   
-             ($graph[$x][0] ne $peak_full_char and           
-              $graph[$x][0] ne $detailed_full_char));        
+             ($is_detaileds[$i] and $graph[$x][1] ne $peak_full_char) or   
+             ($graph[$x][1] ne $peak_full_char and           
+              $graph[$x][1] ne $detailed_full_char));        
 
         if ($should_draw_column) {
             # If it's detailed, mark the X-axis.  Also choose the full-slot
@@ -543,10 +568,8 @@ sub read_input_file()
             my $full_char;
             if ($i == $peak_num)  {                          
                 $full_char = $peak_full_char;                
-                $graph[$x][0] = $full_char;                  
             } elsif ($is_detaileds[$i])  {    
                 $full_char = $detailed_full_char;
-                $graph[$x][0] = $full_char;                  
             } else {
                 $full_char = $normal_full_char;
             }
@@ -566,9 +589,11 @@ sub read_input_file()
     # Print graph[][].
     #-------------------------------------------------------------------------
     my ($y_label, $y_unit) = B_max_label($peak_mem_total_szB);
-    my ($x_label, $x_unit) = ( $time_unit eq "ms" 
-                             ? t_max_label($end_time) 
-                             : B_max_label($end_time) );
+    my ($x_label, $x_unit);
+    if    ($time_unit eq "i") { ($x_label, $x_unit) = i_max_label($end_time) }
+    elsif ($time_unit eq "s") { ($x_label, $x_unit) = t_max_label($end_time) }
+    elsif ($time_unit eq "B") { ($x_label, $x_unit) = B_max_label($end_time) }
+    else                      { die "bad time_unit: $time_unit\n"; }
 
     printf("    %2s\n", $y_unit);
     for ($y = $graph_y; $y >= 0; $y--) {
@@ -612,7 +637,7 @@ sub read_input_file()
             }
         }
     }
-    print("]\n");
+    print("]\n\n");
 
     #-------------------------------------------------------------------------
     # Print snapshots, from $tmp_file.
index 3f54d4508e4e5937e03a1a99dc18ed2e36152e68..97802683b930c8f7015a37028d74214fdf7dce7b 100644 (file)
@@ -8,6 +8,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        alloc-fns-A.post.exp alloc-fns-A.stderr.exp alloc-fns-A.vgtest \
        alloc-fns-B.post.exp alloc-fns-B.stderr.exp alloc-fns-B.vgtest \
        basic.post.exp basic.stderr.exp basic.vgtest \
+       basic2.post.exp basic2.stderr.exp basic2.vgtest \
        insig.post.exp insig.stderr.exp insig.vgtest \
        big-alloc.post.exp big-alloc.stderr.exp big-alloc.vgtest \
        deep-A.post.exp deep-A.stderr.exp deep-A.vgtest \
index 9a21059addc22eb49a00c8646c90c42d8c334ccf..20b43ca42d3faa1108fe03e2abff26081209f938 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |               :       :       :       :       :       :       :       @
      |       :       :       :       :       :       :       :       :       @
      |       :       :       :       :       :       :       :       :       @
-   0 +-----------------------------------------------------------------------@KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   1.758
 
 Number of snapshots: 10
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 3712260d590f05b0dfacc1cc3716e80d1160480a..bb1c6e9f652a5a6f155c98557d7fe54532b484c0 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |               :       :       :       :       :       :       :       @
      |       :       :       :       :       :       :       :       :       @
      |       :       :       :       :       :       :       :       :       @
-   0 +-----------------------------------------------------------------------@KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   1.758
 
 Number of snapshots: 10
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 8cda5873f78d79dafdd761e927eccf44b5040d65..fbc8286140f826c2fdff625413c59b5ffa86484e 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |     .:::@:::::::::@:::::::::@::::::#:::::::::@:::::::::@:::::::::@.    
      |   .:::::@:::::::::@:::::::::@::::::#:::::::::@:::::::::@:::::::::@::.  
      | .:::::::@:::::::::@:::::::::@::::::#:::::::::@:::::::::@:::::::::@::::.
-   0 +---------@---------@---------@------#---------@---------@---------@---->KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   14.42
 
 Number of snapshots: 73
  Detailed snapshots: [9, 19, 29, 37 (peak), 47, 57, 67]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
diff --git a/massif/tests/basic2.post.exp b/massif/tests/basic2.post.exp
new file mode 100644 (file)
index 0000000..f926c7a
--- /dev/null
@@ -0,0 +1,96 @@
+--------------------------------------------------------------------------------
+Command:            ./basic
+Massif arguments:   --stacks=no --time-unit=B --massif-out-file=massif.out --detailed-freq=1 --max-snapshots=10
+ms_print arguments: massif.out
+--------------------------------------------------------------------------------
+
+
+    KB
+7.312^                                      #                                 
+     |                                      #                                 
+     |                                      #                                 
+     |                                      #                                 
+     |                                      #       .                         
+     |                            @         #       @                         
+     |                            @         #       @                         
+     |                            @         #       @                         
+     |                            @         #       @                         
+     |                    .       @         #       @        @                
+     |                    @       @         #       @        @                
+     |                    @       @         #       @        @                
+     |                    @       @         #       @        @                
+     |                    @       @         #       @        @       .        
+     |                    @       @         #       @        @       @        
+     |         @          @       @         #       @        @       @        
+     |         @          @       @         #       @        @       @        
+     |         @          @       @         #       @        @       @        
+     |         @          @       @         #       @        @       @       @
+     |         @          @       @         #       @        @       @       @
+   0 +----------------------------------------------------------------------->KB
+     0                                                                   13.81
+
+Number of snapshots: 9
+ Detailed snapshots: [0, 1, 2, 3, 4 (peak), 5, 6, 7, 8]
+
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+  0              0                0                0             0            0
+00.00% (0B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+  1          1,872            1,872            1,800            72            0
+96.15% (1,800B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+->96.15% (1,800B) 0x........: main (basic.c:14)
+  
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+  2          3,952            3,952            3,800           152            0
+96.15% (3,800B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+->96.15% (3,800B) 0x........: main (basic.c:14)
+  
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+  3          5,616            5,616            5,400           216            0
+96.15% (5,400B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+->96.15% (5,400B) 0x........: main (basic.c:14)
+  
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+  4          7,488            7,488            7,200           288            0
+96.15% (7,200B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+->96.15% (7,200B) 0x........: main (basic.c:14)
+  
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+  5          9,152            5,824            5,600           224            0
+96.15% (5,600B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+->96.15% (5,600B) 0x........: main (basic.c:14)
+  
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+  6         10,816            4,160            4,000           160            0
+96.15% (4,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+->96.15% (4,000B) 0x........: main (basic.c:14)
+  
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+  7         12,480            2,496            2,400            96            0
+96.15% (2,400B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+->96.15% (2,400B) 0x........: main (basic.c:14)
+  
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+  8         14,144              832              800            32            0
+96.15% (800B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
+->96.15% (800B) 0x........: main (basic.c:14)
+  
diff --git a/massif/tests/basic2.stderr.exp b/massif/tests/basic2.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/massif/tests/basic2.vgtest b/massif/tests/basic2.vgtest
new file mode 100644 (file)
index 0000000..e9d1de4
--- /dev/null
@@ -0,0 +1,4 @@
+prog: basic
+vgopts: --stacks=no --time-unit=B --massif-out-file=massif.out --detailed-freq=1 --max-snapshots=10
+post: perl ../../massif/ms_print massif.out | ../../tests/filter_addresses
+cleanup: rm massif.out
index 75c4d34fc3e7d5be58d344d3e6736e8f0ad27165..af84e2a04cd31fa3a602c437c933feb2acfd1562 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |              :      :      :      :       :      :      :      @      :
      |       :      :      :      :      :       :      :      :      @      :
      |       :      :      :      :      :       :      :      :      @      :
-   0 +----------------------------------------------------------------@------>MB
+   0 +----------------------------------------------------------------------->MB
      0                                                                   100.0
 
 Number of snapshots: 11
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 8fcc672bb97222d591b76e2ef01e0d8eee8808b1..567534f41f8ff65b205b3aad06d8c33fb2fd8555 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |      @                #                  :                 :           
      |      @                #                  :                 :           
      |      @                #                  :                 :           
-   0 +------@----------------#----------------------------------------------->KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   1.242
 
 Number of snapshots: 11
  Detailed snapshots: [2, 5 (peak)]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index c84218a5e8c425ba822675d51b9e5069df2f951f..493afdf6e4ea10273bc6c0f641d8d7c903abc9d9 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |              :      :      :      :       :      :      :      @      :
      |       :      :      :      :      :       :      :      :      @      :
      |       :      :      :      :      :       :      :      :      @      :
-   0 +----------------------------------------------------------------@------>KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   2.031
 
 Number of snapshots: 11
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 2e4ceed245f6539c337d6e42dfa1a0af01b397f0..e3e3efe947837a4b4391e65e6d1ecb7f24b751f5 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |              :      :      :      :       :      :      :      @      :
      |       :      :      :      :      :       :      :      :      @      :
      |       :      :      :      :      :       :      :      :      @      :
-   0 +----------------------------------------------------------------@------>KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   2.031
 
 Number of snapshots: 11
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 06f2a68253fc10274e92a0eaaeb83c1ee9718e31..fc12a5a48497e0c1229f96ff32adb83736187adc 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |              :      :      :      :       :      :      :      @      :
      |       :      :      :      :      :       :      :      :      @      :
      |       :      :      :      :      :       :      :      :      @      :
-   0 +----------------------------------------------------------------@------>KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   2.031
 
 Number of snapshots: 11
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index b5da9226f64a08fec0422e99dfcf86542e2bc25e..5d47fe55fb5592656e70695350a1c3ddc82e1b73 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |              :      :      :      :       :      :      :      @      :
      |       :      :      :      :      :       :      :      :      @      :
      |       :      :      :      :      :       :      :      :      @      :
-   0 +----------------------------------------------------------------@------>KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   2.031
 
 Number of snapshots: 11
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 793b158f96625f4ba3b3c07dd9105ad7423b8616..e9d50df8d9d0823318ce3dfa63024368eb365c81 100755 (executable)
@@ -5,5 +5,5 @@ dir=`dirname $0`
 $dir/../../tests/filter_stderr_basic                |
 
 # Remove "Massif, ..." line and the following copyright line.
-sed "/^Massif, a space profiler./ , /./ d"
+sed "/^Massif, a heap profiler./ , /./ d"
 
index e21b19e34a97b24351e2022271fd78e8ababb908..efe7c09214879f8115d81dd6e8f8961126657ce9 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |# @:::@:::::::::::::::@:::@:::@:::@:::@: ::@:::::::@:::::::@:::::::@::::
      |# @:::@:::::::::::::::@:::@:::@:::@:::@: ::@:::::::@:::::::@:::::::@::::
      |# @:::@:::::::::::::::@:::@:::@:::@:::@: ::@:::::::@:::::::@:::::::@::::
-   0 +#-@---@---------------@---@---@---@---@----@-------@-------@-------@--->KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   182.7
 
 Number of snapshots: 88
  Detailed snapshots: [1 (peak), 3, 8, 26, 31, 36, 41, 46, 52, 62, 72, 82]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index b1e5160acf59bb2a11350a0ed5d4915bf1fef5cd..e71fee1567b72bae263c587d382c84caa222c7ae 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |                                                          : ::::@::::@::
      |                                                          : ::::@::::@::
      |                                                          : ::::@::::@::
-   0 +----------------------------------------------------------------@----@->KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   9.617
 
 Number of snapshots: 24
  Detailed snapshots: [9, 19]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 80e91638ae6301de6b70a63998cb28b5a0df395a..298f5677b3025219015f9bdc5f67ba838977a9dd 100644 (file)
@@ -6,31 +6,32 @@ ms_print arguments: massif.out
 
 
     MB
-2.193^#:                  :  :     @  :   :                                   
-     |#:                  :  :     @  :   :                                   
-     |#:                  :  :     @  :   :                                   
-     |#:                  :. :.  . @. :.  .                                   
-     |#:                  :: ::  : @: :@  :                                   
-     |#:                  :: ::  : @: :@  :                                   
-     |#:                  :: ::  : @: :@  :                                   
-     |#:                  :: ::  : @: :@  :                                   
-     |#:                  :: ::  : @: :@  :                                   
-     |#:                  :: ::  : @: :@  :                                   
-     |#:                  :: ::  : @: :@  : :. :. :. :. :. :. :.  . :. :. :. :
-     |#:                  :: ::  : @: :@  : :: :: :: :: :@ :: ::  : :: :@ :: :
-     |#:..................:: ::  : @: :@  : ::.::.::.:: :@ :: :: .: :: :@ :: :
-     |#::::@:::::::::::::::: ::  : @: :@  : :::::@:::::.:@.::.::.@:.::.:@.::.:
-     |#::::@:::::::::::::::: ::  : @: :@  : :::::@:::::::@:::::::@::::::@:::::
-     |#::::@:::::::::::::::: ::  : @: :@  : :::::@:::::::@:::::::@::::::@:::::
-     |#::::@:::::::::::::::: ::  : @: :@  : :::::@:::::::@:::::::@::::::@:::::
-     |#::::@:::::::::::::::: ::  : @: :@  : :::::@:::::::@:::::::@::::::@:::::
-     |#::::@:::::::::::::::: ::  : @: :@  : :::::@:::::::@:::::::@::::::@:::::
-     |#::::@:::::::::::::::: ::  : @: :@  : :::::@:::::::@:::::::@::::::@:::::
-   0 +#----@----------------@---@--@---@---@-----@-------@-------@------@---->GB
+2.193^#:                  :  :  :  @  :   :                                   
+     |#:                  :  :  :  @  :   :                                   
+     |#:                  :  :  :  @  :   :                                   
+     |#:                  :. :. :. @. :.  .                                   
+     |#:                  :: :: :: @: :@  :                                   
+     |#:                  :: :: :: @: :@  :                                   
+     |#:                  :: :: :: @: :@  :                                   
+     |#:                  :: :: :: @: :@  :                                   
+     |#:                  :: :: :: @: :@  :                                   
+     |#:                  :: :: :: @: :@  :                                   
+     |#:                  :: :: :: @: :@  : :. :. :. :. :. :. :.  . :. :. :. :
+     |#:                  :: :: :: @: :@  : :: :: :: :: :@ :: ::  : :: :@ :: :
+     |#:..................:: :: :: @: :@  : ::.::.::.:: :@ :: :: .: :: :@ :: :
+     |#::::@:::::::::::::::: :: :: @: :@  : :::::@:::::.:@.::.::.@:.::.:@.::.:
+     |#::::@:::::::::::::::: :: :: @: :@  : :::::@:::::::@:::::::@::::::@:::::
+     |#::::@:::::::::::::::: :: :: @: :@  : :::::@:::::::@:::::::@::::::@:::::
+     |#::::@:::::::::::::::: :: :: @: :@  : :::::@:::::::@:::::::@::::::@:::::
+     |#::::@:::::::::::::::: :: :: @: :@  : :::::@:::::::@:::::::@::::::@:::::
+     |#::::@:::::::::::::::: :: :: @: :@  : :::::@:::::::@:::::::@::::::@:::::
+     |#::::@:::::::::::::::: :: :: @: :@  : :::::@:::::::@:::::::@::::::@:::::
+   0 +----------------------------------------------------------------------->GB
      0                                                                   11.15
 
 Number of snapshots: 94
  Detailed snapshots: [1 (peak), 7, 28, 33, 38, 43, 48, 56, 66, 76, 86]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 31ecbb34ee36cd36e79646d9149e8d7dd8d27dfe..ce388856782c1e6dd7117f819700eb5900a1d5ed 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |           :           :     :     #           :           :     :      
      |           :           :     :     #           :           :     :      
      |           :           :     :     #           :           :     :      
-   0 +-----------------------------------#----------------------------------->KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   23.50
 
 Number of snapshots: 10
  Detailed snapshots: [5 (peak)]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 553e37ec1b8f8b25bfcd5674660d6802b18901f3..b8caf841a4d113d4bb2d4a9b4baa7e10c2600082 100644 (file)
@@ -31,6 +31,7 @@ ms_print arguments: massif.out
 
 Number of snapshots: 1
  Detailed snapshots: []
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 332b2bf5025b2e5783381f4c68b21839cc0d2c72..b02f5e7c7d486d576b320c751f324c39d5cd9261 100644 (file)
@@ -31,6 +31,7 @@ ms_print arguments: massif.out
 
 Number of snapshots: 1
  Detailed snapshots: []
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index a57a4f4c8238cafcb70e1725fcd177f6303bf2b8..6b7fec26ff83b28b641997ea944c753d72d1d825 100644 (file)
@@ -31,6 +31,7 @@ ms_print arguments: massif.out
 
 Number of snapshots: 2
  Detailed snapshots: []
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index bdabf1d8cf5d96189248c462db12bbf4e31e5a63..179ef2979ab8653b24b79f883d145f63b9cc845e 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |           :           :     :     #           :           :     :      
      |           :           :     :     #           :           :     :      
      |           :           :     :     #           :           :     :      
-   0 +-----------------------------------#----------------------------------->KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   23.50
 
 Number of snapshots: 10
  Detailed snapshots: [5 (peak)]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index d3bd30c9aab380f9e7fa0f2041690cf5c8344872..89d207e58f66ec878133a4c3fbccc0bf26fb9b0b 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |          @  :@  @   @  @:  @  :@  @   @  @:  @  :@  @   @  @:  @  :@  #
      |      @.  @  :@  @   @  @:  @  :@  @   @  @:  @  :@  @   @  @:  @  :@  #
      |   @  @:  @  :@  @   @  @:  @  :@  @   @  @:  @  :@  @   @  @:  @  :@  #
-   0 +---@--@---@---@--@---@--@---@---@--@---@--@---@---@--@---@--@---@---@--#KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   19.69
 
 Number of snapshots: 81
  Detailed snapshots: [3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, 71, 75, 79 (peak)]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index f40f6f78ba7f360ad8081ae8a92d541d2ee315ad..3e9cee60bc6091291ddc6586c0818ddbf14d49c4 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |          @  :@  @   @  @:  @  :@  @   :  @:  :  :@  :   @  ::  @  ::  #
      |      @.  @  :@  @   @  @:  @  :@  @   :  @:  :  :@  :   @  ::  @  ::  #
      |   @  @:  @  :@  @   @  @:  @  :@  @   :  @:  :  :@  :   @  ::  @  ::  #
-   0 +---@--@---@---@--@---@--@---@---@--@------@-------@------@------@------#KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   19.69
 
 Number of snapshots: 76
  Detailed snapshots: [3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 46, 53, 60, 67, 74 (peak)]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 3c14c5b612d039ec2557aad5cb21318f8dcd6658..fc0a7fb8f3f1b4bfe9a6673e88160909cbcf0bd0 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: --threshold=0 massif.out
      |                       @           #                                    
      |                       @           #                                    
      |                       @           #                                    
-   0 +-----------------------@-----------#----------------------------------->KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   1.172
 
 Number of snapshots: 8
  Detailed snapshots: [3, 6 (peak)]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 07c444e0871debc8b7df2e2ff28e5d58c9e047da..ae2bef918b1538605e698aa79887247d30a0a5b5 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out --threshold=0
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
-   0 +-----------------------------------------------------------------------@KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   39.06
 
 Number of snapshots: 10
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 550aa20db6acff1e4df65230f21f408f6a09315f..ab33bd744ea0ad72f4a808800f6f4a5c4c26569c 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out --threshold=10
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
-   0 +-----------------------------------------------------------------------@KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   39.06
 
 Number of snapshots: 10
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 4ff75317e9d0271b1edc3838862e442c37b89a68..53d71e792ab39bbd3b495c2c4e1f7fd32657220f 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out --threshold=0
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
-   0 +-----------------------------------------------------------------------@KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   39.06
 
 Number of snapshots: 10
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index ad56e908ad6984654582aea0e5fa8250c358dcf3..5c2139ef0e20cc3cf7d403baa35c4a79e42a81c7 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out --threshold=10
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
-   0 +-----------------------------------------------------------------------@KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   39.06
 
 Number of snapshots: 10
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index cb5ee8fa6d2c64653d0663cba336722bc85c80cc..8e8edc6ca12b4609ba9fe49a21b0218e757308e7 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out --threshold=0
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
-   0 +-----------------------------------------------------------------------@KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   39.06
 
 Number of snapshots: 10
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 272e205841b91e667bce288a63da3526c2ee7b45..d67b8f70baf0c9f488bba9806c4903982a127520 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out --threshold=10
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
      |                                           :     : :::   :             @
-   0 +-----------------------------------------------------------------------@KB
+   0 +----------------------------------------------------------------------->KB
      0                                                                   39.06
 
 Number of snapshots: 10
  Detailed snapshots: [9]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index 979898272472ecbc562730460ccdb0151a5660e3..faffb809626a0d43bb68e78c5df1d96c5a41e936 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: --threshold=0 massif.out
      |                                                                        
      |                                                                        
      |                                                                        
-   0 +@---------------------------------------------------------------------->B
+   0 +----------------------------------------------------------------------->B
      0                                                                       1
 
 Number of snapshots: 21
  Detailed snapshots: [9, 19]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------
index ba2fea8474e2f15e158d09ff6e5593d146559e35..75d8e7d03124a9a1959135a97fca89b6345ceee7 100644 (file)
@@ -26,11 +26,12 @@ ms_print arguments: massif.out
      |                                                                        
      |                                                                        
      |                                                                        
-   0 +@---------------------------------------------------------------------->B
+   0 +----------------------------------------------------------------------->B
      0                                                                       1
 
 Number of snapshots: 21
  Detailed snapshots: [9, 19]
+
 --------------------------------------------------------------------------------
   n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
 --------------------------------------------------------------------------------