⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecostest.cpp

📁 eCos1.31版
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      nLength+=n;    } else if (n<0) {      break;    }  }  TRACE(_T("End suck\n"));//sdf  return nLength>0;}#endifvoid CeCosTest::LogTimeStampedOutput(LPCTSTR psz){  LogString(psz);  /*  String str(psz);  // Timestamp the output at each _TCHAR('\n')  int nLen=m_strOutput.GetLength();  TCHAR cPrev=(0==nLen?_TCHAR('\0'):((LPCTSTR )m_strOutput)[nLen-1]);      TCHAR *c=str.GetBuffer();    LPCTSTR d=c;    while(*c){    if(_TCHAR('\n')==cPrev){    TCHAR cSav=*c;    *c=_TCHAR('\0');    LogString(d);    Duration &dTime=m_bDownloading?m_nDownloadTime:m_nMaxInactiveTime;    dTime=MAX(dTime,GdbTime()-m_tBase);          String strTime;      strTime.Format(_T("<") WFS _T("/") WFS _T(">\t"),WF(GdbTime()-m_tBase0), WF(GdbTime()-m_tBase));      //strTime.Format(_T("<%03d.%d> "),t/1000,(t%1000)/100);      LogString(strTime);      *c=cSav;      d=c;      }      cPrev=*c;      c++;      }      LogString(d);      str.ReleaseBuffer();  */}#ifdef _WIN32BOOL WINAPI HandlerRoutine(                           DWORD dwCtrlType   //  control signal type                           ){  dwCtrlType; // eliminate compiler warning  return TRUE;}#endifbool CeCosTest::InteractiveGdb(const String &strHost,int nPort,TCHAR **argv){  bool rc=false;  if(strHost.GetLength()>0){    m_strExecutionHostPort=CeCosTestSocket::HostPort(strHost,nPort);    Log(_T("Waiting to connect to %s...\n"),(LPCTSTR )m_strExecutionHostPort);  } else {    Log(_T("Waiting to connect to a server...\n"));  }    ConnectForExecution();    Log(_T("Connected to %s - waiting for target reset\n"),(LPCTSTR )m_strExecutionHostPort);  String strHostPort,strOutput;  // We read:  //     target ready indicator  //     any output so far  //     (if target ready) host:port  if(GetTargetReady(strHostPort)){    Log(_T("Use %s\n"),(LPCTSTR)strHostPort);    const TargetInfo &t=Target(Target());    String strGdb(t.Prefix());    strGdb+=_T("-gdb");#ifdef _WIN32    SetConsoleCtrlHandler(HandlerRoutine,TRUE);    int n=_tspawnvp(_P_WAIT,strGdb,argv);    if(-1==n){      Log(_T("Failed to spawn %s\n"),(LPCTSTR)strGdb);    } else {      rc=(0==n);    }       SetConsoleCtrlHandler(HandlerRoutine,FALSE);#else // UNIX        int pid=fork();    switch(pid){    case -1:      _ftprintf(stderr,_T("fork failed\n"));      pid=0;      break;      case 0:      // Process is created (we're the child)      execvp(strGdb,argv);      Log(_T("Error invoking %s - %s\n"),(LPCTSTR)strGdb,strerror(errno));      exit(1);      break;    default:      // Process is created (we're the parent)      {        signal(SIGINT,SIG_IGN);        int stat;        waitpid(pid,&stat,0);        rc=(0==stat);        signal(SIGINT,SIG_DFL);      }      break;    }#endif    Log(_T("Gdb terminated\n"));    // Tell the server we're through    m_pSock->sendInteger(123,_T("Terminating ack"));  }    return rc;}void CALLBACK CeCosTest::ResetLogFunc(void *pParam, LPCTSTR psz) {  CeCosTest *pTest=(CeCosTest *)pParam;  TRACE(_T("Send Target Ready indicator=2\n"));  pTest->m_pSock->sendInteger(2,_T("target ready indicator"));  TRACE(_T("Send %s\n"),psz);  pTest->m_pSock->sendString(psz,_T("output so far"));}CResetAttributes::ResetResult CeCosTest::Reset(bool bSendStatus){  return m_pPort->Reset(bSendStatus?ResetLogFunc:0,this);}CeCosTest::ExecutionParameters::RequestType CeCosTest::ExecutionParameters::RequestTypeValue(LPCTSTR psz){  int r;  for(r=0;r<RequestTypeMax;r++){    if(0==_tcsicmp(psz,arRequestImage[r])){      break;    }  }  return (RequestType)r;}#ifdef _WIN32void CeCosTest::RunGdb(LPCTSTR pszCmdline,LPCTSTR pszPrompt,const StringArray &arstrGdbCmds){  SetPath(m_strPath);  CSubprocess sp;  unsigned int idProcess=sp.Run(GetCurrentThreadId(),pszCmdline);  if(!idProcess){    Log(_T("Failed to create gdb process: cmdline='%s'\n"),pszCmdline);    TCHAR *pszMsg;        FormatMessage(       FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,      NULL,      sp.GetExitCode(),      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language      (LPTSTR)&pszMsg,      0,      NULL       );        // Display the string.    Log(_T("%s\n"),pszMsg);        // Free the buffer.    LocalFree(pszMsg);  } else {    unsigned int nCmdIndex=0;      SetStatus(NotStarted);      m_nMaxInactiveTime=0;    m_nTotalTime=0;    m_nDownloadTime=0;      m_bDownloading=true;      m_tBase=GdbTime();    m_tBase0=GdbTime();    m_tWallClock0=Now();      TRACE(_T("RunGDb()\n"));      int nLastGdbInst=0;      while(Cancelled!=Status() && CheckForTimeout()){      MSG msg;      if(::PeekMessage(&msg,NULL,WM_SUBPROCESS,WM_SUBPROCESS+1,PM_NOREMOVE)){        switch(::GetMessage(&msg,NULL,WM_SUBPROCESS,WM_SUBPROCESS+1)){        case 0:  //WM_QUIT        case -1: // error          goto Done;        case 1:          if(WM_SUBPROCESS==msg.message && msg.wParam==idProcess){            if(msg.lParam){              LPTSTR pszMsg=(LPTSTR)msg.lParam;              LogTimeStampedOutput(pszMsg);                          if(m_strOutput.GetLength()>20000){                LogString(_T("\n>>>> Infra FAIL\n*** too much output ***\n>>>>\n"));                SetStatus(Fail);                goto Done;              }                          // Test for program loaded and started:              // (remember SetStatus cannot downgrade the status if already > NoResult)              if(OutputContains(_T("Starting program: /")) || (OutputContains(_T("Start address"))&&OutputContains(_T("Continuing.")))){                SetStatus(NoResult);              }                          m_tBase=GdbTime();              //              // If can only hit a single breakpoint don't expect cyg_test_exit to stop us:              //              if(!BreakpointsOperational() && (OutputContains(_T("EXIT:"))||OutputContains(_T("NOTAPPLICABLE:")))){              //                  goto Done;              //              }                          if(AtPrompt(pszPrompt)){                m_tBase=GdbTime();                TRACE(_T("RunGDb(1)\n"));                // gdb's output included one or more prompts                // Send another command along                if(nCmdIndex>=arstrGdbCmds.size()){                  // Nothing further to say to gdb - exit                  TRACE(_T("RunGDb(2)\n"));                  goto Done; // case 3                } else {                  String strCmd(arstrGdbCmds[nCmdIndex++]);                  TRACE(_T("RunGDb(2a) - strCmd='%s' nLastGdbInst=%d\n"),(LPCTSTR)strCmd,nLastGdbInst);                  // If at a prompt and we can see a GDB instruction, send it down                  LPCTSTR pszGdbcmd=_tcsstr(nLastGdbInst+(LPCTSTR)m_strOutput,_T("GDB:"));                  if(pszGdbcmd){                    TRACE(_T("RunGDb(2b)\n"));                    pszGdbcmd+=4;                    TCHAR cTerm;                    if(_TCHAR('<')==*pszGdbcmd){                      cTerm=_TCHAR('>');                      pszGdbcmd++;                    } else {                      cTerm=_TCHAR('\n');                    }                    TRACE(_T("RunGDb(2c)\n"));                    LPCTSTR c=_tcschr(pszGdbcmd,cTerm);                    if(c){                      TRACE(_T("RunGDb(2d)\n"));                      strCmd=String(pszGdbcmd,c-pszGdbcmd);                      nLastGdbInst=c+1-(LPCTSTR )m_strOutput;                      nCmdIndex--; // undo increment above                    }                  }                  strCmd+=_TCHAR('\n');                  LogString(strCmd);                  TRACE(_T("RunGDb(3)\n"));                  sp.Send(strCmd);                            TRACE(_T("RunGDb(4)\n"));                  if(0==_tcscmp(strCmd,_T("run\n"))||0==_tcscmp(strCmd,_T("cont\n"))){                    m_tBase=GdbTime();                    m_bDownloading=false;                  }                  TRACE(_T("RunGDb(5)\n"));                }              }              delete [] pszMsg;            } else {              goto Done;            }          }          break;        }      } else { // no message        Sleep (500l); // sleep 500ms before the next peek      }    }    Done:      // Could use CygKill here    sp.Kill();    TRACE(_T("RunGDb - Done\n"));    AnalyzeOutput();        m_nTotalTime=Duration(Now()-m_tWallClock0);  }  TRACE(_T("Exiting RunGdb()\n"));}bool CeCosTest::GdbProcessAlive(){  DWORD dwExitRc;  GetExitCodeProcess((HANDLE)m_pGdbProcesshandle,&dwExitRc);  return STILL_ACTIVE==dwExitRc;}Time CeCosTest::GdbCpuTime(){  HANDLE hProcess=(HANDLE)m_pGdbProcesshandle;  __int64 ftCreation,ftExit,ftKernel,ftUser;  if(NULL!=hProcess && GetProcessTimes (hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){    return Time((int)((ftKernel+ftUser)/10000));  } else {    return 0;  }}void CeCosTest::GetPath(String &strPath){  int nSize=GetEnvironmentVariable(_T("PATH"), NULL, 0);  if(nSize>0){    GetEnvironmentVariable(_T("PATH"), strPath.GetBuffer(nSize), nSize);    strPath.ReleaseBuffer();  } else {    strPath=_T("");  }}void CeCosTest::SetPath(const String &strPath){  SetEnvironmentVariable(_T("PATH"), strPath);}#else // UNIXvoid CeCosTest::RunGdb(LPCTSTR pszCmdline,LPCTSTR pszPrompt,const StringArray &arstrGdbCmds){  int pipe_ends_w[2];  if (pipe(pipe_ends_w) < 0 ) {     Log(_T("Failed to create pipe_ends_w - %s\n"),strerror(errno));  } else {    int pipe_ends_r[2];    if (pipe(pipe_ends_r) < 0 ) {       Log(_T("Failed to create pipe_ends_r - %s\n"),strerror(errno));    } else {      int new_pid;					  ENTERCRITICAL;      // Ensure no one else has the lock such that the child might block in future      new_pid = fork();      // This leave is executed in *both* the child and parent      LEAVECRITICAL;            switch (new_pid) {        // Fork failed      case -1:        Log(_T("Failed to create gdb process - %s\n"),strerror(errno));        break;      case 0:        // Process is created (we're the child)        // No point in calling Log in this process                // Input to child process        if (dup2(pipe_ends_w[0], 0) < 0) {          TRACE(_T("dup2 error\n"));          exit(1);        }                // Output from process        if (dup2(pipe_ends_r[1], 2) < 0) {          TRACE(_T("dup2 error\n"));          exit(2);        }        if (dup2(pipe_ends_r[1], 1) < 0) {          TRACE(_T("dup2 error\n"));          exit(3);        }        setvbuf(stdout,0,_IONBF,0);        setvbuf(stderr,0,_IONBF,0);        {          StringArray ar;          int argc=String(pszCmdline).Chop(ar,_TCHAR(' '),true);          char **argv=new char *[1+argc];          int i;          for(i=0;i<argc;i++){            argv[i]=ar[i];            }          argv[i]=0;          execvp(argv[0], argv);          delete [] argv;        }        TRACE(_T("exec error - %s\n"),strerror(errno));        exit(4);      default:        // Process is created (we're the parent)                TRACE(_T("Forked to create gdb process %s - pid is <%d>\n"), pszCmdline, new_pid);        if (fcntl(pipe_ends_r[0], F_SETFL, O_NONBLOCK) <0) {          Log(_T("Couldn't set pipe non-blocking - %s\n"),strerror(errno));        } else {          m_pGdbProcesshandle=(void *)new_pid;          VTRACE(_T("RunGdb():Calling DriveGdb\n"));          m_rPipeHandle=(void *)pipe_ends_r[0];          m_wPipeHandle=(void *)pipe_ends_w[1];          DriveGdb (pszPrompt,arstrGdbCmds);          // Finished one way or another. Kill gdb now          TRACE(_T("Finished processing this test.\n"));          if(GdbProcessAlive()){            TRACE(_T("Killing gdb\n"));            // We need to kill gdb *and* its children            FILE *f=popen(_T("ps -l"),_T("r"));            if(f){              TCHAR buf[100];              while(_fgetts(buf,sizeof(buf)-1,f)){                int F,UID,PID,PPID,C,PRI,NI,SZ,HH,MM,SS;                TCHAR discard[100];                // Output is in the form              

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -