static BOOL Intercept(THREADID tid, DEBUGGING_EVENT eventType, CONTEXT *ctxt, VOID *)
{
    if (eventType == DEBUGGING_EVENT_BREAKPOINT)
    {
        // When the child thread reaches the breakpoint in Breakpoint(), wait for the main
        // thread to reach the One() function.  If the main thread is not there yet, squash the
        // breakpoint and move the PC back to the start of the Breakpoint() function.  This will
        // delay a while and then re-trigger the breakpoint.
        //
        ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR);
        if (pc == BreakpointLocation && !AllowBreakpoint)
        {
            PIN_SetContextReg(ctxt, REG_INST_PTR, BreakpointFunction);
            PIN_GetLock(&Lock, 1);
            std::cout << "Squashing breakpoint at 0x" << std::hex << pc << " on thread " << std::dec << tid << std::endl;
            PIN_ReleaseLock(&Lock);
            return FALSE;
        }

        PIN_GetLock(&Lock, 1);
        std::cout << "Stopping at breakpoint at 0x" << std::hex << pc << " on thread " << std::dec << tid << std::endl;
        PIN_ReleaseLock(&Lock);
        return TRUE;
    }

    if (eventType == DEBUGGING_EVENT_ASYNC_BREAK)
    {
        // When the child thread triggers the breakpoint, we should be at the One() function.
        // Change the PC to the Two() function, which is the point of this test.  We want to
        // make sure Pin properly handles the change of PC in this case.
        //
        ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR);
        if (pc == OneFunction)
        {
            PIN_SetContextReg(ctxt, REG_INST_PTR, TwoFunction);
            PIN_GetLock(&Lock, 1);
            std::cout << "Changing ASYNC BREAK PC to Two() on thread " << std::dec << tid << std::endl;
            PIN_ReleaseLock(&Lock);
            return TRUE;
        }

        // If the PC is not at the One() function, the child thread has probably hit some breakpoint
        // other than the one at Breakpoint().  (E.g. an internal breakpoint set by GDB.)  Don't
        // change the PC in such a case.
        //
        PIN_GetLock(&Lock, 1);
        std::cout << "ASYNC_BREAK at 0x" << std::hex << pc << " on thread " << std::dec << tid << std::endl;
        PIN_ReleaseLock(&Lock);
        return TRUE;
    }

    PIN_GetLock(&Lock, 1);
    std::cout << "FAILURE: Unexpected debugging event type" << std::endl;
    PIN_ReleaseLock(&Lock);
    std::exit(1);
}
Esempio n. 2
0
/*!
 * Print out analysis results.
 * This function is called when the application exits.
 * @param[in]   code            exit code of the application
 * @param[in]   v               value specified by the tool in the 
 *                              PIN_AddFiniFunction function call
 */
