Example #1
0
/*
 * MemoryWrite, StackWrite
 * If store occurs and that address was used for read, make a log
 */
VOID MemoryWrite(ADDRINT memaddr, ADDRINT writesize)
{
	treeNode *node;

	ADDRINT startoffset, endoffset;

	PIN_RWMutexReadLock(&data_lock);
	node = FindAddressInRange(data_root, memaddr);
	PIN_RWMutexUnlock(&data_lock);
	if(node && node->usedforread == TRUE)
	{
		startoffset = memaddr - node->address + node->offset;
		endoffset = memaddr - node->address + node->offset + writesize;

		fprintf(trace, "%x%lx:%s:%lx:%lx:D\n", pid, node->readid, node->path, startoffset, endoffset);
		fflush(trace);
		return;
	}
	PIN_RWMutexReadLock(&malloc_lock);
	node = FindAddressInRange(malloc_root, memaddr);
	PIN_RWMutexUnlock(&malloc_lock);
	if(node && node->usedforread == TRUE)
	{
		startoffset = memaddr - node->address + node->offset;
		endoffset = memaddr - node->address + node->offset + writesize;

		fprintf(trace, "%x%lx:%s:%lx:%lx:M\n", pid, node->readid, node->path, startoffset, endoffset);
		fflush(trace);
		return;
	}
}
Example #2
0
/*
 * ThreadStart
 * Called when every single thread starts
 * Insert new thread to BST
 */
VOID ThreadStart(THREADID threadIndex, CONTEXT *ctxt, INT32 flags, VOID *v)
{
	PIN_THREAD_UID threadid = PIN_ThreadUid();
	PIN_RWMutexWriteLock(&thread_lock);
	root_thread = InsertThread(threadid, root_thread);
	PIN_RWMutexUnlock(&thread_lock);
}
Example #3
0
/*
 * ThreadFini
 * Called when every single thread ends
 * Delete the thread from BST
 */
VOID ThreadFini(THREADID threadIndex, const CONTEXT *ctxt, INT32 code, VOID *v)
{
	PIN_THREAD_UID threadid = PIN_ThreadUid();
	PIN_RWMutexWriteLock(&thread_lock);
	root_thread = DeleteThread(threadid, root_thread);
	PIN_RWMutexUnlock(&thread_lock);
}
Example #4
0
static void DoTestReaderTryStress(THREAD_INFO *info, UINT32 *done)
{
    // Try to acquire / release PIN_RWMUTEX as a reader using "try" as fast as possible.

    if (PIN_RWMutexTryReadLock(&RWMutex))
        PIN_RWMutexUnlock(&RWMutex);
    CheckIfDone(info, done);
}
Example #5
0
static void DoTestReaderStress(THREAD_INFO *info, UINT32 *done)
{
    // This test just tries to acquire and release PIN_RWMUTEX as fast as possible
    // as a reader lock.

    PIN_RWMutexReadLock(&RWMutex);
    PIN_RWMutexUnlock(&RWMutex);
    CheckIfDone(info, done);
}
Example #6
0
static void DoTestWriterStress(THREAD_INFO *info, UINT32 *done)
{
    // This test just tries to acquire and release PIN_RWMUTEX as fast as possible
    // as a writer lock to see if we can provoke a deadlock due to missing a wakeup.

    PIN_RWMutexWriteLock(&RWMutex);
    PIN_RWMutexUnlock(&RWMutex);
    CheckIfDone(info, done);
}
Example #7
0
static void DoTestReaderWriterIntegrity(THREAD_INFO *info, UINT32 *done)
{
    // This test checks that a "writer" thread can never hold the lock while
    // there is an active reader.

    if (info->_workerId & 1)
    {
        // Reader thread.
        //
        PIN_RWMutexReadLock(&RWMutex);
        ATOMIC::OPS::Increment(&ActiveReaders, 1);
        if (ATOMIC::OPS::Load(&IsActiveWriter))
        {
            std::cout << "Reader got lock while there is an active writer" << std::endl;
            PIN_ExitProcess(1);
        }

        ATOMIC::OPS::Delay(DELAY_COUNT);

        ATOMIC::OPS::Increment(&ActiveReaders, -1);
        PIN_RWMutexUnlock(&RWMutex);
    }
    else
    {
        // Writer thread.
        //
        PIN_RWMutexWriteLock(&RWMutex);
        ATOMIC::OPS::Store<BOOL>(&IsActiveWriter, TRUE);
        if (ATOMIC::OPS::Load(&ActiveReaders) != 0)
        {
            std::cout << "Writer has lock while there are active readers" << std::endl;
            PIN_ExitProcess(1);
        }

        ATOMIC::OPS::Delay(DELAY_COUNT);

        ATOMIC::OPS::Store<BOOL>(&IsActiveWriter, FALSE);
        PIN_RWMutexUnlock(&RWMutex);
    }
    CheckIfDone(info, done);
}
Example #8
0
static void DoTestReaderWriterStress(THREAD_INFO *info, UINT32 *done)
{
    // This test uses a mix of "reader" and "writer" threads to acquire and
    // release the PIN_RWMUTEX as fast as possible.

    if (info->_workerId & 1)
    {
        // Reader thread.
        //
        PIN_RWMutexReadLock(&RWMutex);
        PIN_RWMutexUnlock(&RWMutex);
    }
    else
    {
        // Writer thread.
        //
        PIN_RWMutexWriteLock(&RWMutex);
        PIN_RWMutexUnlock(&RWMutex);
    }
    CheckIfDone(info, done);
}
Example #9
0
/*
 * Malloc, Realloc
 * Catchs Memory allocations and insert the information to BST
 * Info : Address, Size
 */
