📄 ecostest.cpp
字号:
#include <pthread.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/socket.h>#include <unistd.h>#include <string.h>#include <signal.h>#include <sys/wait.h>#include <stdarg.h>#include <time.h>#include <sys/time.h>#include <unistd.h>#include <sys/resource.h> #include <ctype.h>#include "../eCosTest.h"#include "../eCosTestUtils.h"void CeCosTest::RunGdb(const CeCosTestUtils::String &strExec, const CeCosTestUtils::String *arstrCmds){ const char *pszExecutable=(const char *)m_strExecutable; int pipe_ends_w[2]; if (pipe(pipe_ends_w) < 0 ) { Log("Failed to create pipe_ends_w - %s\n",strerror(errno)); } else { int pipe_ends_r[2]; if (pipe(pipe_ends_r) < 0 ) { Log("Failed to create pipe_ends_r - %s\n",strerror(errno)); } else { ENTERCRITICAL; // Ensure no one else has the lock such that the child might block in future int new_pid = fork(); // This leave is executed in *both* the child and parent LEAVECRITICAL; switch (new_pid) { // Fork failed case -1: Log("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("dup2 error\n"); exit(1); } // Output from process if (dup2(pipe_ends_r[1], 2) < 0) { TRACE("dup2 error\n"); exit(2); } if (dup2(pipe_ends_r[1], 1) < 0) { TRACE("dup2 error\n"); exit(3); } setvbuf(stdout,0,_IONBF,0); setvbuf(stderr,0,_IONBF,0); execlp(strExec, (const char *)strExec, "-nw", pszExecutable, NULL); TRACE("exec error - %s\n",strerror(errno)); exit(4); default: // Process is created (we're the parent) TRACE("Forked to create gdb process '%s %s %s' - pid is <%d>\n", (const char *)strExec, "-nw", pszExecutable, new_pid); if (fcntl(pipe_ends_r[0], F_SETFL, O_NONBLOCK) <0) { Log("Couldn't set pipe non-blocking - %s\n",strerror(errno)); } else { m_pGdbProcesshandle=(void *)new_pid; VTRACE("RunGdb():Calling DriveGdb\n"); m_rPipeHandle=(void *)pipe_ends_r[0]; m_wPipeHandle=(void *)pipe_ends_w[1]; DriveGdb ((void *)arstrCmds); // Finished one way or another. Kill gdb now Trace("Finished processing this test. Killing gdb\n"); if ( kill(new_pid, SIGTERM) == 0 ) { Trace("waitpid <%d>", new_pid); int i; for(i=0;i<10;i++){ int status; switch(waitpid(new_pid,&status,WNOHANG)){ case 0: CeCosTestUtils::Sleep(1000); continue; case -1: Log("Failed to wait for gdb process to die\n"); SetStatus(TimeOut); break; default: break; } break; } if(10==i){ Log("Failed to wait for gdb process to die\n"); SetStatus(TimeOut); } close(new_pid); } else { Log("Failed to kill gdb process %d\n",new_pid); } Trace("Total elapsed time is %d\n", m_nTotalTime); Trace("Killed\n"); } break; } VTRACE("Closing pipe_ends_r[]\n"); close (pipe_ends_r[0]); close (pipe_ends_r[1]); } close (pipe_ends_w[0]); close (pipe_ends_w[1]); }}bool CeCosTest::GdbProcessAlive(){ int status; return 0==waitpid((int)m_pGdbProcesshandle,&status,WNOHANG);}void CeCosTest::LowerGdbPriority(){ ;}CeCosTestUtils::Time CeCosTest::GdbCpuTime(){ if(GdbProcessAlive()){ CeCosTestUtils::Time now=CeCosTestUtils::Time::Now(); if(now-m_tPrevSample>1000){ m_tPrevSample=now; CeCosTestUtils::String strCmd; strCmd.Format("ps Sh %u",m_pGdbProcesshandle); FILE *f=popen(strCmd,"r"); if(f){ char buf[100]; fgets(buf,sizeof(buf)-1,f); pclose(f); // Output is something like "19617 p1 S 1:23 ..." const char *pcSecs=strchr(buf,':'); if(pcSecs){ const char *pcMins=pcSecs++; do { --pcMins; } while(pcMins>=buf&&isdigit(*pcMins)); pcMins++; int t=atoi(pcMins)*60+atoi(pcSecs); VTRACE("ps Sh %d=='%s' -> cpu=%d\n",m_pGdbProcesshandle,buf,t); m_tGdbCpuTime=CeCosTestUtils::Time(1000*t); } } } } else { m_tGdbCpuTime=0; } return m_tGdbCpuTime;}bool CeCosTest::WritePipe (void *Handle,const char *pszBuf){ int write_fd = (int)Handle; int dwWritten; int nToWrite=strlen(pszBuf); do { dwWritten = write(write_fd, pszBuf, nToWrite); if(-1==dwWritten){ Log("pipe write error - %s\n",strerror(errno)); SetStatus(NoResult); break; } nToWrite-=(int)dwWritten; pszBuf+=(int)dwWritten; CeCosTestUtils::Duration dTimeout=m_bDownloading?ElapsedTimeout():ActiveTimeout(); if(!CheckForTimeout()){ return false; } if (Sim() && GdbCpuTime()-m_tBase>PRIORITYLATCH){ LowerGdbPriority(); } } while (nToWrite>0); return true;}int CeCosTest::ReadPipe (void *Handle,CeCosTestUtils::String &str,bool bBlocking /* This param ignored */){ const int bufsize=4096; char *buf=str.GetBuffer(bufsize); int rc = read((int)Handle, buf, bufsize-1); if(-1==rc && EAGAIN==errno){ rc=0; } buf[max(0,rc)]='\0'; return rc;}void CeCosTest::GetPath(CeCosTestUtils::String &strPath){ strPath=getenv("PATH");}void CeCosTest::SetPath(const CeCosTestUtils::String &strPath){ CeCosTestUtils::String str; str.Format("PATH=%s",(const char *)strPath); putenv(str);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -