2015-12-08 103 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语句之前被中断有很多原因。

相关问题