I have a following pin tool, say trace.cpp
(exactly as is in a pin tool manual):
#include "pin.H"
#include <iostream>
#include <fstream>
/* ===================================================================== */
/* 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", "malloctrace.out", "specify trace file name");
/* ===================================================================== */
/* ===================================================================== */
/* Analysis routines */
/* ===================================================================== */
VOID Arg1Before(CHAR * name, ADDRINT size)
{
std::cout << name << "(" << size << ")" << endl;
}
VOID MallocAfter(ADDRINT ret)
{
std::cout << " returns " << ret << endl;
}
/* ===================================================================== */
/* Instrumentation routines */
/* ===================================================================== */
VOID Image(IMG img, VOID *v)
{
// Instrument the malloc() and free() functions. Print the input argument
// of each malloc() or free(), and the return value of malloc().
//
// Find the malloc() function.
RTN mallocRtn = RTN_FindByName(img, MALLOC);
if (RTN_Valid(mallocRtn))
{
RTN_Open(mallocRtn);
// Instrument malloc() to print the input argument value and the return value.
RTN_InsertCall(mallocRtn, IPOINT_BEFORE, (AFUNPTR)Arg1Before,
IARG_ADDRINT, MALLOC,
IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
IARG_END);
RTN_InsertCall(mallocRtn, IPOINT_AFTER, (AFUNPTR)MallocAfter,
IARG_FUNCRET_EXITPOINT_VALUE, IARG_END);
RTN_Close(mallocRtn);
}
// Find the free() function.
RTN freeRtn = RTN_FindByName(img, FREE);
if (RTN_Valid(freeRtn))
{
RTN_Open(freeRtn);
// Instrument free() to print the input argument value.
RTN_InsertCall(freeRtn, IPOINT_BEFORE, (AFUNPTR)Arg1Before,
IARG_ADDRINT, FREE,
IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
IARG_END);
RTN_Close(freeRtn);
}
}
/* ===================================================================== */
VOID Fini(INT32 code, VOID *v)
{
TraceFile.close();
}
/* ===================================================================== */
/* Print Help Message */
/* ===================================================================== */
INT32 Usage()
{
cerr << "This tool produces a trace of calls to malloc." << endl;
cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
return -1;
}
/* ===================================================================== */
/* Main */
/* ===================================================================== */
int main(int argc, char *argv[])
{
// Initialize pin & symbol manager
PIN_InitSymbols();
if( PIN_Init(argc,argv) )
{
return Usage();
}
// Write to a file since cout and cerr maybe closed by the application
TraceFile.open(KnobOutputFile.Value().c_str());
TraceFile << hex;
TraceFile.setf(ios::showbase);
// Register Image to be called to instrument functions.
IMG_AddInstrumentFunction(Image, 0);
PIN_AddFiniFunction(Fini, 0);
// Never returns
PIN_StartProgram();
return 0;
}
(The only variation is that it prints the instead of storing it in the output file)
I have a following c code example - example.c
:
#include <stdio.h>
#include <stdlib.h>
struct A {
int x[10];
int y[1];
};
int main()
{
struct A *ptr = calloc(1, sizeof(struct A));
ptr->x[10] = 4;
printf("%i\n", ptr->x[10]);
ptr = realloc(ptr, sizeof(int));
ptr->x[10] = 4;
printf("%i\n", ptr->x[10]);
free(ptr);
return 0;
}
When I run it with the pin tool, it produces the following output:
$ pin -t obj-intel64/trace.so -- ./example.o | tail
returns 139865991781744
malloc(272)
returns 139865991785984
malloc(44)
returns 33456736
malloc(4096)
returns 33456800
free(33456736)
4
4
Notice the couple of malloc
calls:
malloc(44)
malloc(4096)
It detects the first one perfectly (notice calloc call in the c code), but it detects 4096 for realloc (correct me if I'm wrong here). But, I believe it supposed to detect 4 (sizeof int) instead.
Where am I going wrong? Is there any way by which the correct size can be detected (or maybe I am missing something here)?