/** * Inject faults in the system. * * @param changedBytes - number of bytes changed in within the address range * @param changedBits - number of bits changed (0 (auto)... 8) */ void FaultInjector::injectFaults(unsigned long changedBytes, uint8_t changedBits) { unsigned long addrStart, addrEnd; addrStart = getRandomUInt(0, memorySize - 1); addrEnd = getRandomUInt(addrStart, memorySize - 1); logger.log(" inicial %lu final %lu\t", addrStart, addrEnd); injectFaults(addrStart, addrEnd, changedBytes, changedBits); }
void FaultInjector::generateFaults() { // WeatherStation::getInstance()->getLogger()->log("Inserting faults"); DigitalOut led4(LED4); led4 = 1; logger.log(" memorySize %hu\t", memorySize); injectFaults(DEFAULT_CHANGED_BYTES, DEFAULT_CHANGED_BITS); wait(0.5); led4 = 0; }
// 开始进行故障注入, // startInjtection是最顶层的故障注入处理模块 // 它会调用injectFaults完成故障注入, // 而后者则通过读取故障注入表的每一项一次进行故障注入 // // startInject的处理流程吐下 // // 如果是对某个已经存在的进程(依据进程号)进行故障注入, // 则通过ptrace中断程序的运行, 然后用injectFault读取故障注入表进行故障注入 // // 如果是对某个可执行程序进行故障注入 // 则先fork启动子进程, 再ptrace中断子进程, 然后用injectFault读取故障注入表进行故障注入 int Injector::startInjection( void ) { int iRet; int data = 0; //inject fault into an existing proces /* 内核线程无法进行跟踪 * 内核线程没有用户空间虚拟地址(mm== NULL, avtive_mm是上一个用户进程的虚拟地址) * 因此对内核线程的故障注入需要其他手段 */ if( this->m_targetPid > 0 && this->m_exeArguments == NULL && is_kthread(this->m_targetPid)) { dcout <<endl <<"[" <<__FILE__ <<", "<<__LINE__ <<"]--KERNEL THREAD pid = " <<this->m_targetPid <<endl; iRet = injectFaults( this->m_targetPid ); if( iRet != RT_OK ) { writeResult( this->m_targetPid, KT_RUN, 0); //exit or term return RT_FAIL; } return RT_OK; } else if( this->m_targetPid > 0 && this->m_exeArguments == NULL ) // 用户进程需要跟踪用户的状态 { dcout <<endl <<"[" <<__FILE__ <<", "<<__LINE__ <<"]--USER PROCESS pid = " <<this->m_targetPid <<endl; //设置跟踪进程,等待子进程停止 //bool ptraceFlag = true; childProcess = -1; signalPid = this->m_targetPid; //用于给sigAlrm函数传递进程号 iRet = ptraceAttach( this->m_targetPid ); if( iRet == RT_FAIL ) { //#ifdef TEST_PTRACE // 某些系统内部的进程是无法被跟踪的, 返回信息如下 // ptraceAttach error : : Operation not permitted // [ ptrace.cpp, 27] : ptraceAttach error : (29:Illegal seek) // 因此我们这里判断, 无法跟踪的进程直接进行注入即可 // // 查看是否可悲跟踪的简单方法 strace -p pid if(errno == 29 || errno == 1) { //ptraceFlag = false; iRet = injectFaults( this->m_targetPid ); if( iRet != RT_OK ) { return RT_FAIL; } writeResult( this->m_targetPid, RUN, 0 ); //exit or term return RT_OK; } else //#endif { return RT_FAIL; } } do { iRet = procMonitor( this->m_targetPid, data ); if( iRet == RT_FAIL ) { return RT_FAIL; } }while( iRet == RUN ); // should be STOP if( iRet != STOP ) { //dbgcout <<"test.." <<endl; writeResult( this->m_targetPid, iRet, data ); //exit or term return RT_FAIL; } // 进行故障注入 iRet = injectFaults( this->m_targetPid ); if( iRet != RT_OK ) { dbgcout <<"inject error..." <<endl; return RT_FAIL; } // 继续执行 ptraceCont( this->m_targetPid ); // 跟踪继续执行后的子进程 iRet = waitingProcMonitor(this->m_targetPid, data); return iRet; } //inject fault into an excultable program else if( this->m_exeArguments != NULL && this->m_targetPid < 0 ) { dcout <<endl <<"["<<__FILE__ <<", "<<__LINE__ <<"]--exe = " <<*(this->m_exeArguments) <<", inject fault into an excultable program" <<endl; errno = 0; pid_t child = fork(); if( child < 0 ) { perror("fork"); return RT_FAIL; } else if( child == 0 ) /// child { dcout <<endl <<"["<<__FILE__ <<", "<<__LINE__ <<"]--child pid = " <<getpid( ) <<endl; #ifdef BUGS dcout <<endl <<"BUG002--[" <<__FILE__ <<", " <<__func__ <<", "<<__LINE__ <<"]--exe = " <<this->m_exeArguments[0] <<", address = " <<this->m_exeArguments <<endl; #endif startExe(); _exit( RT_EXIT ); } else /// parent { childProcess = child; dcout <<endl <<"["<<__FILE__ <<", "<<__LINE__ <<"]--exe = " <<*(this->m_exeArguments) <<", pid = " <<childProcess <<" inject fault into an excultable program" <<endl; //inject fault into physical memory address #ifdef BUGS // BUG_002 dcout <<endl <<"["<<__FILE__ <<", "<<__LINE__ <<"]--" <<"start inject child process pid = " <<child <<endl; //exit(0); #endif iRet = injectFaults(child); if( iRet == RT_FAIL ) { cleanup(); } iRet = waitingProcMonitor(child, data); return iRet; } } cerr << "injection target is wrong" << endl; return RT_FAIL; }