2

In the code I"m trying to get the output in the decreasing order of calls. Can someone please help?


#include <fstream>
#include <iomanip>
#include <iostream>
#include <string.h>
#include "pin.H"
using std::ofstream;
using std::string;
using std::hex;
using std::setw;
using std::cerr;
using std::dec;
using std::endl;

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;
}

I'm trying to figure it out, but I'm unable find the solution for it.

I'm getting the output in the following way.

  Procedure           Image            Address        Calls Instructions
         __memcpy_ssse3       libc.so.6       7f9b5b09ebb0          675         8100
         __strcmp_sse42       libc.so.6       7f9b5b090e20           16          784
_dl_mcount_wrapper_check       libc.so.6       7f9b5b08f730          128          512
               _dl_addr       libc.so.6       7f9b5b08f340            1        56541
    __unregister_atfork       libc.so.6       7f9b5b05e930            3           21
               wctype_l       libc.so.6       7f9b5b054a20            9          876
            __init_misc       libc.so.6       7f9b5b0507f0            1           24
                   sbrk       libc.so.6       7f9b5b047250            2           52
                    brk       libc.so.6       7f9b5b0471e0            3           39
       __close_nocancel       libc.so.6       7f9b5b042049            2           10
       __write_nocancel       libc.so.6       7f9b5b0419f9            1            5
                __write       libc.so.6       7f9b5b0419f0            1            2

I want the output in the decreasing order of calls.

Robert
  • 21
  • 2
  • FYI, in C++, you don't need the `typedef struct`. The `struct` will suffice. The `typedef` is a hold-over from C language. – Thomas Matthews Nov 25 '20 at 21:54
  • You can always sort "rtn linked list" using 'Calls' as the key. Or simply store the file as csv and open as a excel sheet and sort based on Calls column. Where is the problem!. – ajit Nov 30 '20 at 12:26

0 Answers0