void InstructionTrace(INS ins, void* v) { // check if we just received a snapshot request bool snapshotStatus = CheckSnapshotEvent(); if (snapshotStatus) { // We just detected a monitoring change! Take a memory snapshot now TakeSnapshot(); // reset the event DisableSnapshotEvent(); } // check the monitoring event if we should still be monitoring or not bool monitoringStatus = CheckMonitoringEvent(); if (!monitoringStatus) { return; } instruction_trace trace; trace.tid = PIN_GetTid(); trace.address = INS_Address(ins); memset(trace.library_name, 0, 260); std::string libraryName; if (CHECK_LIBRARY_NAMES && GetLibraryName(trace.address, libraryName)) { snprintf(trace.library_name, sizeof(trace.library_name), "%s", libraryName.c_str()); } if (INS_IsCall(ins) == true) { trace.execution_depth = executionDepth++; } else if (INS_IsRet(ins) == true) { trace.execution_depth = executionDepth--; } else trace.execution_depth = executionDepth; trace.instruction_count = instructionCount++; #ifdef TARGET_WINDOWS trace.execution_time = WINDOWS::GetTickCount(); #else timeval time; gettimeofday(&time, NULL); unsigned long millis = (time.tv_sec * 1000) + (time.tv_usec / 1000); trace.execution_time = millis; #endif LogStruct(trace); }
void m_dump_bytes(const void *bytes, size_t size) { if(standard_out) { return; } FILE *file; char temp[1000]; sprintf(temp, "%s.mtrace.byte_dump.%u", KnobOutputFile.Value().c_str(), PIN_GetTid()); file = fopen(temp, "a"); fwrite(bytes, size, 1, file); fflush(file); fclose(file); }
void output_dummy_stacktrace() { FILE *file; if(standard_out) { file = stdout; } else { char temp[1000]; sprintf(temp, "%s.mtrace.stackinfo.%u", KnobOutputFile.Value().c_str(), PIN_GetTid()); file = fopen(temp, "a"); } fprintf(file, "[]\n"); fflush(file); fclose(file); }
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); }
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 mprintf(const char *format, ...) { FILE *file; if(standard_out) { file = stdout; } else { char temp[1000]; sprintf(temp, "%s.mtrace.%u", KnobOutputFile.Value().c_str(), PIN_GetTid()); file = fopen(temp, "a"); } va_list ap; va_start(ap, format); vfprintf(file, format, ap); va_end(ap); fflush(file); fclose(file); }
void output_stacktrace() { FILE *file; if(standard_out) { file = stdout; } else { char temp[1000]; sprintf(temp, "%s.mtrace.stackinfo.%u", KnobOutputFile.Value().c_str(), PIN_GetTid()); file = fopen(temp, "a"); } assert(file != NULL); static int initialized = 0; static void (*actual_function)(FILE *) = NULL; if(initialized == 0) { char *errors; char temp[1000]; void *dl_handle; sprintf(temp, "%s/libstacktrace.so", getenv("MTRACE_HOME")); errors = dlerror(); if(errors != NULL) printf("%s\n", errors); dlopen("libunwind.so", RTLD_NOW | RTLD_GLOBAL); errors = dlerror(); if(errors != NULL) printf("%s\n", errors); dl_handle = dlopen(temp, RTLD_NOW | RTLD_GLOBAL); errors = dlerror(); if(errors != NULL) printf("%s\n", errors); actual_function = (void(*)(FILE*)) dlsym(dl_handle, "output_stacktrace"); assert(actual_function != NULL); initialized = 1; } assert(actual_function != NULL); (*actual_function)(file); fflush(file); fclose(file); }
VOID SyscallEntry(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) { flush_mwrite(threadIndex); ADDRINT num = PIN_GetSyscallNumber(ctxt, std); if(num == SYS_execve) { PrintTime(NULL); output_dummy_stacktrace(); mprintf("mtrace_execve(%ld, %u, %u, %u, %u) = 0\n", syscall(SYS_gettid), PIN_GetTid(), getpid(), threadIndex, PIN_ThreadId()); m_dump_bytes(NULL, 0); return; } if (num != SYS_mmap && num != SYS_munmap) { thread_to_syscall[threadIndex].ip = 0; return; } thread_to_syscall[threadIndex].num = num; thread_to_syscall[threadIndex].ip = PIN_GetContextReg(ctxt, REG_INST_PTR); if(num == SYS_mmap) { for(int i = 0; i < 6; i++) { #if defined(TARGET_LINUX) && defined(TARGET_IA32) thread_to_syscall[threadIndex].args[i] = (reinterpret_cast<ADDRINT *>(PIN_GetSyscallArgument(ctxt, std, 0)))[i]; #else thread_to_syscall[threadIndex].args[i] = PIN_GetSyscallArgument(ctxt, std, i); #endif } } else { for(int i = 0; i < 2; i++) { thread_to_syscall[threadIndex].args[i] = PIN_GetSyscallArgument(ctxt, std, i); } } }
VOID Thread::__thr_run (VOID * arg) { // Get the thread object, and update its remaining attributes. Thread * thr = reinterpret_cast <Thread *> (arg); // Set the current thread to the Thread object. This allows the // client to access the Thread object via the current () method. Thread::current_.set (thr->thr_id_, thr); do { Write_Guard <RW_Mutex> guard (thr->rw_mutex_); thr->os_thr_id_ = PIN_GetTid (); thr->parent_os_thr_id_ = PIN_GetParentTid (); // Set the state to running. thr->state_ = RUNNING; } while (0); // Determine what run method we should invoke. Either we invoke the run() // method on the runnable_ object contained in the thread, or we invoke // the run() method on the thread. The runnable_ variable takes precedence // over the run() method on the Thread. Runnable * runnable = thr->runnable_; if (0 == runnable) runnable = thr; runnable->run (); do { // Reset the thread state. Write_Guard <RW_Mutex> guard (thr->rw_mutex_); thr->state_ = TERMINATED; } while (0); }
VOID ThreadFini(THREADID threadid, const CONTEXT *ctxt, INT32 code, VOID *v) { PIN_GetLock(&lock, PIN_GetTid()); threadEnded++; PIN_ReleaseLock(&lock); }
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v) { PIN_GetLock(&lock, PIN_GetTid()); threadCreated++; PIN_ReleaseLock(&lock); }
VOID AppStart(VOID *v) { father_id = PIN_GetTid(); PRINT_ME_AND_MY_FATHER(); TEST(father_id != INVALID_OS_THREAD_ID, "PIN_GetTid failed"); }
VOID AfterForkInChild(THREADID threadid, const CONTEXT* ctxt, VOID * arg) { PrintTime(NULL); output_dummy_stacktrace(); mprintf("mtrace_fork_child(%ld, %u, %u, %u, %u) = 0\n", syscall(SYS_gettid), PIN_GetTid(), getpid(), threadid, PIN_ThreadId()); m_dump_bytes(NULL, 0); }
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v) { PrintTime(NULL); output_dummy_stacktrace(); mprintf("mtrace_thread_start(%u, %u, %u, %u, %u) = 0\n", syscall(SYS_gettid), PIN_GetTid(), getpid(), threadid, PIN_ThreadId()); m_dump_bytes(NULL, 0); }