342353 - Allow dumping full massif output while valgrind is still running

Patch from Andre Goddard Rosa



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14992 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/NEWS b/NEWS
index efb85ea..66689ff 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,10 @@
 
 * Memcheck:
 
+* Massif:
+  New monitor command 'all_snapshots <filename>' that dumps all snapshots
+  taken so far.
+
 * Helgrind:
 
 * Callgrind:
@@ -84,6 +88,7 @@
 342038  Unhandled syscalls on aarch64 (mbind/get/set_mempolicy)
 342063  wrong format specifier for test mcblocklistsearch in gdbserver_tests
 342221  socket connect false positive uninit memory for unknown af family
+342353  Allow dumping full massif output while valgrind is still running
 342603  Add I2C_SMBUS ioctl support
 342635  OS X 10.10 (Yosemite) - missing system calls and fcntl code
 342795  Internal glibc __GI_mempcpy call should be intercepted
diff --git a/gdbserver_tests/mssnapshot.stderrB.exp b/gdbserver_tests/mssnapshot.stderrB.exp
index 62c47b0..93ba9c9 100644
--- a/gdbserver_tests/mssnapshot.stderrB.exp
+++ b/gdbserver_tests/mssnapshot.stderrB.exp
@@ -17,8 +17,11 @@
 massif monitor commands:
   snapshot [<filename>]
   detailed_snapshot [<filename>]
-       takes a snapshot (or a detailed snapshot)
-       and saves it in <filename>
+      takes a snapshot (or a detailed snapshot)
+      and saves it in <filename>
+             default <filename> is massif.vgdb.out
+  all_snapshots [<filename>]
+      saves all snapshot(s) taken so far in <filename>
              default <filename> is massif.vgdb.out
 monitor command request to kill this process
 Remote connection closed
diff --git a/gdbserver_tests/mssnapshot.stdinB.gdb b/gdbserver_tests/mssnapshot.stdinB.gdb
index 5f4257a..69b10e1 100644
--- a/gdbserver_tests/mssnapshot.stdinB.gdb
+++ b/gdbserver_tests/mssnapshot.stdinB.gdb
@@ -16,6 +16,7 @@
 # test non detailed and detailed snapshot
 monitor snapshot
 monitor detailed_snapshot
+monitor all_snapshots
 #
 #
 monitor v.kill
diff --git a/massif/docs/ms-manual.xml b/massif/docs/ms-manual.xml
index 484d3ea..4c555a9 100644
--- a/massif/docs/ms-manual.xml
+++ b/massif/docs/ms-manual.xml
@@ -877,6 +877,12 @@
     &lt;filename&gt; (default massif.vgdb.out).
     </para>
   </listitem>
+  <listitem>
+    <para><varname>all_snapshots [&lt;filename&gt;]</varname>
+    requests to take all captured snapshots so far and save them in the given
+    &lt;filename&gt; (default massif.vgdb.out).
+    </para>
+  </listitem>
 </itemizedlist>
 </sect1>
 
diff --git a/massif/ms_main.c b/massif/ms_main.c
index 24fb18f..5053c4f 100644
--- a/massif/ms_main.c
+++ b/massif/ms_main.c
@@ -37,10 +37,7 @@
 //   - preset column widths for stats are not generic
 //   - preset column headers are not generic
 //   - "Massif arguments:" line is not generic
-// - do snapshots on client requests
-//   - (Michael Meeks): have an interactive way to request a dump
-//     (callgrind_control-style)
-//     - "profile now"
+// - do snapshots on some specific client requests
 //     - "show me the extra allocations since the last snapshot"
 //     - "start/stop logging" (eg. quickly skip boring bits)
 // - Add ability to draw multiple graphs, eg. heap-only, stack-only, total.
@@ -1956,8 +1953,11 @@
    VG_(gdb_printf) ("massif monitor commands:\n");
    VG_(gdb_printf) ("  snapshot [<filename>]\n");
    VG_(gdb_printf) ("  detailed_snapshot [<filename>]\n");
-   VG_(gdb_printf) ("       takes a snapshot (or a detailed snapshot)\n");
-   VG_(gdb_printf) ("       and saves it in <filename>\n");
+   VG_(gdb_printf) ("      takes a snapshot (or a detailed snapshot)\n");
+   VG_(gdb_printf) ("      and saves it in <filename>\n");
+   VG_(gdb_printf) ("             default <filename> is massif.vgdb.out\n");
+   VG_(gdb_printf) ("  all_snapshots [<filename>]\n");
+   VG_(gdb_printf) ("      saves all snapshot(s) taken so far in <filename>\n");
    VG_(gdb_printf) ("             default <filename> is massif.vgdb.out\n");
    VG_(gdb_printf) ("\n");
 }
@@ -2337,6 +2337,20 @@
    delete_snapshot(&snapshot);
 }
 
+static void handle_all_snapshots_monitor_command (const HChar *filename)
+{
+   if (!clo_pages_as_heap && !have_started_executing_code) {
+      // See comments of variable have_started_executing_code.
+      VG_(gdb_printf) 
+         ("error: cannot take snapshot before execution has started\n");
+      return;
+   }
+
+   write_snapshots_to_file ((filename == NULL) ? 
+                            "massif.vgdb.out" : filename,
+                            snapshots, next_snapshot_i);
+}
+
 static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
 {
    HChar* wcmd;
@@ -2346,7 +2360,7 @@
    VG_(strcpy) (s, req);
 
    wcmd = VG_(strtok_r) (s, " ", &ssaveptr);
-   switch (VG_(keyword_id) ("help snapshot detailed_snapshot", 
+   switch (VG_(keyword_id) ("help snapshot detailed_snapshot all_snapshots", 
                             wcmd, kwd_report_duplicated_matches)) {
    case -2: /* multiple matches */
       return True;
@@ -2367,6 +2381,12 @@
       handle_snapshot_monitor_command (filename, True /* detailed */);
       return True;
    }
+   case  3: { /* all_snapshots */
+      HChar* filename;
+      filename = VG_(strtok_r) (NULL, " ", &ssaveptr);
+      handle_all_snapshots_monitor_command (filename);
+      return True;
+   }
    default: 
       tl_assert(0);
       return False;