以及代码
#include "pin.H"
#include <iostream>
#include <fstream>
#include <map>
#pragma GCC diagnostic error "-std=c++11"
#define MALLOC "malloc"
#define FREE "free"
#define MAIN "main"
bool Record = false;
map<ADDRINT, bool> MallocMap;
ofstream OutFile;
string ProgramImage;
KNOB<string> OutFileName(KNOB_MODE_WRITEONCE,
"Pintool", "o", "memtrace.txt",
"Memory trace file name");
void RecordMalloc(ADDRINT addr) {
if (!Record) return;
if (addr == 0) {
cerr << "Heap full!";
return;
}
map<ADDRINT, bool>::iterator it = MallocMap.find(addr);
if (it != MallocMap.end()) {
if (it->second) {
// Allocating a previously allocated and freed memory.
it->second = false;
}
else {
// Malloc should not allocate memory that has
// already been allocated but not freed.
cerr << "Imposible!" << endl;
}
}
else {
// First time allocating at this address.
MallocMap.insert(pair<ADDRINT, bool>(addr, false));
}
}
void RecordFree(ADDRINT addr) {
if (!Record) return;
map<ADDRINT, bool>::iterator it = MallocMap.find(addr);
if (it != MallocMap.end()) {
if (it->second) {
// Double freeing.
OutFile << "Object at address " << hex << addr << "has been freed more than once." << endl;
}
else {
it->second = true; // Mark as freed.
}
}
else {
// Freeing unallocated memory.
OutFile << "Freeing unallocated memory at "
<< hex << addr << "." << endl;
}
}
void RecordMainBegin() {
Record = true;
}
void RecordMainEnd() {
Record = false;
}
void Image(IMG img, void *v) {
if (IMG_Name(img) == ProgramImage) {
RTN mallocRtn = RTN_FindByName(img, MALLOC);
if (mallocRtn.is_valid()) {
RTN_Open(mallocRtn);
RTN_InsertCall(mallocRtn, IPOINT_AFTER, (AFUNPTR)RecordMalloc,
IARG_FUNCRET_EXITPOINT_VALUE,
IARG_END);
RTN_Close(mallocRtn);
}
RTN freeRtn = RTN_FindByName(img, FREE);
if (freeRtn.is_valid()) {
RTN_Open(freeRtn);
RTN_InsertCall(freeRtn, IPOINT_BEFORE, (AFUNPTR)RecordFree,
IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
IARG_END);
RTN_Close(freeRtn);
}
RTN mainRtn = RTN_FindByName(img, MAIN);
if (mainRtn.is_valid()) {
RTN_Open(mainRtn);
RTN_InsertCall(mainRtn, IPOINT_BEFORE, (AFUNPTR)RecordMainBegin,
IARG_END);
RTN_InsertCall(mainRtn, IPOINT_AFTER, (AFUNPTR)RecordMainEnd,
IARG_END);
RTN_Close(mainRtn);
}
}
}
void Fini(INT32 code, void *v)
{
for (pair<ADDRINT, bool> p : MallocMap)
{
if (!p.second)
{
// Unfreed memory.
OutFile << "Memory at " << hex << p.first << "allocated but not freed." << endl;
}
}
OutFile.close();
}
int main(int argc, char *argv[]) {
PIN_Init(argc, argv);
ProgramImage = argv[6]; // Assume that the image name is always at index 6.
PIN_InitSymbols();
OutFile.open(OutFileName.Value().c_str());
IMG_AddInstrumentFunction(Image, NULL);
PIN_AddFiniFunction(Fini, NULL);
PIN_StartProgram();
return 0;
}