Process::cb_ret_t Backend::handleTimeEvent() { // Get all subscribed events set<Event*>& events = Time::getTimeSubscribers(); set<Event*>::iterator eventIter = events.begin(); for(;eventIter != events.end(); eventIter++) { Event* event = *eventIter; ProcessSet::ptr procset = ((Time *)event)->getProcset(); ProcessSet::iterator procIter = procset->begin(); if(procset->size() == 0) continue; if(!event || !event->isEnabled(*procIter)) continue; // this is to avoid a race condition where a time event occurs in the middle of iterating through the processes DYSECTVERBOSE(true, "Time event with timeout %d detected on %d processes", ((Time *)event)->getTimeout(), procset->size()); for(;procIter != procset->end(); procIter++) { Process::ptr procPtr = *procIter; if(event && event->isEnabled(procPtr)) { Thread::ptr threadPtr = procPtr->threads().getInitialThread(); Walker *proc = (Walker *)procPtr->getData(); handleEvent(procPtr, threadPtr, event); } } if(event->getOwner()->getLifeSpan() == fireOnce) event->disable(); } return Process::cbDefault; }
bool Location::disable(ProcessSet::ptr lprocset) { assert(owner != 0); if(codeLocations.empty()) { return Err::verbose(true, "No code locations"); } if(!lprocset) { return Err::warn(false, "Process set not present"); } ProcessSet::iterator procIter = lprocset->begin(); for(;procIter != lprocset->end(); procIter++) { Process::ptr procPtr = *procIter; Walker* proc = (Walker*)procPtr->getData(); vector<DysectAPI::CodeLocation*>::iterator locationIter = codeLocations.begin(); for(;locationIter != codeLocations.end(); locationIter++) { DysectAPI::CodeLocation* location = *locationIter; if(!location->addProcLib(proc)) { return Err::warn(false, "Symbol not found in process"); } vector<Dyninst::Address> addrs; if(!location->getAddrs(proc, addrs) || addrs.empty()) { return Err::warn(false, "Addresses for symbol could not be determined"); } // Breakpoint locations at hand for(int i = 0; i < addrs.size() ; i++) { Dyninst::Address addr = addrs[i]; if(!procPtr->rmBreakpoint(addr, bp)) { Err::verbose(false, "Breakpoint not removed! %s", ProcControlAPI::getLastErrorMsg()); } } } } return true; }
ProcessSet::ptr ProcessMgr::filterExited(ProcessSet::ptr inSet) { if(!inSet) return inSet; if(inSet->empty()) return inSet; ProcessSet::ptr procs = ProcessSet::newProcessSet(); // Filter out exited processes ProcessSet::iterator procIter = inSet->begin(); for(; procIter != inSet->end(); procIter++) { Process::ptr process = *procIter; if(process->isTerminated() || process->isExited() || process->isCrashed() || process->isDetached()) { continue; } procs->insert(process); } return procs; }
bool Location::enable(ProcessSet::ptr lprocset) { assert(owner != 0); if(codeLocations.empty()) { return Err::verbose(true, "No code locations"); } if(!lprocset) { return Err::warn(false, "Process set not present"); } ProcessSet::iterator procIter = lprocset->begin(); AddressSet::ptr addrset = AddressSet::newAddressSet(); if(lprocset->size() <= 0) { return Err::info(true, "Process set empty!"); } // Find library location for target processes for(;procIter != lprocset->end(); procIter++) { Process::ptr procPtr = *procIter; Walker* proc = (Walker*)procPtr->getData(); vector<DysectAPI::CodeLocation*>::iterator locationIter = codeLocations.begin(); for(;locationIter != codeLocations.end(); locationIter++) { DysectAPI::CodeLocation* location = *locationIter; if(!location->addProcLib(proc)) { return Err::warn(false, "Symbol not found in process"); } vector<Dyninst::Address> addrs; if(!location->getAddrs(proc, addrs) || addrs.empty()) { return Err::warn(false, "Addresses for symbol could not be determined"); } // Breakpoint locations at hand for(int i = 0; i < addrs.size() ; i++) { Dyninst::Address addr = addrs[i]; if(!procPtr->addBreakpoint(addr, bp)) { return Err::verbose(false, "Breakpoint not installed: %s", ProcControlAPI::getLastErrorMsg()); } else { Err::verbose(true, "Breakpoint installed at %lx", addr); } //addrset->insert(addr, procPtr); } //if(addrs.empty()) { // Err::verbose(true, "No addresses"); //} } } //if(addrset->size() <= 0) { // return Err::verbose(true, "Empty address set"); //} //if(!lprocset->addBreakpoint(addrset, nbp)) { // return Err::warn(false, "Could not insert breakpoints!"); //} else { // Err::info(true, "%d breakpoints inserted in %d processes", addrset->size(), lprocset->size()); //} return true; }
bool Probe::processRequests() { if(requestQueue.empty()) { return true; } pthread_mutex_lock(&requestQueueMutex); vector<ProbeRequest*> queue = requestQueue; requestQueue.clear(); pthread_mutex_unlock(&requestQueueMutex); ProcessSet::ptr continueSet = ProcessSet::newProcessSet(); // Sort queue deque<ProbeRequest*> sortedQueue; vector<ProbeRequest*>::iterator requestIter = queue.begin(); for(int i = 0; requestIter != queue.end(); requestIter++) { ProbeRequest* request = *requestIter; if(!request) { DYSECTWARN(true, "Invalid request in request queue"); break; } if(request->type == DisableType) { sortedQueue.push_back(request); } else { sortedQueue.push_front(request); } } if (sortedQueue.size() == 0) return true; DYSECTVERBOSE(true, "Handling %d process requests", sortedQueue.size()); deque<ProbeRequest*>::iterator sortedRequestIter = sortedQueue.begin(); for(int i = 0; sortedRequestIter != sortedQueue.end(); sortedRequestIter++) { ProbeRequest* request = *sortedRequestIter; if(!request) { DYSECTWARN(true, "Invalid request in request queue"); break; } DYSECTVERBOSE(true, "processRequests() %d", i++); Probe* probe = request->probe; if(!probe) { DYSECTWARN(false, "Probe not found for disable request!"); break; } ProcessSet::ptr waitingProcs = request->scope; if(waitingProcs && waitingProcs->size() > 0) { DYSECTVERBOSE(true, "Adding %d request processes to %d continue set...", waitingProcs->size(), continueSet->size()); continueSet = continueSet->set_union(waitingProcs); } ProcessSet::ptr operationSet = ProcessSet::newProcessSet(); ProcessSet::ptr stopSet = ProcessSet::newProcessSet(); ProcessSet::ptr scope = request->scope; if(scope && scope->size() > 0) { DYSECTVERBOSE(true, "Adding processes from scope set (%d) to affected procs (%d)", scope->size(), operationSet->size()); operationSet = operationSet->set_union(scope); } // // Filter out detached // operationSet = ProcessMgr::filterDetached(operationSet); stopSet = ProcessMgr::filterDetached(stopSet); DYSECTVERBOSE(true, "%d procs in op set, %d procs in stop set", operationSet->size(), stopSet->size()); // // Stop processes // stopSet = operationSet->getAnyThreadRunningSubset(); if(stopSet && stopSet->size() > 0) { DYSECTVERBOSE(true, "Stopping %d processes", stopSet->size()); stopSet->stopProcs(); } // // Carry out operations // if(operationSet && operationSet->size() > 0) { if(request->type == DisableType) { DYSECTVERBOSE(true, "Disabling %d processes", operationSet->size()); probe->disable(operationSet); } else { DYSECTVERBOSE(true, "Enabling %d processes", operationSet->size()); probe->enableChildren(operationSet); } } // // Processes must be started when all operations have been carried out. // if(operationSet && operationSet->size() > 0) { continueSet = continueSet->set_union(operationSet); } delete(request); } continueSet = ProcessMgr::filterDetached(continueSet); if(continueSet && continueSet->size() > 0) { DYSECTVERBOSE(true, "Continuing %d processes", continueSet->size()); if(continueSet->size() == 1) { ProcessSet::iterator procIter = continueSet->begin(); Process::ptr process = *procIter; DYSECTVERBOSE(true, "Continuing process %d", process->getPid()); } continueSet->continueProcs(); } DYSECTVERBOSE(true, "Done handling requests"); return true; }