#include "pin.H" #include #include #include #pragma GCC diagnostic error "-std=c++11" #define MALLOC "malloc" #define FREE "free" #define MAIN "main" bool Record = false; map MallocMap; ofstream OutFile; string ProgramImage; KNOB 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::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(addr, false)); } } void RecordFree(ADDRINT addr) { if (!Record) return; map::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 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; }