VOID * Malloc( CONTEXT * context, AFUNPTR orgFuncptr, size_t size)
{
    VOID * ret;

    PIN_CallApplicationFunction( context, PIN_ThreadId(),
                                 CALLINGSTD_DEFAULT, orgFuncptr,
                                 PIN_PARG(void *), &ret,
                                 PIN_PARG(size_t), size,
                                 PIN_PARG_END() );

	PIN_RWMutexWriteLock(&malloc_lock);
	malloc_root = InsertMAddress(malloc_root, (ADDRINT)ret, size, 0);
	PIN_RWMutexUnlock(&malloc_lock);
    return ret;
}
Example #10
0
/*
 * Fini
 * Called when process ends
 * Clean up mems & locks
 */
VOID Fini(INT32 code, VOID *v)
{
	PIN_RWMutexWriteLock(&malloc_lock);
	while(malloc_root != NULL)
		malloc_root = DeleteAddress(malloc_root, malloc_root->address);
	PIN_RWMutexUnlock(&malloc_lock);

	PIN_RWMutexWriteLock(&data_lock);
	while(data_root != NULL)
		data_root = DeleteAddress(data_root, data_root->address);
	PIN_RWMutexUnlock(&data_lock);

	PIN_RWMutexWriteLock(&thread_lock);
	while(root_thread != NULL)
		root_thread = DeleteThread(root_thread->tid, root_thread);
	PIN_RWMutexUnlock(&thread_lock);

	PIN_RWMutexFini(&thread_lock);
	PIN_RWMutexFini(&data_lock);
	PIN_RWMutexFini(&malloc_lock);
	PIN_MutexFini(&readid_lock);

	fclose(trace);
}
Example #11
0
/*
 * Return
 * Called when native procedure returns
 * Delete read info of removed stack area
 */
VOID Return(ADDRINT sp)
{
	PIN_THREAD_UID threadid = PIN_ThreadUid();
	PIN_RWMutexReadLock(&thread_lock);
	THREAD* thread = FindThread(threadid);
	PIN_RWMutexUnlock(&thread_lock);
	treeNode *node = FindMinAddress(thread->stack);
	if(node == NULL)
		return;
	while(node->address <= sp)
	{
		thread->stack = DeleteAddress(thread->stack, node->address);
		node = FindMinAddress(thread->stack);
		if(node == NULL)
			return;
	}
}
Example #12
0
/*
 * Free
 * Delete Allocation Info from BST
 */
VOID Free( CONTEXT * context, AFUNPTR orgFuncptr, void * ptr)
{
    if(ptr != NULL)
    {
    	if(!FindAddress(malloc_root, (ADDRINT)ptr))
    	{
			PIN_RWMutexWriteLock(&malloc_lock);
			malloc_root = DeleteMAddress(malloc_root, (ADDRINT)ptr);
			PIN_RWMutexUnlock(&malloc_lock);
    	}
    }

    PIN_CallApplicationFunction( context, PIN_ThreadId(),
                                 CALLINGSTD_DEFAULT, orgFuncptr,
                                 PIN_PARG(void),
                                 PIN_PARG(void *), ptr,
                                 PIN_PARG_END() );
}
Example #13
0
VOID StackWrite(ADDRINT memaddr, ADDRINT writesize)
{
	treeNode *node;
	PIN_THREAD_UID threadid = PIN_ThreadUid();
	ADDRINT startoffset, endoffset;

	PIN_RWMutexReadLock(&thread_lock);
	THREAD* thread = FindThread(threadid);
	PIN_RWMutexUnlock(&thread_lock);

	node = FindAddressInRange(thread->stack, memaddr);
	if(node && node->usedforread == TRUE)
	{
		startoffset = memaddr - node->address + node->offset;
		endoffset = memaddr - node->address + node->offset + writesize;

		fprintf(trace, "%x%lx:%s:%lx:%lx:S\n", pid, node->readid, node->path, startoffset, endoffset);
		fflush(trace);
	}
}
Example #14
0
static void DoTestWriterIntegrity(THREADID tid, THREAD_INFO *info, UINT32 *done)
{
    // This test checks to see if two writer threads can be in the PIN_RWMUTEX mutex
    // simultaneously.

    PIN_RWMutexWriteLock(&RWMutex);
    THREADID owner = HasLock;
    HasLock = tid;

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

    ATOMIC::OPS::Delay(DELAY_COUNT);

    HasLock = INVALID_THREADID;
    PIN_RWMutexUnlock(&RWMutex);

    CheckIfDone(info, done);
}
Example #15
0
/*
 * SysBefore
 * Our focus is on "read" syscall, so it traces only read-like syscalls - read, readv, pread, preadv
 */
VOID SysBefore(ADDRINT ip, ADDRINT num, ADDRINT arg0, ADDRINT arg1, ADDRINT arg2, ADDRINT arg3, ADDRINT arg4, ADDRINT arg5, ADDRINT sp)
{

	treeNode *node;
	struct stat stat;
	off_t offset;
	char buf[2][MAX_BUFSIZE];
	int tmp;
	int i;
	long unsigned int readid;
	long unsigned int size;
	struct iovec *vec;

	PIN_THREAD_UID threadid = PIN_ThreadUid();
	PIN_RWMutexReadLock(&thread_lock);
	THREAD* thread = FindThread(threadid);
	PIN_RWMutexUnlock(&thread_lock);
	assert(thread);

	switch(num)
	{
	case SYS_READ:
	case SYS_PREAD64:
		//arg0 : fd
		//arg1 : buf addr
		//arg2 : buf size

		//stdin
		if(arg0 == 0)
			break;

		//Get the path of current file
		sprintf(buf[0], "/proc/self/fd/%d", (int)arg0);
		tmp = readlink(buf[0], buf[1], MAX_BUFSIZE);

		//Skip socket, pipe, proc filesystem, etc
		if(buf[1][0] != '/')
			break;

		if(strncmp(buf[1], "/proc", 5) == 0)
			break;
		else if(strncmp(buf[1], "/dev/urandom", 12)== 0)
			break;

		buf[1][tmp] = '\0';

		if(num == SYS_READ)
		{
			//If SYS_READ, we have to find out current file pointer
			offset = lseek((int)arg0, 0, SEEK_CUR);
			if(offset+1 == 0)
				offset = 0;
		}
		else
		{
			//Or pread case, file pointer is given
			offset = arg3;
		}

		//Get the file size
		size = fstat((int)arg0, &stat);
		assert(size == 0);

		size = stat.st_size;
		if(offset+arg2 > size)
			size = size - offset;
		else
			size = arg2;
		if(size <= 0)
			break;

		//Get Unique ID for each Read
		readid = GetReadId();

		sprintf(thread->buffer, "%s:%lx:%lx:%lx:", buf[1], offset, size, stat.st_size);

		/*
		 * Add Read Info to Data Structure
		 *
		 * Find the buffer address in malloc BST
		 * 	if found, write the info to it
		 *  else
		 *  	Buffer is in stack or data segment
		 */
		PIN_RWMutexReadLock(&malloc_lock);
		node = FindAddressInRange(malloc_root, arg1);
		PIN_RWMutexUnlock(&malloc_lock);
		if(node != NULL)
		{
			node->usedforread = TRUE;
			node->offset = offset;
			node->fd = (int)arg0;
			if(node->path != NULL)
				free(node->path);
			node->path = strdup(buf[1]);
			node->size = size;
			node->readid = readid;
			strcat(thread->buffer, "M");
		}
		else if(arg1 >= sp - pagesize)
		{
			thread->stack = InsertSAddress(thread->stack, arg1, (int)arg0, size, offset, buf[1], readid);
			strcat(thread->buffer, "S");
		}
		else
		{
			PIN_RWMutexWriteLock(&data_lock);
			data_root = InsertDAddress(data_root, arg1, (int)arg0, size, offset, buf[1], readid);
			PIN_RWMutexUnlock(&data_lock);
			strcat(thread->buffer, "D");
		}
		fprintf(trace, "%s\n", thread->buffer);
		fflush(trace);
		break;

	case SYS_PREADV:
	case SYS_READV:
		//arg0 : fd
		//arg1 : iov
		//arg2 : iovcnt
		//iovec.iov_base : address
		//iovec.iov_len : length

		//stdin
		if(arg0 == 0)
			break;

		sprintf(buf[0], "/proc/self/fd/%d", (int)arg0);
		tmp = readlink(buf[0], buf[1], MAX_BUFSIZE);
		if(buf[1][0] != '/')
			break;

		if(strncmp(buf[1], "/proc", 5) == 0)
			break;

		readid = GetReadId();
		buf[1][tmp] = '\0';

		if(num == SYS_READV)
		{
			offset = lseek((int)arg0, 0, SEEK_CUR);
			if(offset+1 == 0)
				offset = 0;
		}
		else
			offset = arg3;

		size = fstat((int)arg0, &stat);
		assert(size == 0);


		vec = (struct iovec *)arg1;
		for(i=0; i < (int)arg2; i++)
		{
			size = stat.st_size;
			if(offset+vec[i].iov_len > size)
				size = size - offset;
			else
				size = vec[i].iov_len;

			if(size <= 0)
				continue;

			PIN_RWMutexReadLock(&malloc_lock);
			node = FindAddressInRange(malloc_root, (ADDRINT)vec[i].iov_base);
			PIN_RWMutexUnlock(&malloc_lock);
			sprintf(thread->buffer, "%s:%lx:%lx:%lx:",buf[1], offset, size, stat.st_size);

			if(node != NULL)
			{
				strcat(thread->buffer, "M");
				node->usedforread = TRUE;
				node->offset = offset;
				node->fd = (int)arg0;
				if(node->path != NULL)
					free(node->path);
				node->path = strdup(buf[1]);
				node->size = size;
				node->readid = readid;
			}
			else if(arg1 >= sp - pagesize)
			{
				strcat(thread->buffer, "S");
				thread->stack = InsertSAddress(thread->stack, arg1, (int)arg0, size, offset, buf[1], readid);
			}
			else
			{
				strcat(thread->buffer, "D");
				PIN_RWMutexWriteLock(&data_lock);
				data_root = InsertDAddress(data_root, arg1, (int)arg0, size, offset, buf[1], readid);
				PIN_RWMutexUnlock(&data_lock);
			}
			fprintf(trace, "%s\n", thread->buffer);
			fflush(trace);
		}
		break;

		/*
	case SYS_WRITE:
	case SYS_PWRITE64:
		if(arg0 == 1 || arg0 == 2)
			break;

		if(num == SYS_WRITE)
		{
			offset = lseek((int)arg0, 0, SEEK_CUR);
			if(offset + 1 == 0)
				offset = 0;
		}
		else
			offset = arg3;

		sprintf(thread->buffer, "%lx:%lx:%lx:%lx:%lx:", num, arg0, arg1, arg2, offset);
		break;

	case SYS_PWRITEV:
	case SYS_WRITEV:
		//stdin
		if(arg0 == 0)
			break;

		sprintf(buf[0], "/proc/self/fd/%d", (int)arg0);
		tmp = readlink(buf[0], buf[1], MAX_BUFSIZE);
		buf[1][tmp] = '\0';

		if(num == SYS_PWRITEV)
		{
			offset = lseek((int)arg0, 0, SEEK_CUR);
			if(offset + 1 == 0)
				offset = 0;
		}
		else
			offset = arg3;

		vec = (struct iovec *)arg1;
		for(i=0; i < (int)arg2; i++)
		{
			sprintf(thread->buffer, "%lx:%lx:%lx:%lx:%lx:", num, arg0, (ADDRINT)vec[i].iov_base, vec[i].iov_len, offset);
		}
		break;
		*/

	default :
		break;
	}
}
Example #16
0
static void DoTestTryLocks(UINT32 *done)
{
    // This is a collection of single-thread tests that make sure that the
    // various "try" operations succeed or fail as expected.

    BOOL gotLock = PIN_MutexTryLock(&Mutex);
    if (!gotLock)
    {
        std::cout << "Failure on uncontended PIN_MutexTryLock" << std::endl;
        PIN_ExitProcess(1);
    }

    gotLock = PIN_MutexTryLock(&Mutex);
    if (gotLock)
    {
        std::cout << "PIN_MutexTryLock was able to get a lock twice" << std::endl;
        PIN_ExitProcess(1);
    }

    gotLock = PIN_RWMutexTryWriteLock(&RWMutex);
    if (!gotLock)
    {
        std::cout << "Failure on uncontended PIN_RWMutexTryWriteLock" << std::endl;
        PIN_ExitProcess(1);
    }

    gotLock = PIN_RWMutexTryWriteLock(&RWMutex);
    if (gotLock)
    {
        std::cout << "PIN_RWMutexTryWriteLock was able to get a lock twice" << std::endl;
        PIN_ExitProcess(1);
    }

    gotLock = PIN_RWMutexTryReadLock(&RWMutex);
    if (gotLock)
    {
        std::cout << "PIN_RWMutexTryReadLock was able to get a lock when writer owns it" << std::endl;
        PIN_ExitProcess(1);
    }

    PIN_RWMutexUnlock(&RWMutex);
    gotLock = PIN_RWMutexTryReadLock(&RWMutex);
    if (!gotLock)
    {
        std::cout << "Failure on uncontended PIN_RWMutexTryReadLock" << std::endl;
        PIN_ExitProcess(1);
    }

    gotLock = PIN_RWMutexTryReadLock(&RWMutex);
    if (!gotLock)
    {
        std::cout << "Unable to get a reader lock twice" << std::endl;
        PIN_ExitProcess(1);
    }

    PIN_SemaphoreSet(&Sem1);
    if (!PIN_SemaphoreIsSet(&Sem1))
    {
        std::cout << "Expected 'set' status from PIN_SemaphoreIsSet" << std::endl;
        PIN_ExitProcess(1);
    }

    PIN_SemaphoreClear(&Sem1);
    if (PIN_SemaphoreIsSet(&Sem1))
    {
        std::cout << "Expected 'clear' status from PIN_SemaphoreIsSet" << std::endl;
        PIN_ExitProcess(1);
    }

    if (PIN_SemaphoreTimedWait(&Sem1, 1))
    {
        std::cout << "Expected PIN_SemaphoreTimedWait to time-out" << std::endl;
        PIN_ExitProcess(1);
    }

    *done = 1;
}