|
From: <sv...@va...> - 2005-12-30 22:40:08
|
Author: njn
Date: 2005-12-30 22:39:58 +0000 (Fri, 30 Dec 2005)
New Revision: 5462
Log:
Add a --trace-mem option to Lackey to print out a memory access trace, if
only so people will stop asking how to do it.
Modified:
trunk/lackey/docs/lk-manual.xml
trunk/lackey/lk_main.c
Modified: trunk/lackey/docs/lk-manual.xml
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/lackey/docs/lk-manual.xml 2005-12-30 15:02:49 UTC (rev 5461)
+++ trunk/lackey/docs/lk-manual.xml 2005-12-30 22:39:58 UTC (rev 5462)
@@ -4,7 +4,7 @@
=20
<chapter id=3D"lk-manual" xreflabel=3D"Lackey">
=20
-<title>Lackey: a very simple profiler</title>
+<title>Lackey: a simple profiler and memory tracer</title>
=20
<para>To use this tool, you must specify
<computeroutput>--tool=3Dlackey</computeroutput> on the Valgrind
@@ -71,6 +71,16 @@
"F32", "F64", and "V128").</para>
</listitem>
=20
+ <listitem>
+ <para>When command line option
+ <computeroutput>--trace-mem=3Dyes</computeroutput> is
+ specified, it prints out the size and address of almost every load a=
nd
+ store made by the program. See Section 3.3.7 of Nicholas Nethercote=
's
+ PhD dissertation "Dynamic Binary Analysis and Instrumentation", 2004=
,
+ for details about the few loads and stores that it misses, and other
+ caveats about the accuracy of the address trace.</para>
+ </listitem>
+
</orderedlist>
=20
</listitem>
Modified: trunk/lackey/lk_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/lackey/lk_main.c 2005-12-30 15:02:49 UTC (rev 5461)
+++ trunk/lackey/lk_main.c 2005-12-30 22:39:58 UTC (rev 5462)
@@ -29,6 +29,27 @@
The GNU General Public License is contained in the file COPYING.
*/
=20
+// This tool shows how to do some basic instrumentation.
+//
+// In particular, if you are interested in tracing every load and store =
a
+// program does, use the --trace-mem=3Dyes option. Please note that the
+// address trace is good, but not perfect; see Section 3.3.7 of Nichola=
s
+// Nethercote's PhD dissertation "Dynamic Binary Analysis and
+// Instrumentation", 2004, for details about the few loads and stores th=
at
+// it misses, and other caveats about the accuracy of the address trace.
+//
+// If you want to modify how the memory traces are printed/gathered, loo=
k at
+// the code that is controlled by the variable 'lk_clo_trace_mem' and th=
e
+// functions 'trace_load()' and 'trace_mem'.. With a bit of effort you
+// should be able to see which other bits of code can be removed, if tha=
t's
+// what you want. If you want to do more complex modifications, please =
read
+// VEX/pub/libvex_ir.h to understand the intermediate representation.
+//
+// For further inspiration, you should look at cachegrind/cg_main.c whic=
h
+// handles memory accesses in a more sophisticated way -- it groups them
+// together for processing into twos and threes so that fewer C calls ar=
e
+// made and things run faster.
+
#include "pub_tool_basics.h"
#include "pub_tool_tooliface.h"
#include "pub_tool_libcassert.h"
@@ -47,6 +68,9 @@
* with command line option --detailed-counts. */
static Bool lk_clo_detailed_counts =3D False;
=20
+/* If true, print the trace of loads and stores. Set with --trace-mem. =
*/
+static Bool lk_clo_trace_mem =3D False;
+
/***********************************************************************
* Implement the needs_command_line_options for Valgrind.
**********************************************************************/
@@ -55,6 +79,7 @@
{
VG_STR_CLO(arg, "--fnname", lk_clo_fnname)
else VG_BOOL_CLO(arg, "--detailed-counts", lk_clo_detailed_counts)
+ else VG_BOOL_CLO(arg, "--trace-mem", lk_clo_trace_mem)
else
return False;
=20
@@ -88,7 +113,6 @@
static ULong n_Jccs =3D 0;
static ULong n_Jccs_untaken =3D 0;
=20
-__attribute__((unused))
static void add_one_func_call(void)
{
n_func_calls++;
@@ -104,13 +128,11 @@
n_BBs_completed++;
}
=20
-__attribute__((unused))
static void add_one_IRStmt(void)
{
n_IRStmts++;
}
=20
-__attribute__((unused))
static void add_one_guest_instr(void)
{
n_guest_instrs++;
@@ -224,6 +246,20 @@
=20
=20
/***********************************************************************
+ * Data and helpers related to --trace-mem. =20
+ **********************************************************************/
+
+static VG_REGPARM(2) void trace_load(Addr addr, SizeT size)
+{
+ VG_(printf)("load : %p, %d\n", addr, size);
+}
+
+static VG_REGPARM(2) void trace_store(Addr addr, SizeT size)
+{
+ VG_(printf)("store: %p, %d\n", addr, size);
+}
+
+/***********************************************************************
* Implement the basic_tool_funcs for Valgrind.
**********************************************************************/
=20
@@ -246,6 +282,9 @@
IRBB* bb;
Char fnname[100];
IRType type;
+ IRExpr** argv;
+ IRExpr* addr_expr;
+ IRExpr* size_expr;
=20
if (gWordTy !=3D hWordTy) {
/* We don't currently support this case. */
@@ -345,6 +384,19 @@
* constrains them to being flat SSA-style.
*/
case Ist_Store:
+ // Add a call to trace_store() if --trace-mem=3Dyes.
+ if (lk_clo_trace_mem) {
+ addr_expr =3D st->Ist.Store.addr;
+ size_expr =3D mkIRExpr_HWord(=20
+ sizeofIRType(
+ typeOfIRExpr(bb->tyenv, st->Ist.Store.dat=
a)));
+ argv =3D mkIRExprVec_2( addr_expr, size_expr );
+ di =3D unsafeIRDirty_0_N( /*regparms*/2,=20
+ "trace_store",
+ VG_(fnptr_to_fnentry)( trace_stor=
e ),=20
+ argv );
+ addStmtToIRBB( bb, IRStmt_Dirty(di) );
+ }
if (lk_clo_detailed_counts) {
type =3D typeOfIRExpr(bb->tyenv, st->Ist.Store.data);
tl_assert(type !=3D Ity_INVALID);
@@ -354,6 +406,20 @@
break;
=20
case Ist_Tmp:
+ // Add a call to trace_load() if --trace-mem=3Dyes.
+ if (lk_clo_trace_mem) {
+ IRExpr* data =3D st->Ist.Tmp.data;
+ if (data->tag =3D=3D Iex_Load) {
+ addr_expr =3D data->Iex.Load.addr;
+ size_expr =3D mkIRExpr_HWord( sizeofIRType(data->Iex.L=
oad.ty) );
+ argv =3D mkIRExprVec_2( addr_expr, size_expr );
+ di =3D unsafeIRDirty_0_N( /*regparms*/2,=20
+ "trace_load",
+ VG_(fnptr_to_fnentry)( trace_l=
oad ),=20
+ argv );
+ addStmtToIRBB( bb, IRStmt_Dirty(di) );
+ }
+ }
if (lk_clo_detailed_counts) {
IRExpr* expr =3D st->Ist.Tmp.data;
type =3D typeOfIRExpr(bb->tyenv, expr);
|