void EventHandler<T>::setName(char *newIdStr) { free(idstr); idstr = strdup(newIdStr); // Update the thread map if (threadmap->defines(getExecThreadID())) { free((*threadmap)[getExecThreadID()]->name); (*threadmap)[getExecThreadID()]->name = strdup(idstr); } else { fprintf(stderr, "ERROR: threadMap does not contain name for thread %lu (%s)\n", getExecThreadID(), idstr); } }
void EventHandler<T>::addToThreadMap() { assert(tid == (unsigned long) -1); assert(threadMapLock != NULL); tid = getExecThreadID(); threadMapLock->_Lock(FILE__, __LINE__); if (threadmap->defines(tid)) { // Can happen if we reuse threads... nuke the old. if ((*threadmap)[tid]->active == true) { // Weird... fprintf(stderr, "Warning: replacing thread %s that's still marked as active\n", (*threadmap)[tid]->name); } assert((*threadmap)[tid]->active == false); // We create a new name when we deactivate - delete it here. free((*threadmap)[tid]->name); threadmap_t *foo = (*threadmap)[tid]; threadmap->undef(tid); delete foo; } threadmap_t *t = new threadmap_t; t->name = strdup(idstr); t->active = true; (*threadmap)[tid] = t; threadMapLock->_Unlock(FILE__, __LINE__); }
bool SignalHandler::handleLwpExit(EventRecord &ev, bool &continueHint) { thread_printf("%s[%d]: welcome to handleLwpExit\n", FILE__, __LINE__); signal_printf("%s[%d]: welcome to handleLwpExit\n", FILE__, __LINE__); process *proc = ev.proc; dyn_lwp *lwp = ev.lwp; dyn_thread *thr = NULL; //Find the exiting thread for (unsigned i=0; i<proc->threads.size(); i++) { if (proc->threads[i]->get_lwp()->get_lwp_id() == lwp->get_lwp_id()) { thr = proc->threads[i]; break; } } if (proc->IndependentLwpControl()) { proc->set_lwp_status(ev.lwp, exited); } ev.lwp->set_dead(); if (!thr) { // DOA thread... continueHint = true; return true; } BPatch::bpatch->registerThreadExit(proc, thr->get_tid(), false); flagBPatchStatusChange(); #if defined(os_windows) if (getExecThreadID() != sg->getThreadID()) { signal_printf("%s[%d][%s]: signalling active process\n", FILE__, __LINE__, getThreadStr(getExecThreadID())); sg->requested_wait_until_active = false; sg->signalActiveProcess(); } #endif #if defined(os_linux) sg->unregisterLWP(lwp->get_lwp_id()); #endif continueHint = true; return true; }
void EventHandler<T>::removeFromThreadMap() { // remove ourselves from the threadmap before exiting assert(threadMapLock != NULL); threadMapLock->_Lock(FILE__, __LINE__); if (threadmap->defines(getExecThreadID())) { (*threadmap)[getExecThreadID()]->active = false; // We mark the fact that the thread is deleted by changing out the name. char *oldname = (*threadmap)[getExecThreadID()]->name; assert(oldname); char *newname = (char *)malloc(strlen(oldname) + strlen("-DELETED") + 1); sprintf(newname, "%s-DELETED", oldname); (*threadmap)[getExecThreadID()]->name = newname; free(oldname); } threadMapLock->_Unlock(FILE__, __LINE__); }
void initializeThreadMap() { if (threadMapLock != NULL) return; threadMapLock = new eventLock; threadMapLock->_Lock(FILE__, __LINE__); threadmap = new dictionary_hash<Address, threadmap_t *>(addrHash4); assert(threadmap->size() == 0); assert(getExecThreadID() == primary_thread_id); // Initialization threadmap_t *t = new threadmap_t; t->active = true; t->name = strdup("UI"); #if defined(os_windows) (*threadmap)[_threadid] = t; #else (*threadmap)[getExecThreadID()] = t; #endif threadMapLock->_Unlock(FILE__, __LINE__); }
int infmalloc_printf_int(const char *format, ...) { if (!dyn_debug_infmalloc) return 0; if (NULL == format) return -1; debugPrintLock->lock(); fprintf(stderr, "[%ld]", getExecThreadID()); va_list va; va_start(va, format); int ret = vfprintf(stderr, format, va); va_end(va); debugPrintLock->unlock(); return ret; }
int bpfatal_lf(const char *__file__, unsigned int __line__, const char *format, ...) { fprintf(stderr, "%s[%d]\n", __FILE__, __LINE__); if (NULL == format) return -1; char errbuf[ERR_BUF_SIZE]; fprintf(stderr, "%s[%d]\n", __FILE__, __LINE__); int header_len = sprintf(errbuf, "[%ld]%s[%d]: ", getExecThreadID(), __file__, __line__); fprintf(stderr, "%s[%d]\n", __FILE__, __LINE__); va_list va; va_start(va, format); VSNPRINTF(errbuf + header_len, ERR_BUF_SIZE - header_len, format, va); va_end(va); fprintf(stderr, "%s[%d]\n", __FILE__, __LINE__); BPatch::reportError(BPatchFatal, 0, errbuf); fprintf(stderr, "%s[%d]\n", __FILE__, __LINE__); return 0; }
EventRecord &EventGate::wait(bool executeCallbacks /* = true */) { trigger.type = evtUndefined; assert(lock->depth()); still_waiting: waiting = true; if (executeCallbacks) getMailbox()->executeCallbacks(FILE__, __LINE__); if (trigger.type != evtUndefined) { return trigger; } extern int dyn_debug_signal; if (dyn_debug_signal) { signal_printf("%s[%d][%s]: waiting for event matching:\n", FILE__, __LINE__, getThreadStr(getExecThreadID())); for (unsigned int i = 0; i < evts.size(); ++i) { char buf[1024]; signal_printf("\t%s\n", evts[i].sprint_event(buf)); } } lock->_WaitForSignal(FILE__, __LINE__); waiting = false; bool triggered = false; for (unsigned int i = 0; i < evts.size(); ++i) { if (evts[i].isTemplateOf(trigger)) { triggered = true; break; } } if (!triggered) goto still_waiting; return trigger; }
void EventHandler<T>::main() { addToThreadMap(); thread_printf("%s[%d]: welcome to main() for %s\n", __FILE__, __LINE__, idstr); thread_printf("%s[%d]: new thread id %lu -- %s\n", __FILE__, __LINE__, tid, idstr); startupLock->_Lock(__FILE__, __LINE__); thread_printf("%s[%d]: about to do init for %s\n", __FILE__, __LINE__, idstr); if (!initialize_event_handler()) { _isRunning = false; init_ok = false; removeFromThreadMap(); startupLock->_Broadcast(__FILE__, __LINE__); startupLock->_Unlock(__FILE__, __LINE__); return; } init_ok = true; thread_printf("%s[%d]: init success for %s\n", __FILE__, __LINE__, idstr); _isRunning = true; startupLock->_Broadcast(__FILE__, __LINE__); startupLock->_Unlock(__FILE__, __LINE__); T ev; thread_printf("%s[%d]: before main loop for %s\n", __FILE__, __LINE__, idstr); while (1) { if (!this->waitNextEvent(ev)) { fprintf(stderr, "%s[%d][%s]: waitNextEvent failed \n", __FILE__, __LINE__,getThreadStr(getExecThreadID())); if (!stop_request) continue; } if (stop_request) { thread_printf("%s[%d]: thread terminating at stop request\n", __FILE__, __LINE__); break; } if (!handleEvent(ev)) { fprintf(stderr, "%s[%d][%s]: handleEvent() failed\n", __FILE__, __LINE__, getThreadStr(getExecThreadID())); } if (stop_request) break; } global_mutex->_Lock(FILE__, __LINE__); removeFromThreadMap(); _isRunning = false; if (global_mutex->depth() != 1) { fprintf(stderr, "%s[%d]: WARNING: global_mutex->depth() is %d, leaving thread %s\n", FILE__, __LINE__, global_mutex->depth(),idstr); global_mutex->printLockStack(); } assert(global_mutex->depth() == 1); global_mutex->_Broadcast(FILE__, __LINE__); global_mutex->_Unlock(FILE__, __LINE__); thread_printf("%s[%d][%s]: InternalThread::main exiting\n", FILE__, __LINE__, idstr); }
bool rpcLWP::handleCompletedIRPC() { inferiorrpc_cerr << "Completed lwp RPC " << runningRPC_->rpc->id << " on lwp " << lwp_->get_lwp_id() << endl; // step 1) restore registers: if (runningRPC_->savedRegs) { bool savedFP = runningRPC_->rpc->saveFPState; if (!lwp_->restoreRegisters(*runningRPC_->savedRegs, savedFP)) { cerr << "handleCompletedIRPC failed because restoreRegisters failed" << endl; assert(false); } delete runningRPC_->savedRegs; // The above implicitly must restore the PC. } else { inferiorrpc_printf("%s[%d]: odd case with no saved registers, changing PC to 0x%lx\n", FILE__, __LINE__, runningRPC_->origPC); if (!lwp_->changePC(runningRPC_->origPC, NULL)) assert(0 && "Failed to reset PC"); } // step 2) delete temp tramp process *proc = lwp_->proc(); proc->deleteCodeRange(runningRPC_->rpcStartAddr); proc->inferiorFree(runningRPC_->rpcStartAddr); // save enough information to call the callback function, if needed inferiorRPCcallbackFunc cb = runningRPC_->rpc->callbackFunc; void* userData = runningRPC_->rpc->userData; void* resultValue = runningRPC_->resultValue; unsigned id = runningRPC_->rpc->id; // Save whether we were running or not bool runProcess = runningRPC_->runProcWhenDone; // And blow away the data structures mgr_->removeRunningRPC(runningRPC_); delete runningRPC_->rpc; delete runningRPC_; runningRPC_ = NULL; // step 3) invoke user callback, if any // call the callback function if needed if( cb != NULL ) { cb(proc, id, userData, resultValue); inferiorrpc_printf("%s[%d][%s]: registered/exec'd callback %p\n", FILE__, __LINE__, getThreadStr(getExecThreadID()), (void *) (*cb)); } // Before we continue the process: if there is another RPC, // start it immediately (instead of waiting for an event loop // to do the job) if (isReadyForIRPC()) { irpcLaunchState_t launchState = launchLWPIRPC(runProcess); if (launchState == irpcStarted) { // Run the process return true; } } return runProcess; }