2015-12-08 104 views
0

我使用Intel-Pin來測試Linux中的pthread_mutex_lockpthread_mutex_unlock。我分別在這兩個鎖定函數的調用之前和之後插入函數,所以我期望該工具將在鎖定函數之前和之後輸出字符串。
該儀器代碼是作爲遵循爲什麼在Pin中不能調用某個回調函數?

#include "pin.H" 
#include <iostream> 
#include <fstream> 

/* ===================================================================== */ 
/* Names of pthread_mutex_lock and pthread_mutex_unlock */ 
/* ===================================================================== */ 
#define PTHREAD_MUTEX_INIT "pthread_mutex_init" 
#define PTHREAD_MUTEX_DESTROY "pthread_mutex_destroy" 
#define PTHREAD_MUTEX_LOCK "pthread_mutex_lock" 
#define PTHREAD_MUTEX_UNLOCK "pthread_mutex_unlock" 

/* ===================================================================== */ 
/* Global Variables */ 
/* ===================================================================== */ 
PIN_LOCK lock; 

std::ofstream TraceFile; 

/* ===================================================================== */ 
/* Commandline Switches */ 
/* ===================================================================== */ 

KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", 
    "o", "malloctrace.out", "specify trace file name"); 

/* ===================================================================== */ 


/* ===================================================================== */ 
/* Analysis routines              */ 
/* ===================================================================== */ 
VOID Pthread_mutex_lock_callBefore(ADDRINT lockaddr) 
{ 
    PIN_GetLock(&lock, 1); 
    printf("Pthread_mutex_lock_callBefore\n"); 
    PIN_ReleaseLock(&lock); 
} 

VOID Pthread_mutex_lock_callAfter(ADDRINT ret) 
{ 
    if(ret != 0) 
     return; 
    PIN_GetLock(&lock, 2); 
    printf("Pthread_mutex_lock_callAfter\n"); 
    PIN_ReleaseLock(&lock); 
} 

VOID Pthread_mutex_unlock_callBefore(ADDRINT lockaddr) 
{ 

    PIN_GetLock(&lock, 3); 
    printf("Pthread_mutex_unlock_callBefore\n"); 
    PIN_ReleaseLock(&lock); 
} 

static VOID Pthread_mutex_unlock_callAfter(ADDRINT ret) 
{ 
    if(ret != 0) 
     return; 
    PIN_GetLock(&lock, 4); 
    printf("Pthread_mutex_unlock_callAfter\n"); 
    PIN_ReleaseLock(&lock); 
} 


/* ===================================================================== */ 
/* Instrumentation routines            */ 
/* ===================================================================== */ 

VOID Image(IMG img, VOID *v) 
{ 

    RTN pmlRtn = RTN_FindByName(img, PTHREAD_MUTEX_LOCK); 
    if (RTN_Valid(pmlRtn) && PIN_IsApplicationThread()) 
    { 
     RTN_Open(pmlRtn); 

     RTN_InsertCall(pmlRtn, IPOINT_BEFORE, (AFUNPTR)Pthread_mutex_lock_callBefore, 
         IARG_FUNCARG_ENTRYPOINT_VALUE, 0, 
         IARG_END); 

     RTN_InsertCall(pmlRtn, IPOINT_AFTER, (AFUNPTR)Pthread_mutex_lock_callAfter, 
         IARG_FUNCRET_EXITPOINT_VALUE, 
         IARG_END); 
     RTN_Close(pmlRtn); 
    } 

    //pthread_mutex_unlock 
    pmlRtn = RTN_FindByName(img, PTHREAD_MUTEX_UNLOCK); 
    if (RTN_Valid(pmlRtn)) 
    { 
     RTN_Open(pmlRtn); 

     RTN_InsertCall(pmlRtn, IPOINT_BEFORE, (AFUNPTR)Pthread_mutex_unlock_callBefore, 
         IARG_FUNCARG_ENTRYPOINT_VALUE, 0, 
         IARG_END); 
     RTN_InsertCall(pmlRtn, IPOINT_AFTER, (AFUNPTR)Pthread_mutex_unlock_callAfter, 
         IARG_FUNCRET_EXITPOINT_VALUE, 
         IARG_END); 

     RTN_Close(pmlRtn); 
    } 
} 

/* ===================================================================== */ 

VOID Fini(INT32 code, VOID *v) 
{ 
    TraceFile.close(); 
} 

/* ===================================================================== */ 
/* Print Help Message             */ 
/* ===================================================================== */ 

INT32 Usage() 
{ 
    cerr << "This tool produces a trace of calls to malloc." << endl; 
    cerr << endl << KNOB_BASE::StringKnobSummary() << endl; 
    return -1; 
} 


/* ===================================================================== */ 
/* Main                 */ 
/* ===================================================================== */ 

int main(int argc, char *argv[]) 
{ 
    // Initialize pin & symbol manager 
    PIN_InitLock(&lock); 
    PIN_InitSymbols(); 
    if(PIN_Init(argc,argv)) 
    { 
     return Usage(); 
    } 

    // Write to a file since cout and cerr maybe closed by the application 
    TraceFile.open(KnobOutputFile.Value().c_str()); 
    TraceFile << hex; 
    TraceFile.setf(ios::showbase); 

    // Register Image to be called to instrument functions. 
    IMG_AddInstrumentFunction(Image, 0); 
    PIN_AddFiniFunction(Fini, 0); 

    // Never returns 
    PIN_StartProgram(); 

    return 0; 
} 

/* ===================================================================== */ 
/* eof */ 
/* ===================================================================== */ 

編譯此工具

make obj-ia32/mytool.so TARGET=ia32 

使用此工具器械一個簡單的測試

#include <stdio.h> 
#include <pthread.h> 
#include <unistd.h> 
#include <stdlib.h> 

pthread_mutex_t m; 

void * fun1(void *arg) 
{ 
    pthread_mutex_lock(&m); 

    pthread_mutex_unlock(&m); 
} 

int main(int argc,char* argv[]) 
{ 
    pthread_t npid1; 

    pthread_mutex_init(&m,NULL); 

    pthread_create(&npid1,NULL,fun1,NULL); 

    pthread_join(npid1,NULL); 

    return 0; 
} 

編譯此測試

gcc -g t.c -o t -lpthread 

最後,我用我的工具儀器這個測試

sudo ./pin -t obj-ia32/mytool.so -- ./t 

結果是

[email protected]:~/MyPinTool$ sudo ./pin -t obj-ia32/mytool.so -- ./t 
Pthread_mutex_lock_callBefore 
Pthread_mutex_lock_callAfter 
Pthread_mutex_unlock_callBefore 
Pthread_mutex_lock_callBefore 
Pthread_mutex_lock_callAfter 
Pthread_mutex_unlock_callBefore 
Pthread_mutex_lock_callBefore 
Pthread_mutex_lock_callAfter 
Pthread_mutex_unlock_callBefore 

你可以看到有沒有Pthread_mutex_unlock_callAfter,我有調用pthread_mutex_unlock後插入函數,爲什麼這個功能還沒有被召喚?
PS:引腳API說

VOID LEVEL_PINCLIENT::RTN_InsertCall ( RTN  rtn, 
     IPOINT  action, 
     AFUNPTR  funptr, 
      ... 
    ) 


Insert call relative to a rtn. 

Parameters: 
     rtn  Routine to instrument 
     action Use IPOINT_BEFORE to call funptr before execution, or IPOINT_AFTER for immediately before the return NOTE: IPOINT_AFTER is implemented by instrumenting each return instruction in a routine. Pin tries to find all return instructions, but success is not guaranteed 
     funptr Analysis function to call 
     ...  IARG_TYPE. Arguments to pass to funptr 
+0

api參考文獻中的NOTE已經表明:pin盡最大努力來測試ipoint_after,但不能保證。如果您希望在回調之前和之後保證,請使用RTN替換API。 – nitzanms

+0

@nitzanms我是使用Pin的新人,對我來說使用它有很多問題。非常感謝你。如果我有一些問題,我可以在哪裏詢問有關Pin的問題? – wangxf

+0

當然你可以在這裏問,但你也可以在Pinheads中找到很多有用的信息,Pin用戶的支持小組:https://groups.yahoo.com/neo/groups/pinheads/info – nitzanms

回答

0

正如Nitzan已經說過,這些API說明了一切:針試圖儀器功能的每個ret指令,但成功並不保證下,。想想如果在函數內拋出異常,或者函數發生遠程跳轉,會發生什麼......

函數在到達return語句之前被中斷有很多原因。

相關問題