VOID Fini(INT32 code, VOID *v)
{
    PIN_GetLock(&fileLock, 1);
    fclose(outfile);
    printf("outfile closed\n");
    PIN_ReleaseLock(&fileLock);
}
Esempio n. 3
0
// Note that opening a file in a callback is only supported on Linux systems.
// See buffer-win.cpp for how to work around this issue on Windows.
//
// This routine is executed every time a thread is created.
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    PIN_GetLock(&lock, threadid+1);
    fprintf(out, "thread begin %d\n",threadid);
    fflush(out);
    PIN_ReleaseLock(&lock);
}
Esempio n. 4
0
static void DoTestLockIntegrity(THREADID tid, THREAD_INFO *info, UINT32 *done)
{
    // This test checks to see if two threads can be in the PIN_LOCK mutex
    // simultaneously.

    PIN_GetLock(&Lock, tid);
    THREADID owner = HasLock;
    HasLock = tid;

    if (owner != INVALID_THREADID)
    {
        std::cout << "Two theads in lock simultaneously: " << std::dec << tid <<
            " and " << owner << std::endl;
        PIN_ExitProcess(1);
    }

    ATOMIC::OPS::Delay(DELAY_COUNT);

    HasLock = INVALID_THREADID;
    THREADID ret = PIN_ReleaseLock(&Lock);

    if (ret != tid)
    {
        std::cout << "PIN_ReleaseLock returned unexpected value " << std::dec << ret <<
            " (expected " << tid << ")" << std::endl;
        PIN_ExitProcess(1);
    }

    CheckIfDone(info, done);
}
Esempio n. 5
0
VOID Error(std::string where, THREADID tid, UINT32 r, ADDRINT expect, ADDRINT val)
{
    PIN_GetLock(&Lock, 1);
    Out << "Mismatch " << where << ": tid=" << std::dec << tid << " (G" << r << ")" <<
        ", Expect " << std::hex << expect << ", Got " << std::hex << val << std::endl;
    PIN_ReleaseLock(&Lock);
}
Esempio n. 6
0
// This routine is executed every time a thread is destroyed.
VOID ThreadFini(THREADID threadid, const CONTEXT *ctxt, INT32 code, VOID *v)
{
    PIN_GetLock(&lock, threadid+1);
    fprintf(out, "thread end %d code %d\n",threadid, code);
    fflush(out);
    PIN_ReleaseLock(&lock);
}
Esempio n. 7
0
// This routine is executed each time malloc is called.
VOID BeforeMalloc( int size, THREADID threadid )
{
    PIN_GetLock(&lock, threadid+1);
    fprintf(out, "thread %d entered malloc(%d)\n", threadid, size);
    fflush(out);
    PIN_ReleaseLock(&lock);
}
Esempio n. 8
0
	static bool address_mapped(void *addr) {
		int i;
		PIN_GetLock(&globalLock, 1);
		i = _find_overlap(addr, addr);
		PIN_ReleaseLock(&globalLock);
		return (i != -1);
	}
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    PIN_GetLock(&lock, threadid+1);
    numThreads++;
    PIN_ReleaseLock(&lock);
    
    ASSERT(numThreads <= MaxNumThreads, "Maximum number of threads exceeded\n");
}
static VOID GetToolLock(THREADID tid)
{
    PIN_GetLock(&ToolLock, tid+1);

    // The loop opens the timing hole, making the deadlock more likely.
    for(int i=0;i<10000000;i++);
    PIN_ReleaseLock(&ToolLock);
}
Esempio n. 11
0
static void DoTestLockStress(THREADID tid, THREAD_INFO *info, UINT32 *done)
{
    // This test just tries to acquire and release PIN_LOCK as fast as possible
    // to see if we can provoke a deadlock due to missing a wakeup.

    PIN_GetLock(&Lock, tid);
    PIN_ReleaseLock(&Lock);
    CheckIfDone(info, done);
}
Esempio n. 12
0
VOID ThreadFini(THREADID tid, const CONTEXT *ctxt, INT32 code, VOID *v)
{
    // When the thread exits, accumulate the thread's dynamic instruction
    // count into the total.
    //
    PIN_GetLock(&Lock, tid+1);
    TotalCount += PIN_GetContextReg(ctxt, ScratchReg);
    PIN_ReleaseLock(&Lock);
}
Esempio n. 13
0
// Print a memory write record
VOID RecordMemWrite(VOID * ip, VOID * addr, THREADID threadid)
{
    PIN_GetLock(&lock, 0);
    bool dl1hit = dl1cache->AccessSingleLine((ADDRINT)addr, CACHE_BASE::ACCESS_TYPE_STORE);
    bool dl3hit = dl3cache->AccessSingleLine((ADDRINT)addr, CACHE_BASE::ACCESS_TYPE_STORE);
    PIN_ReleaseLock(&lock);

    thread_data *td = get_tls(threadid);
    td->record_mem_write(ip, addr, dl1hit || dl3hit);
}
Esempio n. 14
0
static void UseLocksScheduler()
{
    UseLockSchedulerCount++;

    // The scheduler thread executes this after it has lowered the priority of
    // the worker thread.  The hope is that we will try to acquire the lock while
    // the worker already has it.
    //
    PIN_GetLock(&Lock, 2);
    PIN_ReleaseLock(&Lock);
}
Esempio n. 15
0
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
  if(threadid!=0)return;
  PIN_GetLock(&lock, threadid+1);
  numThreads++;
  PIN_ReleaseLock(&lock);    

  tdata = new thread_data_t (threadid);

  PIN_SetThreadData(tls_key, tdata, threadid);
}
Esempio n. 16
0
VOID Call(THREADID tid, ADDRINT sp, ADDRINT target, ADDRINT eip, ADDRINT nxtIns )
{
    thread_data_t *tdata = get_tls(tid);

    PIN_GetLock(&lock, tid+1);
    tdata->data_sp.push_front(sp);	// Pushing SP register 
    tdata->data_ret.push_front(nxtIns); // Pushing return address for the call ins
    tdata->tuplist.push_front(boost::tuple<ADDRINT, ADDRINT>(eip, nxtIns));
    depth++;
    PIN_ReleaseLock(&lock);
}
Esempio n. 17
0
static void UseLocksWorker()
{
    UseLockWorkerCount++;

    // The worker thread executes this in a loop.  We do sched_yield() to
    // encourage the kernel to switch the thread off the CPU while it holds
    // the lock.  This would be possible even without the sched_yield(), though.
    //
    PIN_GetLock(&Lock, 1);
    sched_yield();
    PIN_ReleaseLock(&Lock);
}
Esempio n. 18
0
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    PIN_GetLock(&lock, threadid+1);
    numThreads++;
    PIN_ReleaseLock(&lock);

    thread_data_t* tdata = new thread_data_t;
    clock_gettime(CLOCK_MONOTONIC, &tdata->tstart);

    PIN_SetThreadData(tls_key, tdata, threadid);

}
Esempio n. 19
0
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    PIN_GetLock(&lock, 0);

    thread_data *td = new thread_data;

    PIN_SetThreadData(tls_key, td, threadid);

    all_thread_data.push_back(td);

    PIN_ReleaseLock(&lock);
}
Esempio n. 20
0
VOID Call(THREADID tid, ADDRINT sp, ADDRINT target, ADDRINT eip, ADDRINT nxtIns )
{
    thread_data_t *tdata = get_tls(tid);

    PIN_GetLock(&lock, tid+1);
    tdata->data_sp.push_front(sp);	// Pushing SP register 
    tdata->data_ret.push_front(nxtIns); // Pushing return address for the call ins
    tdata->tuplist.push_front(boost::tuple<ADDRINT, ADDRINT>(eip, nxtIns));
    depth++;
    PIN_ReleaseLock(&lock);
    if ( eip == 12 )
//    cout << hex << (nxtIns - eip ) << " : " << nxtIns <<  " : " << eip << endl;
    cout << hex << tdata->tuplist.begin()->get<0>() << " " <<tdata->tuplist.begin()->get<1>() << endl;
}
static VOID AtOne()
{
    if (!AllowBreakpoint)
    {
        PIN_GetLock(&Lock, 1);
        std::cout << "Breakpoint is allowed" << std::endl;
        PIN_ReleaseLock(&Lock);
    }

    // When the main thread reaches the One() function, allow the child thread to trigger
    // the breakpoint.  The main thread will continue executing this instruction in a loop
    // until we intercept the DEBUGGING_EVENT_ASYNC_BREAK event below.
    //
    AllowBreakpoint = TRUE;
}
Esempio n. 22
0
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    PIN_InitLock(&lock);
    PIN_GetLock(&lock, threadid+1);
    numThreads++;
    if (threadid > maxThreads)
        maxThreads = threadid;

    OS_THREAD_ID oid = PIN_GetTid();
    OSTID_ITER iter = tidMap.find(oid);
    if (iter == tidMap.end())
    {
        // new threads
        numSysThreads++;
        tidMap.insert(oid);
    }
    PIN_ReleaseLock(&lock);
}
Esempio n. 23
0
/*!
 * Called when a buffer fills up, or the thread exits, so we can process it or pass it off
 * as we see fit.
 * @param[in] id		buffer handle
 * @param[in] tid		id of owning thread
 * @param[in] ctxt		application context when the buffer filled
 * @param[in] buf		actual pointer to buffer
 * @param[in] numElements	number of records
 * @param[in] v			callback value
 * @return  A pointer to the buffer to resume filling.
 */
