First, we must install Pintool:

http://www.pintool.org/

In the folder source/tools/SimpleExamples we create a CPP file, for example MyMallocTrace.cpp:

/* ===================================================================== */
/*
  @ORIGINAL_AUTHOR: Robert Cohn
  @AUTHOR: José L. Risco-Martín
*/
 
/* ===================================================================== */
/*! @file
 *  This file contains an ISA-portable PIN tool for tracing calls to malloc
 */
 
#include "pin.H"
#include <iostream>
#include <fstream>
#include <time.h>
 
/* ===================================================================== */
/* Names of malloc and free */
/* ===================================================================== */
#if defined(TARGET_MAC)
#define MALLOC "_malloc"
#define FREE "_free"
#else
#define MALLOC "malloc"
#define FREE "free"
#endif
 
/* ===================================================================== */
/* Global Variables */
/* ===================================================================== */
 
std::ofstream TraceFile;
 
/* ===================================================================== */
/* Commandline Switches */
/* ===================================================================== */
 
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
	"o", "MyMallocTrace.mem", "specify trace file name");
 
/* ===================================================================== */
/* Print Help Message                                                	*/
/* ===================================================================== */
 
INT32 Usage()
{
	cerr <<
    	"This tool produces a trace of calls to malloc.\n"
    	"\n";
 
	cerr << KNOB_BASE::StringKnobSummary();
 
	cerr << endl;
 
	return -1;
}
 
/* ===================================================================== */
 
VOID MallocBefore(CHAR * name, ADDRINT size)
{
	TraceFile << name << " " << (1.0*clock())/CLOCKS_PER_SEC << " " << size;
}
 
/* ===================================================================== */
 
VOID FreeBefore(CHAR * name, ADDRINT addr)
{
	TraceFile << name << " " << (1.0*clock())/CLOCKS_PER_SEC << " " << addr << endl;
}
 
/* ===================================================================== */
 
VOID MallocAfter(ADDRINT addr)
{
	TraceFile << " " << addr << endl;
}
 
/* ===================================================================== */
 
VOID Image(IMG img, VOID *v)
{
	RTN mallocRtn = RTN_FindByName(img, MALLOC);
	if (RTN_Valid(mallocRtn))
	{
    	RTN_Open(mallocRtn);
    	RTN_InsertCall(mallocRtn, IPOINT_BEFORE, (AFUNPTR)MallocBefore, IARG_ADDRINT, MALLOC, IARG_G_ARG0_CALLEE, IARG_END);
    	RTN_InsertCall(mallocRtn, IPOINT_AFTER, (AFUNPTR)MallocAfter, IARG_G_RESULT0, IARG_END);
    	RTN_Close(mallocRtn);
	}
 
	RTN freeRtn = RTN_FindByName(img, FREE);
	if (RTN_Valid(freeRtn))
	{
    	RTN_Open(freeRtn);
    	RTN_InsertCall(freeRtn, IPOINT_BEFORE, (AFUNPTR)FreeBefore, IARG_ADDRINT, FREE, IARG_G_ARG0_CALLEE, IARG_END);
    	RTN_Close(freeRtn);
	}
}
 
/* ===================================================================== */
 
VOID Fini(INT32 code, VOID *v)
{
	TraceFile.close();
}
 
/* ===================================================================== */
/* Main                                                              	*/
/* ===================================================================== */
 
int main(int argc, char *argv[])
{
	PIN_InitSymbols();
 
	if( PIN_Init(argc,argv) )
	{
    	return Usage();
	}
 
 
	TraceFile.open(KnobOutputFile.Value().c_str());
 
	//TraceFile << hex;
	//TraceFile.setf(ios::showbase);
 
	//cout << hex;
	//cout.setf(ios::showbase);
 
	IMG_AddInstrumentFunction(Image, 0);
	PIN_AddFiniFunction(Fini, 0);
 
	// Never returns
	PIN_StartProgram();
 
	return 0;
}
 
/* ===================================================================== */
/* eof */
/* ===================================================================== */

Now we edit the makefile (in the same folder). We insert the CPP created:

… TOOL_ROOTS = dcache edgcnt pinatrace trace icount inscount2_mt opcodemix malloctrace MyMallocTrace calltrace jumpmix toprtn catmix regmix ilenmix coco

… TEST_TOOLS_ROOTS = dcache edgcnt pinatrace trace icount opcodemix malloctrace MyMallocTrace calltrace jumpmix toprtn catmix regmix inscount2_mt

In the same folder we compile:

make dir MyMallocTrace.so.test

And we execute any binary file with PIN:

../../../pin -t obj-ia32/MyMallocTrace.so – boxed-sim

The result is a profiling report called: MyMallocTrace.mem

Now generate the grammar rules for this profiling report:

java -jar GrammarGenerator.jar <PathToProfilingReport>

where:

<ProfilingReport>: Relative path to the profiling report including malloc/free entries

Now download GEA (DmmExplorer.jar):

java -jar DmmExplorer.jar -p <PathToProfilingReport> [-d <KINGSLEY,LEA,FIBONACCI,SEGREGATED,EXACT,GE> (default: KINGSLEY)] [-g <NumberOfGenerations> (default: 100)] [-i <NumberOfIndividuals> (default: 60)] [-o <GlobalOptimum>]

java -jar DmmExplorer.jar -p boxed-sim.mem -d LEA,GE -g 80 -i 30

where:

-p <ProfilingReport>: Relative path to the profiling report including malloc/free entries

-d <KINGSLEY,LEA,FIBONACCI,SEGREGATED,EXACT,GE>: Is the DMM simulator selected. GE will find a custom DMM using Grammatical evolution )(a .bnf file is needed in the same path that the profiling report).

-g <NumberOfGenerations>: Number of generations for GE (default is 100)

-i <NumberOfIndividuals>: Number of individuals for GE (default is 60)

-o <GlobalOptimum>: GE stops when GlobalOptimum is reached (default is 0.0)

If using GE, you will obtain two files (mtr and map extension). The map file is a description of the resultant DMM that can be implemented with the real DMM library. The second file (.mtr extension) contains all the metrics obtained with the GE algorithm.