void Process::executeProcess(){ IntVTime sendTime = dynamic_cast<const IntVTime&>(getSimulationTime()); do { PHOLDEvent* recvEvent = (PHOLDEvent*) getEvent(); if( recvEvent != NULL ){ ProcessState* myState = (ProcessState *) getState(); myState->eventReceived(); SimulationObject* receiver = getDestination(myState); // Generate the delay between the send and receive times. int ldelay = msgDelay(); IntVTime recvTime = sendTime + 1 + ldelay; PHOLDEvent* newRequest = new PHOLDEvent(sendTime, recvTime, this, receiver); newRequest->numberOfHops = recvEvent->numberOfHops + 1; newRequest->eventNumber = recvEvent->eventNumber; computationGrain(); receiver->receiveEvent(newRequest); myState->eventSent(); } } while(haveMoreEvents() == true); // end of while loop }
void Process::finalize(){ SEVERITY severity = NOTE; ProcessState* myState = dynamic_cast<ProcessState*>(getState()); ASSERT(myState != NULL); ostringstream oss; oss << " Sent: " << myState->getNumSent() << " Received: " << myState->getNumReceived(); string msg = myObjectName + oss.str() + "\n"; cout << msg; reportError( msg, severity ); }
bool StackCallback::beginStackWalk(Thread::ptr thr) { assert(!cur); Process::ptr proc = thr->getProcess(); ProcessState *pstate = ProcessState::getProcessStateByPid(proc->getPid()); if (!pstate) { sw_printf("[%s:%u] - Error, unknown process state for %d while starting stackwalk\n", FILE__, __LINE__, proc->getPid()); return false; } cur_walker = pstate->getWalker(); cur = tree.getHead(); return true; }
static int ConvertModulesToJSON(const ProcessState& aProcessState, OrderedModulesMap& aOrderedModules, Json::Value& aNode) { const CodeModules* modules = aProcessState.modules(); if (!modules) { return -1; } // Create a sorted set of modules so that we'll be able to lookup the index // of a particular module. for (unsigned int i = 0; i < modules->module_count(); ++i) { aOrderedModules.insert( std::pair<const CodeModule*, unsigned int>( modules->GetModuleAtSequence(i), i ) ); } uint64_t mainAddress = 0; const CodeModule *mainModule = modules->GetMainModule(); if (mainModule) { mainAddress = mainModule->base_address(); } unsigned int moduleCount = modules->module_count(); int mainModuleIndex = -1; for (unsigned int moduleSequence = 0; moduleSequence < moduleCount; ++moduleSequence) { const CodeModule *module = modules->GetModuleAtSequence(moduleSequence); if (module->base_address() == mainAddress) { mainModuleIndex = moduleSequence; } Json::Value moduleNode; moduleNode["filename"] = PathnameStripper::File(module->code_file()); moduleNode["code_id"] = PathnameStripper::File(module->code_identifier()); moduleNode["version"] = module->version(); moduleNode["debug_file"] = PathnameStripper::File(module->debug_file()); moduleNode["debug_id"] = module->debug_identifier(); moduleNode["base_addr"] = ToHex(module->base_address()); moduleNode["end_addr"] = ToHex(module->base_address() + module->size()); aNode.append(moduleNode); } return mainModuleIndex; }
void Process::initialize() { for (int i = 0; i < outputNames.size(); i++) outputHandles.push_back(getObjectHandle(outputNames[i])); // replace hotspots with their indexes in our output handles // delete hotspots that are not in our neighborhood vector<vector<int> >::iterator it(hotspots.begin()); for(; it != hotspots.end(); ++it) { vector<int>::iterator iit((*it).begin()); while(iit != (*it).end()) { int n = procNumToOutputNum(*iit); if(n < 0 || n >= numberOfOutputs) (*it).erase(iit); else *iit++ = n; } } ProcessState* myState = dynamic_cast<ProcessState *>( getState() ); ASSERT(myState != NULL); delete myState->gen; // delete old copy myState->gen = new MLCG(processNumber, (processNumber + 1)); for (int i = 0; i < myState->sizeOfStateData; i++) { myState->stateBulk[i] = '1'; } // Process numbers have to be 0, 1, 2, ... to get a fully ordered // and sequenced set of event numbers in steps of 1. int eventNumberBase = numberOfTokens * processNumber; for(int i = 1; i <= numberOfTokens; i++ ) { IntVTime sendTime = dynamic_cast<const IntVTime&>(getSimulationTime()); int ldelay = msgDelay(); PHOLDEvent *event = new PHOLDEvent(sendTime, sendTime + 1 + ldelay, this, this); event->eventNumber = eventNumberBase + i; receiveEvent(event); myState->eventSent(); } }
static void ConvertProcessStateToJSON(const ProcessState& aProcessState, Json::Value& aRoot) { // We use this map to get the index of a module when listed by address OrderedModulesMap orderedModules; // Crash info Json::Value crashInfo; int requestingThread = aProcessState.requesting_thread(); if (aProcessState.crashed()) { crashInfo["type"] = aProcessState.crash_reason(); crashInfo["address"] = ToHex(aProcessState.crash_address()); if (requestingThread != -1) { crashInfo["crashing_thread"] = requestingThread; } } else { crashInfo["type"] = Json::Value(Json::nullValue); // Add assertion info, if available string assertion = aProcessState.assertion(); if (!assertion.empty()) { crashInfo["assertion"] = assertion; } } aRoot["crash_info"] = crashInfo; // Modules Json::Value modules(Json::arrayValue); int mainModule = ConvertModulesToJSON(aProcessState, orderedModules, modules); if (mainModule != -1) { aRoot["main_module"] = mainModule; } aRoot["modules"] = modules; // Threads Json::Value threads(Json::arrayValue); int threadCount = aProcessState.threads()->size(); for (int threadIndex = 0; threadIndex < threadCount; ++threadIndex) { Json::Value thread; Json::Value stack(Json::arrayValue); const CallStack* rawStack = aProcessState.threads()->at(threadIndex); ConvertStackToJSON(aProcessState, orderedModules, rawStack, stack); thread["frames"] = stack; threads.append(thread); } aRoot["threads"] = threads; }
int main(int argc, char *argv[]) { BPLOG_INIT(&argc, &argv); if (argc <= 1) { std::cerr << "Usage: " << argv[0] << " <config file path>" << std::endl; return 1; } std::ifstream configFile; configFile.open(argv[1]); if (!configFile.is_open()) { std::cerr << "Failed to open config file for reading: " << argv[1] << std::endl; return 1; } json config; configFile >> config; configFile.close(); const auto &beanstalkHost = config["beanstalk"]["host"]; const auto &beanstalkPort = config["beanstalk"]["port"]; const auto &beanstalkQueue = config["beanstalk"]["queue"]; Client queue(beanstalkHost, beanstalkPort); queue.watch(beanstalkQueue); BPLOG(INFO) << "Connected to beanstalkd @ " << beanstalkHost << ":" << beanstalkPort << " (queue: " << beanstalkQueue << ")"; const auto &mysqlHost = config["mysql"]["host"]; const auto &mysqlPort = config["mysql"]["port"]; const auto &mysqlUser = config["mysql"]["user"]; const auto &mysqlPassword = config["mysql"]["password"]; const auto &mysqlDatabase = config["mysql"]["database"]; Connection mysql( mysqlDatabase.get<string>().c_str(), mysqlHost.is_null() ? nullptr :mysqlHost.get<string>().c_str(), mysqlUser.is_null() ? nullptr :mysqlUser.get<string>().c_str(), mysqlPassword.is_null() ? nullptr :mysqlPassword.get<string>().c_str(), mysqlPort); BPLOG(INFO) << "Connected to MySQL @ " << mysql.ipc_info() << " (database: " << mysqlDatabase << ")"; const std::vector<string> &symbolPaths = config["breakpad"]["symbols"]; CompressedSymbolSupplier symbolSupplier(symbolPaths); const string &minidumpDirectory = config["breakpad"]["minidumps"]; Job job; while (true) { if (!queue.reserve(job) || !job) { BPLOG(ERROR) << "Failed to reserve job."; break; } const json body = json::parse(job.body()); const string &id = body["id"]; BPLOG(INFO) << id << " " << body["ip"] << " " << body["owner"]; auto start = std::chrono::steady_clock::now(); // Create this inside the loop to avoid keeping a global symbol cache. RepoSourceLineResolver resolver; MinidumpProcessor minidumpProcessor(&symbolSupplier, &resolver); std::string minidumpFile = minidumpDirectory + "/" + id.substr(0, 2) + "/" + id + ".dmp"; ProcessState processState; ProcessResult processResult = minidumpProcessor.Process(minidumpFile, &processState); if (processResult == google_breakpad::PROCESS_ERROR_MINIDUMP_NOT_FOUND) { queue.del(job); continue; } if (processResult != google_breakpad::PROCESS_OK) { BPLOG(ERROR) << "MinidumpProcessor::Process failed"; queue.bury(job); continue; } //////////////////////////////////////////////////////////////////////// #if 0 // If there is no requesting thread, print the main thread. int requestingThread = processState.requesting_thread(); if (requestingThread == -1) { requestingThread = 0; } const CallStack *stack = processState.threads()->at(requestingThread); if (!stack) { BPLOG(ERROR) << "Missing stack for thread " << requestingThread; queue.bury(job); continue; } int frameCount = stack->frames()->size(); for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { const StackFrame *frame = stack->frames()->at(frameIndex); std::cout << frameIndex << ": "; std::cout << std::hex; if (frame->module) { std::cout << PathnameStripper::File(frame->module->code_file()); if (!frame->function_name.empty()) { std::cout << "!" << frame->function_name; if (!frame->source_file_name.empty()) { std::cout << " [" << PathnameStripper::File(frame->source_file_name) << ":" << std::dec << frame->source_line << std::hex << " + 0x" << frame->ReturnAddress() - frame->source_line_base << "]"; } else { std::cout << " + 0x" << frame->ReturnAddress() - frame->function_base; } } else { std::cout << " + 0x" << frame->ReturnAddress() - frame->module->base_address(); } } else { std::cout << "0x" << frame->ReturnAddress(); } std::cout << std::dec; std::string repoUrl = resolver.LookupRepoUrl(frame); if (!repoUrl.empty()) { std::cout << " <" << repoUrl << ">"; } std::cout << std::endl; } #endif //////////////////////////////////////////////////////////////////////// //__asm__("int3"); auto end = std::chrono::steady_clock::now(); double elapsedSeconds = ((end - start).count()) * std::chrono::steady_clock::period::num / static_cast<double>(std::chrono::steady_clock::period::den); //std::cout << "Processing Time: " << elapsedSeconds << "s" << std::endl; json serialized = SerializeProcessState(&processState, &resolver); serialized["id"] = id; if (!body["ip"].is_null()) serialized["ip"] = body["ip"]; if (!body["owner"].is_null()) serialized["owner"] = body["owner"]; serialized["processing_time"] = elapsedSeconds; std::cout << serialized << std::endl; queue.del(job); bool processSingleJob = config["processSingleJob"]; if (processSingleJob) { break; } } return 0; }
// binder_call의 래퍼를 제공합니다. 안드로이드에서는 transact 함수를 사용합니다. int transact(int handle, int code, int* msg, int* reply) { return binder_call(mProcess->get_driver(), msg, reply, handle, code); }
void SigHandlerStepperImpl::registerStepperGroup(StepperGroup *group) { sw_printf("[%s:%u] - Begin SigHandlerStepperImpl::registerStepperGroup\n", FILE__, __LINE__); ProcessState *ps = getProcessState(); assert(ps); LibraryState *libs = getProcessState()->getLibraryTracker(); if (!libs) { sw_printf("[%s:%u] - Custom library tracker. Don't know how to" " to get libc\n", FILE__, __LINE__); return; } SymbolReaderFactory *fact = Walker::getSymbolReader(); if (!fact) { sw_printf("[%s:%u] - Failed to get symbol reader\n", FILE__, __LINE__); return; } sw_printf("[%s:%u] - Got lib tracker and sym reader OK, checking for __restore_rt...\n", FILE__, __LINE__); if (!init_libc) { /** * Get __restore_rt out of libc **/ sw_printf("[%s:%u] - Getting __restore_rt from libc\n", FILE__, __LINE__); LibAddrPair libc_addr; Dyninst::SymReader *libc = NULL; Symbol_t libc_restore; bool result = libs->getLibc(libc_addr); if (!result) { sw_printf("[%s:%u] - Unable to find libc, not registering restore_rt" "tracker.\n", FILE__, __LINE__); } if (!init_libc) { if (result) { init_libc = true; libc = fact->openSymbolReader(libc_addr.first); if (!libc) { sw_printf("[%s:%u] - Unable to open libc, not registering restore_rt\n", FILE__, __LINE__); } } if (result && libc) { init_libc = true; libc_restore = libc->getSymbolByName("__restore_rt"); if (!libc->isValidSymbol(libc_restore)) { sw_printf("[%s:%u] - Unable to find restore_rt in libc\n", FILE__, __LINE__); } else { Dyninst::Address start = libc->getSymbolOffset(libc_restore) + libc_addr.second; Dyninst::Address end = libc->getSymbolSize(libc_restore) + start; if (start == end) end = start + 16; //Estimate--annoying sw_printf("[%s:%u] - Registering libc restore_rt as at %lx to %lx\n", FILE__, __LINE__, start, end); group->addStepper(parent_stepper, start, end); } } } } if (!init_libthread) { /** * Get __restore_rt out of libpthread **/ sw_printf("[%s:%u] - Getting __restore_rt out of libpthread\n", FILE__, __LINE__); LibAddrPair libpthread_addr; Dyninst::SymReader *libpthread = NULL; Symbol_t libpthread_restore; bool result = libs->getLibthread(libpthread_addr); if (!result) { sw_printf("[%s:%u] - Unable to find libpthread, not registering restore_rt" "pthread tracker.\n", FILE__, __LINE__); } if (result) { libpthread = fact->openSymbolReader(libpthread_addr.first); if (!libpthread) { sw_printf("[%s:%u] - Unable to open libc, not registering restore_rt\n", FILE__, __LINE__); } init_libthread = true; } if (libpthread) { libpthread_restore = libpthread->getSymbolByName("__restore_rt"); if (!libpthread->isValidSymbol(libpthread_restore)) { sw_printf("[%s:%u] - Unable to find restore_rt in libpthread\n", FILE__, __LINE__); } else { Dyninst::Address start = libpthread->getSymbolOffset(libpthread_restore) + libpthread_addr.second; Dyninst::Address end = libpthread->getSymbolSize(libpthread_restore) + start; if (start == end) end = start + 16; //Estimate--annoying sw_printf("[%s:%u] - Registering libpthread restore_rt as at %lx to %lx\n", FILE__, __LINE__, start, end); group->addStepper(parent_stepper, start, end); } } } /** * Get symbols out of vsyscall page **/ sw_printf("[%s:%u] - Getting vsyscall page symbols\n", FILE__, __LINE__); vsys_info *vsyscall = getVsysInfo(ps); if (!vsyscall) { #if !defined(arch_x86_64) sw_printf("[%s:%u] - Odd. Couldn't find vsyscall page. Signal handler" " stepping may not work\n", FILE__, __LINE__); #endif } else { SymReader *vsys_syms = vsyscall->syms; if (!vsys_syms) { sw_printf("[%s:%u] - Vsyscall page wasn't parsed\n", FILE__, __LINE__); } else { for (unsigned i=0; i<NUM_VSYS_SIGRETURNS; i++) { Symbol_t sym; sym = vsys_syms->getSymbolByName(vsys_sigreturns[i]); if (!vsys_syms->isValidSymbol(sym)) continue; Dyninst::Offset offset = vsys_syms->getSymbolOffset(sym); Dyninst::Address addr; if (offset < vsyscall->start) addr = offset + vsyscall->start; else addr = offset; unsigned long size = vsys_syms->getSymbolSize(sym); if (!size) size = ps->getAddressWidth(); group->addStepper(parent_stepper, addr, addr + size); } } } }
void BottomOfStackStepperImpl::initialize() { ProcessState *proc = walker->getProcessState(); assert(proc); sw_printf("[%s:%u] - Initializing BottomOfStackStepper\n", FILE__, __LINE__); LibraryState *libs = proc->getLibraryTracker(); if (!libs) { sw_printf("[%s:%u] - Error initing StackBottom. No library state for process.\n", FILE__, __LINE__); return; } SymbolReaderFactory *fact = Walker::getSymbolReader(); if (!fact) { sw_printf("[%s:%u] - Failed to get symbol reader\n"); return; } if (!aout_init) { LibAddrPair aout_addr; SymReader *aout = NULL; Symbol_t start_sym; bool result = libs->getAOut(aout_addr); if (result) { aout = fact->openSymbolReader(aout_addr.first); aout_init = true; } if (aout) { start_sym = aout->getSymbolByName(START_FUNC_NAME); if (aout->isValidSymbol(start_sym)) { Dyninst::Address start = aout->getSymbolOffset(start_sym)+aout_addr.second; Dyninst::Address end = aout->getSymbolSize(start_sym) + start; if (start == end) { sw_printf("[%s:%u] - %s symbol has 0 length, using length of %lu\n", FILE__, __LINE__, START_FUNC_NAME, START_HEURISTIC_LENGTH); end = start + START_HEURISTIC_LENGTH; } sw_printf("[%s:%u] - Bottom stepper taking %lx to %lx for start\n", FILE__, __LINE__, start, end); ra_stack_tops.push_back(std::pair<Address, Address>(start, end)); } } } if (!libthread_init) { LibAddrPair libthread_addr; SymReader *libthread = NULL; Symbol_t clone_sym, startthread_sym; bool result = libs->getLibthread(libthread_addr); if (result) { libthread = fact->openSymbolReader(libthread_addr.first); libthread_init = true; } if (libthread) { clone_sym = libthread->getSymbolByName(CLONE_FUNC_NAME); if (libthread->isValidSymbol(clone_sym)) { Dyninst::Address start = libthread->getSymbolOffset(clone_sym) + libthread_addr.second; Dyninst::Address end = libthread->getSymbolSize(clone_sym) + start; sw_printf("[%s:%u] - Bottom stepper taking %lx to %lx for clone\n", FILE__, __LINE__, start, end); ra_stack_tops.push_back(std::pair<Address, Address>(start, end)); } startthread_sym = libthread->getSymbolByName(START_THREAD_FUNC_NAME); if (libthread->isValidSymbol(startthread_sym)) { Dyninst::Address start = libthread->getSymbolOffset(startthread_sym) + libthread_addr.second; Dyninst::Address end = libthread->getSymbolSize(startthread_sym) + start; sw_printf("[%s:%u] - Bottom stepper taking %lx to %lx for start_thread\n", FILE__, __LINE__, start, end); ra_stack_tops.push_back(std::pair<Address, Address>(start, end)); } } } }