I want a memory (read) trace of a function and all the functions called by the function I wish to trace.
This is the code I wrote.
#include "pin.H"
#include <cstdint>
#include <iostream>
#include <map>
#include <vector>
using std::string,std::endl,std::cerr,std::vector,std::cout;
FILE *trace;
int max_threads=8;
vector<vector<string>> CallStack(max_threads,vector<string>());
string func_to_trace="ZSTD_compressBlock_doubleFast";
vector<int> func_to_trace_count(max_threads,0);
VOID RecordMemRead(ADDRINT address,THREADID thid, UINT64 memOp, string rname) {
if(func_to_trace_count[(uint32_t)thid]!=0)
fprintf(trace,"%s %ld %ld\n",rname.c_str(),address,memOp);
}
VOID AddStack(string rname,THREADID thid)
{
auto &cs=CallStack[(uint32_t)thid];
if(rname==func_to_trace)
func_to_trace_count[(uint32_t)thid]++;
cs.push_back(rname);
for(auto const &x:cs)
{
cout<<x<<"/";
}
cout<<"\n";
}
VOID RmStack(string rname,THREADID thid)
{
auto &cs=CallStack[(uint32_t)thid];
if(cs.empty())
{
cout<<"CallStack was empty. Ret was for "<<rname<<"\n";
return;
}
if(cs.back()!=rname)
{
cout<<"call stack end was "<<cs.back()<<" and Ret was for "<<rname<<"\n";
}
if(rname==func_to_trace)
func_to_trace_count[(uint32_t)thid]--;
cs.pop_back();
}
VOID Routine(RTN rtn, VOID *v) {
RTN_Open(rtn);
string name = RTN_Name(rtn);
INS ins = RTN_InsHead(rtn);
INS_InsertPredicatedCall(ins, IPOINT_BEFORE,
(AFUNPTR)AddStack,IARG_PTR,new string(name),IARG_THREAD_ID, IARG_END);
for (; INS_Valid(ins); ins = INS_Next(ins)) {
UINT32 memOperands = INS_MemoryOperandCount(ins);
if(INS_IsRet(ins))
{
INS_InsertPredicatedCall(ins, IPOINT_BEFORE,
(AFUNPTR)RmStack,IARG_PTR,new string(name),IARG_THREAD_ID, IARG_END);
}
for (UINT32 memOp = 0; memOp < memOperands; memOp++) {
if (INS_MemoryOperandIsRead(ins, memOp)) {
INS_InsertPredicatedCall(ins, IPOINT_BEFORE,
(AFUNPTR)RecordMemRead, IARG_INST_PTR,IARG_THREAD_ID,
IARG_MEMORYOP_EA, memOp, IARG_PTR,
new string(name), IARG_END);
}
}
}
RTN_Close(rtn);
}
VOID Fini(INT32 code, VOID *v) {
}
INT32 Usage() {
cerr << "This Pintool prints the addresses being read" << endl;
cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
return -1;
}
int main(int argc, char *argv[]) {
PIN_InitSymbols();
trace=stdout;
if (PIN_Init(argc, argv))
return Usage();
RTN_AddInstrumentFunction(Routine, 0);
PIN_AddFiniFunction(Fini, 0);
PIN_StartProgram();
return 0;
}
This code creates a callstack with only function names for each thread.
Sample of the output
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__tunable_get_val/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__tunable_get_val/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__tunable_get_val/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__tunable_get_val/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__tunable_get_val/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__tunable_get_val/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__tunable_get_val/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__tunable_get_val/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__tunable_get_val/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__default_morecore/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__default_morecore/sbrk/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__default_morecore/sbrk/brk/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__default_morecore/sbrk/brk/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__default_morecore/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/malloc/__default_morecore/sbrk/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/.plt/AIO_supported/
call stack end was .plt and Ret was for FIO_createPreferences
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/malloc@plt/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/malloc@plt/malloc/
call stack end was malloc@plt and Ret was for FIO_createContext
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/getenv/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/ZSTD_minCLevel/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/UTIL_allocateFileNamesTable/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/UTIL_allocateFileNamesTable/malloc@plt/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/UTIL_allocateFileNamesTable/malloc@plt/malloc/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/UTIL_allocateFileNamesTable/malloc@plt/malloc@plt/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/UTIL_allocateFileNamesTable/malloc@plt/malloc@plt/malloc/
call stack end was malloc@plt and Ret was for UTIL_allocateFileNamesTable
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/UTIL_allocateFileNamesTable/malloc@plt/UTIL_allocateFileNamesTable/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/UTIL_allocateFileNamesTable/malloc@plt/UTIL_allocateFileNamesTable/malloc@plt/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/UTIL_allocateFileNamesTable/malloc@plt/UTIL_allocateFileNamesTable/malloc@plt/malloc/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/UTIL_allocateFileNamesTable/malloc@plt/UTIL_allocateFileNamesTable/malloc@plt/malloc@plt/
_start/_setjmp/main/FIO_createPreferences/malloc@plt/FIO_createContext/getenv@plt/.plt/UTIL_allocateFileNamesTable/malloc@plt/UTIL_allocateFileNamesTable/malloc@plt/malloc@plt/malloc/
call stack end was malloc@plt and Ret was for UTIL_allocateFileNamesTable
ZSTD_compressBlock_doubleFast 94835784967665 139831250250248
ZSTD_compressBlock_doubleFast 94835784967683 139831250250208
ZSTD_compressBlock_doubleFast 94835784967698 139831250250220
ZSTD_compressBlock_doubleFast 94835784967702 139831250250224
ZSTD_compressBlock_doubleFast 94835784967717 139831206211790
FIO_createPreferencesZSTD_compressBlock_doubleFast 94835784967754 139831206211793
/malloc@pltZSTD_compressBlock_doubleFast 94835784967782 139831250250192
ZSTD_compressBlock_doubleFast 94835784967794 139831206211794
/ZSTD_compressBlock_doubleFast 94835784967818 139831250250296
FIO_createContextZSTD_compressBlock_doubleFast 94835784967825 139831206211795
/ZSTD_compressBlock_doubleFast 94835784967831 139831206211776
getenv@pltZSTD_compressBlock_doubleFast 94835784966505 139831250250216
ZSTD_compressBlock_doubleFast 94835784966529 139831250250208
ZSTD_compressBlock_doubleFast 94835784966540 139831206211795
ZSTD_compressBlock_doubleFast 94835784966543 139831250250220
/ZSTD_compressBlock_doubleFast 94835784966576 139831250250216
.plt/ZSTD_compressBlock_doubleFast 94835784966580 139831195386620
UTIL_allocateFileNamesTableZSTD_compressBlock_doubleFast 94835784966654 139831250250224
ZSTD_compressBlock_doubleFast 94835784966659 139831250250192
ZSTD_compressBlock_doubleFast 94835784966691 139831250250240
/malloc@plt/UTIL_allocateFileNamesTable/malloc@pltZSTD_compressBlock_doubleFast 94835784966696 139831195715192
ZSTD_compressBlock_doubleFast 94835784966706 139831206211796
/strcmp@pltZSTD_compressBlock_doubleFast 94835784966709 139831206211765
/.plt/ZSTD_compressBlock_doubleFast 94835784966725 139831206211796
ZSTD_compressBlock_doubleFast 94835784966728 139831250250220
strrchr@plt/.pltZSTD_compressBlock_doubleFast 94835784966764 139831195481240
/strrchr@plt/getenv@plt/exeNameMatch/ZSTD_compressBlock_doubleFast 94835784966806 139831250250208
ZSTD_compressBlock_doubleFast 94835784966654 139831250250224
strlen@pltZSTD_compressBlock_doubleFast 94835784966659 139831250250192
ZSTD_compressBlock_doubleFast 94835784966691 139831250250240
ZSTD_compressBlock_doubleFast 94835784966696 139831195616704
ZSTD_compressBlock_doubleFast 94835784966706 139831206211797
/.pltZSTD_compressBlock_doubleFast 94835784966709 139831206211766
ZSTD_compressBlock_doubleFast 94835784966725 139831206211797
ZSTD_compressBlock_doubleFast 94835784966728 139831250250220
/strncmp@pltZSTD_compressBlock_doubleFast 94835784966764 139831195052680
/exeNameMatchZSTD_compressBlock_doubleFast 94835784966782 139831206211796
ZSTD_compressBlock_doubleFast 94835784966784 139831206211060
ZSTD_compressBlock_doubleFast 94835784966806 139831250250208
ZSTD_compressBlock_doubleFast 94835784966654 139831250250224
ZSTD_compressBlock_doubleFast 94835784966659 139831250250192
ZSTD_compressBlock_doubleFast 94835784966691 139831250250240
ZSTD_compressBlock_doubleFast 94835784966696 139831195649664
ZSTD_compressBlock_doubleFast 94835784966706 139831206211798
ZSTD_compressBlock_doubleFast 94835784966709 139831206211767
ZSTD_compressBlock_doubleFast 94835784966725 139831206211798
ZSTD_compressBlock_doubleFast 94835784966728 139831250250220
ZSTD_compressBlock_doubleFast 94835784966764 139831195189212
Often I see that call stack end was .plt and Ret was for FIO_createPreferences
the top of the stack and the return does not match. Looks like the callstack implementation is wrong. Can someone help me fix this code?