/** * Attaches to the target process. * * @param tids The thread IDs of the threads that belong to the target process. * * @return A NaviError code that describes whether the operation was successful or not. */ NaviError LinuxSystem::attachToProcess() { msglog->log(LOG_VERBOSE, "Trying to attach to process %d", getPID()); int result = ptrace(PTRACE_ATTACH, getPID(), 0, 0); if (result) { msglog->log(LOG_ALWAYS, "Error: Couldn't attach to process"); return errno; } // TODO: Right now multi-threading is not supported Thread ts(getPID(), SUSPENDED); tids.push_back(ts); setActiveThread (getPID()); std ::string path; NaviError pathError = getExecutablePath(getPID(), path); if (pathError) { msglog->log( LOG_ALWAYS, "Error: Unable to determine the executable path of the debuggee."); return pathError; } // Generate processStart message and send it to BinNavi. fillModules(getPID(), this->modules); std::map<std::string, Module>::const_iterator cit = this->modules.find(path); if (cit != this->modules.end()) { Module processModule = cit->second; processStart(processModule, ts); } else { msglog->log(LOG_ALWAYS, "Error: Unable to determine main process module for '%s'", path.c_str()); exit(0); } return NaviErrors::SUCCESS; }
/** * Attaches to the target process. * * @param tids The thread IDs of the threads that belong to the target process. * * @return A NaviError code that describes whether the operation was successful * or not. */ NaviError GdbSystem::attachToProcess() { std::vector < Thread > tids; NaviError attachResult = cpu->attach(tids, this); if (attachResult) { msglog->log(LOG_VERBOSE, "Error: Couldn't attach to GDB server (Code: %d)", attachResult); } else { unsigned int activeThread; cpu->getActiveThread(activeThread, this); setActiveThread(activeThread); // The module constructor parameters are an optimistic over-approximation // since // Gdb can not provide us with better info about the executable image. processStart(Module("", "", 0, 0xFFFFFFFF), Thread(activeThread, SUSPENDED)); } return attachResult; }
bool CCrossSectionTask::process(const bool & useInitialValues) { processStart(useInitialValues); //this instructs the process queue to call back whenever an event is //executed mpCrossSectionProblem->getModel()->getMathModel()->getProcessQueue().setEventCallBack(this, &EventCallBack); mPreviousCrossingTime = std::numeric_limits< C_FLOAT64 >::quiet_NaN(); mPeriod = std::numeric_limits< C_FLOAT64 >::quiet_NaN(); mAveragePeriod = std::numeric_limits< C_FLOAT64 >::quiet_NaN(); mLastPeriod = std::numeric_limits< C_FLOAT64 >::quiet_NaN(); mPeriodicity = -1; mLastFreq = std::numeric_limits< C_FLOAT64 >::quiet_NaN(); mFreq = std::numeric_limits< C_FLOAT64 >::quiet_NaN(); mAverageFreq = std::numeric_limits< C_FLOAT64 >::quiet_NaN(); C_FLOAT64 MaxDuration = mpCrossSectionProblem->getDuration(); //the output starts only after "outputStartTime" has passed if (mpCrossSectionProblem->getFlagLimitOutTime()) { mOutputStartTime = *mpCurrentTime + mpCrossSectionProblem->getOutputStartTime(); MaxDuration += mpCrossSectionProblem->getOutputStartTime(); } else { mOutputStartTime = *mpCurrentTime; } const C_FLOAT64 EndTime = *mpCurrentTime + MaxDuration; mStartTime = *mpCurrentTime; // It suffices to reach the end time within machine precision C_FLOAT64 CompareEndTime = mOutputStartTime - 100.0 * (fabs(EndTime) * std::numeric_limits< C_FLOAT64 >::epsilon() + std::numeric_limits< C_FLOAT64 >::min()); if (mpCrossSectionProblem->getFlagLimitCrossings()) mMaxNumCrossings = mpCrossSectionProblem->getCrossingsLimit(); else mMaxNumCrossings = 0; if (mpCrossSectionProblem->getFlagLimitOutCrossings()) mOutputStartNumCrossings = mpCrossSectionProblem->getOutCrossingsLimit(); else mOutputStartNumCrossings = 0; output(COutputInterface::BEFORE); bool flagProceed = true; mProgressFactor = 100.0 / (MaxDuration + mpCrossSectionProblem->getOutputStartTime()); mProgressValue = 0; if (mpCallBack != NULL) { mpCallBack->setName("performing simulation..."); mProgressMax = 100.0; mhProgress = mpCallBack->addItem("Completion", mProgressValue, &mProgressMax); } mState = TRANSIENT; mStatesRingCounter = 0; mNumCrossings = 0; try { do { flagProceed &= processStep(EndTime); } while ((*mpCurrentTime < CompareEndTime) && flagProceed); } catch (int) { mpCrossSectionProblem->getModel()->setState(*mpCurrentState); mpCrossSectionProblem->getModel()->updateSimulatedValues(mUpdateMoieties); finish(); CCopasiMessage(CCopasiMessage::EXCEPTION, MCTrajectoryMethod + 16); } catch (CCopasiException & Exception) { mpCrossSectionProblem->getModel()->setState(*mpCurrentState); mpCrossSectionProblem->getModel()->updateSimulatedValues(mUpdateMoieties); finish(); throw CCopasiException(Exception.getMessage()); } finish(); return true; }
/** * Starts a new process for debugging. * * @param path The path to the executable of the process. * @param tids The thread IDs of the threads that belong to the target process. * * @return A NaviError code that describes whether the operation was successful or not. */ NaviError LinuxSystem::startProcess( const NATIVE_STRING path, const std::vector<const NATIVE_STRING>& commands) { pid_t pid = fork(); if (pid == -1) { msglog->log(LOG_ALWAYS, "Error: Couldn't fork process"); return NaviErrors::COULDNT_OPEN_TARGET_PROCESS; } else if (pid == 0) { ptrace(PTRACE_TRACEME, 0, 0, 0); char** child_arguments = new char*[1 + commands.size() + 1]; child_arguments[0] = new char[strlen(path) + 1]; strcpy(child_arguments[0], path); for (unsigned int i = 0; i < commands.size(); i++) { child_arguments[i + 1] = new char[strlen(commands[i]) + 1]; strcpy(child_arguments[i + 1], commands[i]); } child_arguments[1 + commands.size()] = 0; // Child process if (execvp(path, child_arguments) == -1) { msglog->log(LOG_ALWAYS, "Error: Could not start the child process '%s'", path); exit(0); } return NaviErrors::SUCCESS; } else { int status; if (waitpid(pid, &status, __WALL) == -1) { msglog->log(LOG_ALWAYS, "Error: Wait for target process failed '%s'", path); exit(0); } if (WIFSTOPPED(status)) { if (WSTOPSIG(status) == SIGTRAP) { msglog->log(LOG_VERBOSE, "Initial STOP signal received"); } else { msglog->log(LOG_ALWAYS, "Error: Received unexpected STOP signal"); exit(0); } } else { msglog->log(LOG_ALWAYS, "Error: Did not receive initial STOP signal"); exit(0); } if (ptrace( PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEVFORKDONE) == -1) { msglog->log(LOG_ALWAYS, "Error: Could not set ptrace options"); exit(0); } msglog->log(LOG_VERBOSE, "PID of the child process is %d", pid); setPID(pid); Thread ts(pid, SUSPENDED); tids.push_back(ts); setActiveThread(pid); lastMapFileSize = getFileSize( "/proc/" + zylib::zycon::toString(pid) + "/maps"); fillModules(pid, modules); this->modules = modules; std::map<std::string, Module>::const_iterator cit = this->modules.find( getTargetApplicationPath().string()); if (cit != this->modules.end()) { Module processModule = cit->second; processStart(processModule, ts); } else { msglog->log(LOG_ALWAYS, "Error: Unable to determine main process module for '%s'", getTargetApplicationPath().string().c_str()); exit(0); } return NaviErrors::SUCCESS; } }
bool CTSSATask::process(const bool & useInitialValues) { //***** processStart(useInitialValues); //***** C_FLOAT64 StepSize = mpTSSAProblem->getStepSize(); C_FLOAT64 NextTimeToReport; const C_FLOAT64 EndTime = *mpCurrentTime + mpTSSAProblem->getDuration(); const C_FLOAT64 StartTime = *mpCurrentTime; C_FLOAT64 StepNumber = (mpTSSAProblem->getDuration()) / StepSize; bool (*LE)(const C_FLOAT64 &, const C_FLOAT64 &); bool (*L)(const C_FLOAT64 &, const C_FLOAT64 &); if (StepSize < 0.0) { LE = &tble; L = &tbl; } else { LE = &tfle; L = &tfl; } unsigned C_INT32 StepCounter = 1; C_FLOAT64 outputStartTime = mpTSSAProblem->getOutputStartTime(); if (StepSize == 0.0 && mpTSSAProblem->getDuration() != 0.0) { CCopasiMessage(CCopasiMessage::ERROR, MCTSSAProblem + 1, StepSize); return false; } output(COutputInterface::BEFORE); bool flagProceed = true; C_FLOAT64 handlerFactor = 100.0 / mpTSSAProblem->getDuration(); C_FLOAT64 Percentage = 0; unsigned C_INT32 hProcess; if (mpCallBack) { mpCallBack->setName("performing simulation..."); C_FLOAT64 hundred = 100; hProcess = mpCallBack->addItem("Completion", CCopasiParameter::DOUBLE, &Percentage, &hundred); } if ((*LE)(outputStartTime, *mpCurrentTime)) output(COutputInterface::DURING); try { do { // This is numerically more stable then adding // mpTSSAProblem->getStepSize(). NextTimeToReport = StartTime + (EndTime - StartTime) * StepCounter++ / StepNumber; flagProceed &= processStep(NextTimeToReport); if (mpCallBack) { Percentage = (*mpCurrentTime - StartTime) * handlerFactor; flagProceed &= mpCallBack->progressItem(hProcess); } if ((*LE)(outputStartTime, *mpCurrentTime)) { output(COutputInterface::DURING); } } while ((*L)(*mpCurrentTime, EndTime) && flagProceed); } catch (int) { mpTSSAProblem->getModel()->setState(*mpCurrentState); mpTSSAProblem->getModel()->updateSimulatedValues(true); if ((*LE)(outputStartTime, *mpCurrentTime)) { output(COutputInterface::DURING); } if (mpCallBack) mpCallBack->finishItem(hProcess); output(COutputInterface::AFTER); CCopasiMessage(CCopasiMessage::EXCEPTION, MCTSSAMethod + 4); } catch (CCopasiException Exception) { mpTSSAProblem->getModel()->setState(*mpCurrentState); mpTSSAProblem->getModel()->updateSimulatedValues(true); if ((*LE)(outputStartTime, *mpCurrentTime)) { output(COutputInterface::DURING); } if (mpCallBack) mpCallBack->finishItem(hProcess); output(COutputInterface::AFTER); throw CCopasiException(Exception.getMessage()); } if (mpCallBack) mpCallBack->finishItem(hProcess); output(COutputInterface::AFTER); return true; }
bool CTrajectoryTask::process(const bool & useInitialValues) { //***** processStart(useInitialValues); //***** //size_t FailCounter = 0; C_FLOAT64 Duration = mpTrajectoryProblem->getDuration(); C_FLOAT64 StepSize = mpTrajectoryProblem->getStepSize(); C_FLOAT64 StepNumber = fabs(Duration) / StepSize; if (isnan(StepNumber) || StepNumber < 1.0) StepNumber = 1.0; //the output starts only after "outputStartTime" has passed if (useInitialValues) mOutputStartTime = mpTrajectoryProblem->getOutputStartTime(); else mOutputStartTime = *mpCurrentTime + mpTrajectoryProblem->getOutputStartTime(); C_FLOAT64 NextTimeToReport; const C_FLOAT64 EndTime = *mpCurrentTime + Duration; const C_FLOAT64 StartTime = *mpCurrentTime; C_FLOAT64 CompareEndTime; if (StepSize < 0.0) { mpLessOrEqual = &ble; mpLess = &bl; // It suffices to reach the end time within machine precision CompareEndTime = EndTime + 100.0 * (fabs(EndTime) * std::numeric_limits< C_FLOAT64 >::epsilon() + std::numeric_limits< C_FLOAT64 >::min()); } else { mpLessOrEqual = &fle; mpLess = &fl; // It suffices to reach the end time within machine precision CompareEndTime = EndTime - 100.0 * (fabs(EndTime) * std::numeric_limits< C_FLOAT64 >::epsilon() + std::numeric_limits< C_FLOAT64 >::min()); } unsigned C_INT32 StepCounter = 1; if (StepSize == 0.0 && Duration != 0.0) { CCopasiMessage(CCopasiMessage::ERROR, MCTrajectoryProblem + 1, StepSize); return false; } output(COutputInterface::BEFORE); bool flagProceed = true; C_FLOAT64 handlerFactor = 100.0 / Duration; C_FLOAT64 Percentage = 0; size_t hProcess; if (mpCallBack != NULL && StepNumber > 1.0) { mpCallBack->setName("performing simulation..."); C_FLOAT64 hundred = 100; hProcess = mpCallBack->addItem("Completion", Percentage, &hundred); } if ((*mpLessOrEqual)(mOutputStartTime, *mpCurrentTime)) output(COutputInterface::DURING); try { do { // This is numerically more stable then adding // mpTrajectoryProblem->getStepSize(). NextTimeToReport = StartTime + (EndTime - StartTime) * StepCounter++ / StepNumber; flagProceed &= processStep(NextTimeToReport); if (mpCallBack != NULL && StepNumber > 1.0) { Percentage = (*mpCurrentTime - StartTime) * handlerFactor; flagProceed &= mpCallBack->progressItem(hProcess); } if ((*mpLessOrEqual)(mOutputStartTime, *mpCurrentTime)) { output(COutputInterface::DURING); } } while ((*mpLess)(*mpCurrentTime, CompareEndTime) && flagProceed); } catch (int) { mpTrajectoryProblem->getModel()->setState(*mpCurrentState); mpTrajectoryProblem->getModel()->updateSimulatedValues(mUpdateMoieties); if ((*mpLessOrEqual)(mOutputStartTime, *mpCurrentTime)) { output(COutputInterface::DURING); } if (mpCallBack != NULL && StepNumber > 1.0) mpCallBack->finishItem(hProcess); output(COutputInterface::AFTER); CCopasiMessage(CCopasiMessage::EXCEPTION, MCTrajectoryMethod + 16); } catch (CCopasiException & Exception) { mpTrajectoryProblem->getModel()->setState(*mpCurrentState); mpTrajectoryProblem->getModel()->updateSimulatedValues(mUpdateMoieties); if ((*mpLessOrEqual)(mOutputStartTime, *mpCurrentTime)) { output(COutputInterface::DURING); } if (mpCallBack != NULL && StepNumber > 1.0) mpCallBack->finishItem(hProcess); output(COutputInterface::AFTER); throw CCopasiException(Exception.getMessage()); } if (mpCallBack != NULL && StepNumber > 1.0) mpCallBack->finishItem(hProcess); output(COutputInterface::AFTER); return true; }