Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save reactormonk/3fa9390e62c53427fe2e8a96d509169e to your computer and use it in GitHub Desktop.
Save reactormonk/3fa9390e62c53427fe2e8a96d509169e to your computer and use it in GitHub Desktop.
valgrind patch
From 3c18119cd72d7f101190ca28fd89f3181296ed7b Mon Sep 17 00:00:00 2001
From: Simon Hafner <simon.hafner@iohk.io>
Date: Fri, 10 Jul 2020 17:21:09 +0200
Subject: [PATCH] Add client requests to massif to trigger snapshots
---
massif/Makefile.am | 3 ++
massif/massif.h | 92 ++++++++++++++++++++++++++++++++++++++++++++++
massif/ms_main.c | 36 +++++++++++++++---
3 files changed, 125 insertions(+), 6 deletions(-)
create mode 100644 massif/massif.h
diff --git a/massif/Makefile.am b/massif/Makefile.am
index f631831b2..87d588bbd 100644
--- a/massif/Makefile.am
+++ b/massif/Makefile.am
@@ -10,6 +10,9 @@ EXTRA_DIST = \
bin_SCRIPTS = ms_print
+pkginclude_HEADERS = \
+ massif.h
+
#----------------------------------------------------------------------------
# massif-<platform>
#----------------------------------------------------------------------------
diff --git a/massif/massif.h b/massif/massif.h
new file mode 100644
index 000000000..fd4d2fa81
--- /dev/null
+++ b/massif/massif.h
@@ -0,0 +1,92 @@
+/*
+ ----------------------------------------------------------------
+
+ Notice that the following BSD-style license applies to this one
+ file (callgrind.h) only. The rest of Valgrind is licensed under the
+ terms of the GNU General Public License, version 2, unless
+ otherwise indicated. See the COPYING file in the source
+ distribution for details.
+
+ ----------------------------------------------------------------
+
+ This file is part of callgrind, a valgrind tool for cache simulation
+ and call tree tracing.
+
+ Copyright (C) 2003-2017 Josef Weidendorfer. All rights reserved.
+ Copyright (C) 2020-2020 Simon Hafner. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+ 3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+ 4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ----------------------------------------------------------------
+
+ Notice that the above BSD-style license applies to this one file
+ (callgrind.h) only. The entire rest of Valgrind is licensed under
+ the terms of the GNU General Public License, version 2. See the
+ COPYING file in the source distribution for details.
+
+ ----------------------------------------------------------------
+*/
+
+#ifndef __MASSIF_H
+#define __MASSIF_H
+
+#include "valgrind.h"
+
+/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
+ This enum comprises an ABI exported by Valgrind to programs
+ which use client requests. DO NOT CHANGE THE ORDER OF THESE
+ ENTRIES, NOR DELETE ANY -- add new ones at the end.
+ */
+
+typedef
+ enum {
+ VG_USERREQ__MAKE_SNAPSHOT = VG_USERREQ_TOOL_BASE('M','S'),
+ VG_USERREQ__MAKE_DETAILED_SNAPSHOT
+ } Vg_MassifClientRequest;
+
+/* Return values:
+ 0 if not running on valgrind
+ 1 success
+*/
+#define VALGRIND_MAKE_SNAPSHOT(filename) \
+ (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
+ VG_USERREQ__MAKE_SNAPSHOT, \
+ filename, \
+ 0, 0, 0, 0 )
+
+#define VALGRIND_MAKE_DETAILED_SNAPSHOT(filename) \
+ (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
+ VG_USERREQ__MAKE_DETAILED_SNAPSHOT, \
+ filename, \
+ 0, 0, 0, 0 )
+
+#endif /* __MASSIF_H */
\ No newline at end of file
diff --git a/massif/ms_main.c b/massif/ms_main.c
index f022621ea..5146f1605 100644
--- a/massif/ms_main.c
+++ b/massif/ms_main.c
@@ -173,6 +173,7 @@ Number of snapshots: 50
#include "pub_tool_gdbserver.h"
#include "pub_tool_clreq.h" // For {MALLOC,FREE}LIKE_BLOCK
+#include "massif.h"
//------------------------------------------------------------*/
//--- Overview of operation ---*/
@@ -278,6 +279,11 @@ static ULong total_allocs_deallocs_szB = 0;
//
static Bool have_started_executing_code = False;
+// Whether to take automatic snapshots. Useful if you want to trigger
+// snapshots via client requests.
+// TODO make this configurable somehow
+static Bool take_automatic_snapshots = False;
+
//------------------------------------------------------------//
//--- Alloc fns ---//
//------------------------------------------------------------//
@@ -991,6 +997,8 @@ maybe_take_snapshot(SnapshotKind kind, const HChar* what)
// declaration in /usr/include/time.h on Darwin.
Time my_time = get_time();
+ if (!take_automatic_snapshots) { return; }
+
switch (kind) {
case Normal:
// Only do a snapshot if it's time.
@@ -1624,6 +1632,7 @@ static void print_monitor_help ( void )
/* Forward declaration.
return True if request recognised, False otherwise */
static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req);
+static Bool handle_snapshot_monitor_command (const HChar *filename, Bool detailed);
static Bool ms_handle_client_request ( ThreadId tid, UWord* argv, UWord* ret )
{
switch (argv[0]) {
@@ -1658,6 +1667,14 @@ static Bool ms_handle_client_request ( ThreadId tid, UWord* argv, UWord* ret )
*ret = 0;
return handled;
}
+ case VG_USERREQ__MAKE_SNAPSHOT: {
+ const HChar *filename = (HChar*)argv[1];
+ return handle_snapshot_monitor_command(filename, /*detailed*/False);
+ }
+ case VG_USERREQ__MAKE_DETAILED_SNAPSHOT: {
+ const HChar *filename = (HChar*)argv[1];
+ return handle_snapshot_monitor_command(filename, /*detailed*/True);
+ }
default:
*ret = 0;
@@ -1816,16 +1833,14 @@ static void write_snapshots_array_to_file(void)
VG_(free)(massif_out_file);
}
-static void handle_snapshot_monitor_command (const HChar *filename,
+static Bool handle_snapshot_monitor_command (const HChar *filename,
Bool detailed)
{
Snapshot snapshot;
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;
+ return False;
}
clear_snapshot(&snapshot, /* do_sanity_check */ False);
@@ -1835,6 +1850,7 @@ static void handle_snapshot_monitor_command (const HChar *filename,
&snapshot,
1);
delete_snapshot(&snapshot);
+ return True;
}
static void handle_all_snapshots_monitor_command (const HChar *filename)
@@ -1893,13 +1909,21 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
case 1: { /* snapshot */
HChar* filename;
filename = VG_(strtok_r) (NULL, " ", &ssaveptr);
- handle_snapshot_monitor_command (filename, False /* detailed */);
+ Bool running = handle_snapshot_monitor_command (filename, False /* detailed */);
+ if (!running) {
+ VG_(gdb_printf)
+ ("error: cannot take snapshot before execution has started\n");
+ }
return True;
}
case 2: { /* detailed_snapshot */
HChar* filename;
filename = VG_(strtok_r) (NULL, " ", &ssaveptr);
- handle_snapshot_monitor_command (filename, True /* detailed */);
+ Bool running = handle_snapshot_monitor_command (filename, True /* detailed */);
+ if (!running) {
+ VG_(gdb_printf)
+ ("error: cannot take snapshot before execution has started\n");
+ }
return True;
}
case 3: { /* all_snapshots */
--
2.27.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment