/* * 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); }
/* * 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); }
void Scheduler::SetPriority(int priority) { DEBUG_FMT_PRINT_SAFE("[T%lx] set priority = %d\n", PIN_ThreadUid(), priority); if (knob_->ValueBool("strict")) { SetStrictPriority(priority); } else { SetRelaxPriority(priority); } }
VOID ThreadStart(THREADID threadIndex, CONTEXT *ctxt, INT32 flags, VOID *v) { PRINT_ME_AND_MY_FATHER(); // only the new thread should check it if (PIN_GetParentTid() != INVALID_OS_THREAD_ID) { TEST(PIN_GetParentTid() == father_id, "PIN_GetParentTid failed"); } TEST(PIN_ThreadUid() != INVALID_PIN_THREAD_UID, "PIN_ThreadUid failed"); }
/* * 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; } }
Thread * Thread::current (void) { // Get the current thread in TLS, and return if exists. THREADID thr_id = PIN_ThreadId (); Thread * thr = Thread::current_.get (thr_id); if (0 != thr) return thr; // This could be the main thread, which does not have an Thread object // in the TLS. So, create a new thread, and store it. thr = new Thread (thr_id, PIN_GetTid (), PIN_ThreadUid (), PIN_GetParentTid ()); Thread::current_.set (thr_id, thr); return thr; }
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); } }
/* * 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; } }
void Scheduler::RandomDelay() { useconds_t t = (useconds_t)((double)delay_unit_ * random_number()); DEBUG_FMT_PRINT_SAFE("[T%lx] Delay time = %lu microseconds\n", PIN_ThreadUid(), (unsigned long)t); usleep(t); }