// // This tool counts the number of times a routine is executed and // the number of instructions executed in a routine // #include <fstream> #include <iomanip> #include <iostream> #include <string.h> #include "pin.H" ofstream outFile; // Holds instruction count for a single procedure typedef struct RtnCount { string _name; string _image; ADDRINT _address; RTN _rtn; UINT64 _rtnCount; UINT64 _icount; struct RtnCount * _next; } RTN_COUNT; // Linked list of instruction counts for each routine RTN_COUNT * RtnList = 0; // This function is called before every instruction is executed VOID docount(UINT64 * counter) { (*counter)++; } const char * StripPath(const char * path) { const char * file = strrchr(path,'/'); if (file) return file+1; else return path; } // Pin calls this function every time a new rtn is executed VOID Routine(RTN rtn, VOID *v) { // Allocate a counter for this routine RTN_COUNT * rc = new RTN_COUNT; // The RTN goes away when the image is unloaded, so save it now // because we need it in the fini rc->_name = RTN_Name(rtn); rc->_image = StripPath(IMG_Name(SEC_Img(RTN_Sec(rtn))).c_str()); rc->_address = RTN_Address(rtn); rc->_icount = 0; rc->_rtnCount = 0; // Add to list of routines rc->_next = RtnList; RtnList = rc; RTN_Open(rtn); // Insert a call at the entry point of a routine to increment the call count RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)docount, IARG_PTR, &(rc->_rtnCount), IARG_END); // For each instruction of the routine for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { // Insert a call to docount to increment the instruction counter for this rtn INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_PTR, &(rc->_icount), IARG_END); } RTN_Close(rtn); } // This function is called when the application exits // It prints the name and count for each procedure VOID Fini(INT32 code, VOID *v) { outFile << setw(23) << "Procedure" << " " << setw(15) << "Image" << " " << setw(18) << "Address" << " " << setw(12) << "Calls" << " " << setw(12) << "Instructions" << endl; for (RTN_COUNT * rc = RtnList; rc; rc = rc->_next) { if (rc->_icount > 0) outFile << setw(23) << rc->_name << " " << setw(15) << rc->_image << " " << setw(18) << hex << rc->_address << dec <<" " << setw(12) << rc->_rtnCount << " " << setw(12) << rc->_icount << endl; } } /* ===================================================================== */ /* Print Help Message */ /* ===================================================================== */ INT32 Usage() { cerr << "This Pintool counts the number of times a routine is executed" << endl; cerr << "and the number of instructions executed in a routine" << endl; cerr << endl << KNOB_BASE::StringKnobSummary() << endl; return -1; } /* ===================================================================== */ /* Main */ /* ===================================================================== */ int main(int argc, char * argv[]) { // Initialize symbol table code, needed for rtn instrumentation PIN_InitSymbols(); outFile.open("proccount.out"); // Initialize pin if (PIN_Init(argc, argv)) return Usage(); // Register Routine to be called to instrument rtn RTN_AddInstrumentFunction(Routine, 0); // Register Fini to be called when the application exits PIN_AddFiniFunction(Fini, 0); // Start the program, never returns PIN_StartProgram(); return 0; }
이제 RTN_이 나온다.
이 코드는 각각의 routine(procedure)에 대해서 각각 몇 번씩 실행했고, 각각은 몇 개의 instruction으로 되어 있는지를 출력하는 소스이다. 그리고 이름이 같은 루틴이더라도 이미지가 unloaded 되면 RTN은 goes away되기 때문에 실행결과 이름이 같은 것이 많이 나온다.
질문
루틴이 무엇인지
call이 0번인건 어떤 의미인지
올리디버거로 따라갔을때...?
'pintool' 카테고리의 다른 글
Order of Instrumentation (0) | 2018.09.18 |
---|---|
Using PIN_SafeCopy() (0) | 2018.09.18 |
More Efficient Instruction Counting (Trace Instrumentation) +질문 (0) | 2018.09.14 |
Detecting the Loading and Unloading of Images (Image Instrumentation)+질문 (0) | 2018.09.14 |
Memory Reference Trace (Instruction Instrument) (0) | 2018.09.14 |