bool DepositLightCore::prepare() { DYSECTVERBOSE(true, "Preparing deposit light core action"); #ifdef CALLPATH_ENABLED prepared = true; findAggregates(); string libraryPath; char *envValue; Domain *domain = owner->getDomain(); bool boolRet; vector<Process::ptr>::iterator procIter; ProcessSet::ptr procs; WalkerSet *allWalkers; Process::ptr *proc; ProcDebug *pDebug; if(domain == NULL) return DYSECTWARN(false, "Domain not found when preparing DepositLightCore action"); allWalkers = domain->getAllWalkers(); DYSECTVERBOSE(true, "Preparing deposit light core action %d", allWalkers->size()); envValue = getenv("STAT_PREFIX"); if (envValue != NULL) libraryPath = envValue; else libraryPath = STAT_PREFIX; libraryPath += "/lib/libcallpathwrap.so"; for (WalkerSet::iterator i = allWalkers->begin(); i != allWalkers->end(); i++) { pDebug = dynamic_cast<ProcDebug *>((*i)->getProcessState()); proc = &(pDebug->getProc()); DYSECTVERBOSE(true, "loading library %s", libraryPath.c_str()); // This will fail in launch mode since process hasn't been started yet. We will also try loading the library on finishBE // This will also be called multiple times if multiple probes use this action, but this won't result in any errors if (Backend::loadLibrary(*proc, libraryPath) != OK) { return DYSECTWARN(false, "Failed to load library %s: %s", libraryPath.c_str(), Stackwalker::getLastErrorMsg()); } } DYSECTVERBOSE(true, "Prepared deposit light core action"); #endif //ifdef CALLPATH_ENABLED return true; }
bool PCLibraryState::getAOut(LibAddrPair &ao) { Process::ptr proc = pdebug->getProc(); CHECK_PROC_LIVE; Library::ptr lib = proc->libraries().getExecutable(); if (!lib) { sw_printf("[%s:%u] - Could not get executable\n", FILE__, __LINE__); return false; } ao = LibAddrPair(lib->getName(), lib->getLoadAddress()); return true; }
bool PCLibraryState::updateLibraries() { Process::ptr proc = pdebug->getProc(); CHECK_PROC_LIVE; LibraryPool::iterator i; for (i = proc->libraries().begin(); i != proc->libraries().end(); i++) { checkForNewLib(*i); } return true; }
bool PCLibraryState::getLibraryAtAddr(Address addr, LibAddrPair &lib) { Process::ptr proc = pdebug->getProc(); CHECK_PROC_LIVE; /** * An OS can have a list of platform-special libs (currently only the * vsyscall DSO on Linux). Those don't appear in the normal link_map * and thus won't have dynamic addresses. Check their library range * manually. **/ vector<pair<LibAddrPair, unsigned int> > arch_libs; updateLibsArch(arch_libs); vector<pair<LibAddrPair, unsigned int> >::iterator j; for (j = arch_libs.begin(); j != arch_libs.end(); j++) { string name = (*j).first.first; Address start = (*j).first.second; Address size = (*j).second; if (addr >= start && addr < start + size) { lib.first = name; lib.second = start; return true; } } /** * Look up the address in our cache of libraries **/ bool ret = findInCache(proc, addr, lib); if (ret) { return true; } /** * Cache lookup failed. Instead of iterating over every library, * look at the link map in memory. This allows us to avoid opening * files. **/ // Do a fast in-memory scan ret = memoryScan(proc, addr, lib); if (ret) { return true; } return false; }
void PCLibraryState::checkForNewLib(Library::ptr lib) { if (lib->getData()) return; sw_printf("[%s:%u] - Detected new library %s at %lx, notifying\n", FILE__, __LINE__, lib->getName().c_str(), lib->getLoadAddress()); lib->setData((void *) 0x1); StepperGroup *group = pdebug->getWalker()->getStepperGroup(); LibAddrPair la(lib->getName(), lib->getLoadAddress()); group->newLibraryNotification(&la, library_load); }
bool PCLibraryState::getLibraries(std::vector<LibAddrPair> &libs, bool allow_refresh) { Process::ptr proc = pdebug->getProc(); CHECK_PROC_LIVE; LibraryPool::iterator i; for (i = proc->libraries().begin(); i != proc->libraries().end(); i++) { if (allow_refresh) checkForNewLib(*i); libs.push_back(LibAddrPair((*i)->getName(), (*i)->getLoadAddress())); } vector<pair<LibAddrPair, unsigned int> > arch_libs; vector<pair<LibAddrPair, unsigned int> >::iterator j; updateLibsArch(arch_libs); for (j = arch_libs.begin(); j != arch_libs.end(); j++) { libs.push_back(j->first); } return true; }
bool BucketAgg::collect(void* process, void *thread) { Process::const_ptr process_ptr = *(Process::const_ptr*)process; Thread::const_ptr thread_ptr = *(Thread::const_ptr*)thread; if(!process_ptr) { return DYSECTVERBOSE(false, "Process object not available"); return false; } // Get the rank of the process Probe *owner = getOwner(); if (!owner) { return DYSECTVERBOSE(false, "Could not find Probe owner"); } Domain *dom = owner->getDomain(); if (!dom) { return DYSECTVERBOSE(false, "Could not find Domain"); } std::map<int, Dyninst::ProcControlAPI::Process::ptr> *mpiRankToProcessMap; mpiRankToProcessMap = dom->getMpiRankToProcessMap(); if (!mpiRankToProcessMap) { return DYSECTVERBOSE(false, "Could not find MPI rank map"); } int rank = -1; std::map<int, Dyninst::ProcControlAPI::Process::ptr>::iterator iter; for (iter = mpiRankToProcessMap->begin(); iter != mpiRankToProcessMap->end(); iter++) { if (iter->second == process_ptr) { rank = iter->first; break; } } if (rank == -1) { return DYSECTVERBOSE(false, "Failed to determine Rank"); } // Read the value of the variable ProcDebug* pDebug; Walker* proc = (Walker*)process_ptr->getData(); if(!proc) { return DYSECTVERBOSE(false, "Could not get walker from process"); } bool wasRunning; if (process_ptr->allThreadsRunning()) { wasRunning = true; pDebug = dynamic_cast<ProcDebug *>(proc->getProcessState()); if (pDebug == NULL) { return DYSECTWARN(false, "Failed to dynamic_cast ProcDebug pointer"); } if (pDebug->isTerminated()) { return DYSECTWARN(false, "Process is terminated"); } if (pDebug->pause() == false) { return DYSECTWARN(false, "Failed to pause process"); } } DataRef ref(Value::floatType, variableName.c_str()); TargetVar var(variableName.c_str()); ConditionResult condRes; Value val; DysectErrorCode readStatus = var.getValue(condRes, val, process_ptr, thread_ptr->getTID()); if (wasRunning == true) { if (pDebug->resume() == false) { return DYSECTWARN(false, "Failed to resume process"); } } if (readStatus != OK) { return DYSECTWARN(false, "Could not read value from reference"); } if (condRes != Resolved) { return DYSECTINFO(false, "Value not available - could be optimized out!"); } if (variableType == Value::noType) { variableType = val.getType(); } int bucket = getBucketFromValue(val); buckets[bucket] += 1; string valStr; val.getStr(valStr); DYSECTVERBOSE(true, "Rank %d read the value %s and will place it in bucket %d", rank, valStr.c_str(), bucket); return true; }