VOID * BufferFull(BUFFER_ID bid, THREADID tid, const CONTEXT *ctxt, VOID *buf,
                  UINT64 numElements, VOID *v)
{
    PIN_GetLock(&fileLock, 1);

    ASSERTX(buf == PIN_GetThreadData(buf_key, tid));
    
    struct MEMREF* reference=(struct MEMREF*)buf;
    UINT64 i;

    for(i=0; i<numElements; i++, reference++){
        fprintf(outfile, "%lx %lx %u %u\n", (unsigned long)reference->pc, (unsigned long)reference->address,
                reference->size, reference->load);   
    }
    fflush(outfile);
    PIN_ReleaseLock(&fileLock);

    return buf;
}
Esempio n. 24
0
/*!
 * Called when a buffer fills up, or the thread exits, so we can process it or pass it off
 * as we see fit.
 * @param[in] id		buffer handle
 * @param[in] tid		id of owning thread
 * @param[in] ctxt		application context when the buffer filled
 * @param[in] buf		actual pointer to buffer
 * @param[in] numElements	number of records
 * @param[in] v			callback value
 * @return  A pointer to the buffer to resume filling.
 */
VOID * BufferFull2(BUFFER_ID id, THREADID tid, const CONTEXT *ctxt, VOID *buf,
                   UINT64 numElements, VOID *v)
{
    PIN_GetLock(&fileLock, 1);

    struct MEMREF* reference=(struct MEMREF*)buf;
    unsigned int i;

    fprintf( outfile, "Dumping buffer 2 at address %lx\n", (unsigned long)buf);
    
    for(i=0; i<numElements; i++, reference++){
        fprintf(outfile, "%lx %lx %u %u\n", (unsigned long)reference->pc, (unsigned long)reference->address,
                reference->size, reference->load);   
    }
    fflush(outfile);
    PIN_ReleaseLock(&fileLock);

    return buf;
}
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    PIN_InitLock(&lock);
    PIN_GetLock(&lock, threadid+1);
    fprintf(trace, "thread begin %x %x\n",threadid, numThreads);
    numThreads++;
    if (threadid < MAX_THREADS)
    {
#ifndef TARGET_LINUX
        threadData[threadid].threadTeb = InitializeThreadData();
#endif
    }
    else
    {
        fprintf (trace, "ERROR - maximum #threads exceeded\n");
    }
    fflush(trace);
    PIN_ReleaseLock(&lock);
}
Esempio n. 26
0
VOID ThreadStart( THREADID tid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    PIN_GetLock(&lock, tid+1);

    tIds[numThreads] = tid;
    stringstream fn;

    if ( tid != numThreads ) {
	cout << " TID NOT SAME AS NUMTHREADS " << tid << " " << numThreads << endl;
    }

    fn.str("");
    fn << OUT_FILE << "_" << numThreads;
    OutFile[numThreads].open(fn.str().c_str(), ios::out);
    ++numThreads;
    PIN_ReleaseLock(&lock);

    thread_data_t *tdata = new thread_data_t(numThreads-1);
    PIN_SetThreadData(tls_key, tdata, tid);
}
Esempio n. 27
0
VOID ThreadStart( THREADID tid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    PIN_GetLock(&lock, tid+1);

    tIds[numThreads] = tid;
    stringstream fn;

    /* If you ever see this then change the logic in code which uses tid to 
       index into open File streams to do File I/O */
    if ( tid != numThreads ) {
	cout << " TID NOT SAME AS NUMTHREADS " << tid << " " << numThreads << endl;
    }

    fn.str("");
    fn << OUT_FILE << "_" << numThreads;
    OutFile[numThreads].open(fn.str().c_str(), ios::out);
    ++numThreads;
    PIN_ReleaseLock(&lock);

    thread_data_t *tdata = new thread_data_t(numThreads-1);
    PIN_SetThreadData(tls_key, tdata, tid);
}
Esempio n. 28
0
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    PIN_GetLock(&lock, threadid+1);
    fprintf(trace, "thread begin %x %x\n",threadid, numThreads);
    numThreads++;
    if (threadid < MAX_THREADS)
    {
#ifdef TARGET_WINDOWS
        threadData[threadid].threadTeb = InitializeThreadData();
        if ((ADDRINT)PIN_GetContextReg( ctxt, TESTED_SEG_REG_BASE ) != InitializeThreadData())
        {
            fprintf (trace, "ERROR - Initial value of tested segment base does not match TEB\n");
            hadError = TRUE;
        }
#endif
    }
    else
    {
        fprintf (trace, "ERROR - maximum #threads exceeded\n");
    }
    fflush(trace);
    PIN_ReleaseLock(&lock);
}
Esempio n. 29
0
VOID ThreadFini(THREADID threadid, const CONTEXT *ctxt, INT32 code, VOID *v)
{
    PIN_GetLock(&lock, PIN_GetTid());
    threadEnded++;
    PIN_ReleaseLock(&lock);
}
Esempio n. 30
0
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    PIN_GetLock(&lock, PIN_GetTid());
    threadCreated++;
    PIN_ReleaseLock(&lock);
}