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

📄 ecostest.cpp

📁 ecos为实时嵌入式操作系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // Do not spawn a thread while in possession of a mutex    ENTERCRITICAL;        Trace("csl=%d\n",CeCosTestUtils::m_nCriticalSectionLock);        assert(1==CeCosTestUtils::m_nCriticalSectionLock);    LEAVECRITICAL;    THREAD_ID hThread;    SetPath(m_strPath);    if(0==cb.m_pProc && 0==cb.m_pParam){        Trace("RunThread: - blocking call\n");        // No callback, so no need to create a thread:        (this->*pThreadFunc)(pParam);        hThread=(THREAD_ID)-1;    } else {        ThreadInfo *pInfo=new ThreadInfo; // SThreadFunc will delete        pInfo->pTest=this;        pInfo->pFunc=pThreadFunc;        pInfo->pParam=pParam; // Param to pass to pThreadFunc        pInfo->cb=cb;#ifdef _WIN32        DWORD dwID;        hThread=pInfo->hThread=CreateThread (0,0,SThreadFunc, pInfo, 0, &dwID);        Trace("RunThread: - non-blocking call (new thread=%x)\n",dwID);#else        VTRACE("RunThread():Calling pthread_create()\n");        int pc_rc, pd_rc;        pc_rc = pthread_create(&pInfo->hThread, NULL, SThreadFunc, pInfo);        Trace("RunThread: - non-blocking call (new thread=%x)\n",pInfo->hThread);        VTRACE("RunThread(): pthread_create() returned <%d>\n", pc_rc);        if (pc_rc != 0) {            VTRACE("RunThread(): pthread_create failed\n");            perror("RunThread(): pthread_create failed with : ");            hThread=pInfo->hThread=0;        } else {            VTRACE("RunThread(): Calling pthread_detach\n");            pd_rc = pthread_detach(pInfo->hThread);            VTRACE("RunThread(): pthread_detach returned <%d>\n", pd_rc);            if (pd_rc != 0) {                Trace("RunThread(): pthread_detach failed\n");                perror("RunThread(): pthread_detach failed with : ");                hThread=pInfo->hThread=0;            }        }        VTRACE("RunThread(): returned from pthread calls - exiting RunThread()\n");#endif    }    return hThread;}THREADFUNC CeCosTest::SThreadFunc (void *pParam){    VTRACE("SThreadFunc()\n");    ThreadInfo *pInfo=(ThreadInfo*)pParam;    #ifdef _WIN32    __try {        // Call what we are instructed to (e.g. LocalThreadFunc):        (pInfo->pTest->*pInfo->pFunc)(pInfo->pParam);    }    __except ( CeCosTestUtils::FilterFunction(GetExceptionInformation() ))     {         TRACE("Handling exception...\n");    }    #else    try {        // Call what we are instructed to (e.g. LocalThreadFunc):        (pInfo->pTest->*pInfo->pFunc)(pInfo->pParam);    }    catch (...){        TRACE("Exception caught!!!\n");    }    #endif    // Call the Callback:    VTRACE("SThreadFunc(): Calling InvokeCallback()\n");    pInfo->pTest->InvokeCallback(pInfo->cb);    // No more references to pInfo->pTest from now on...    VTRACE("SThreadFunc(): deleting (ThreadInfo)pInfo\n");    #ifdef _WIN32    CloseHandle(pInfo->hThread);    #endif    delete pInfo;     TRACE("Thread exiting\n");    return 0;}// Call the given Callback function with the given argument:void CeCosTest::InvokeCallback(const CeCosTest::Callback &cb){    if(cb.m_pProc){        cb.m_pProc (this, cb.m_pParam);    } else if (cb.m_pParam) {        // No function - just a flag:        *(char *)cb.m_pParam=1;    }}// This function may be run as a thread (win32) or called (unix)void CeCosTest::DriveGdb(void *pParam){    const CeCosTestUtils::String *arstrCmd=(const CeCosTestUtils::String *)pParam;    int nCmdIndex=0;    SetStatus(NotStarted);    m_nMaxInactiveTime=0;    m_nTotalTime=0;    m_nDownloadTime=0;    m_bDownloading=!Sim();    m_tBase=GdbTime();    m_tBase0=GdbTime();    m_tWallClock0=CeCosTestUtils::Time::Now();        TRACE("DriveGdb()\n");    bool bBlockingReads;    int nLastGdbInst=0;    #ifdef _WIN32    bBlockingReads=true;    #else     bBlockingReads=false;    #endif    // Loop until 1 of:    //      1. Timeout detected    //      2. Gdb process is dead    //      3. At a gdb prompt and no more commands to send to gdb    //      4. Pipe read failure    //      5. Pipe write failure    do {        CeCosTestUtils::String str;        int readrc=ReadPipe(m_rPipeHandle,str,bBlockingReads);        #ifdef _WIN32        VTRACE("Blocking read returned %d\n",readrc);        #endif        switch(readrc){            case 0:                CeCosTestUtils::Sleep(250); // only unix will execute this                break;            case -1:                goto Done; // case 4                break;            default:                LogTimeStampedOutput(str);                                if(m_strOutput.GetLength()>20000){                    LogString("\n>>>> Infra FAIL\n*** too much output ***\n>>>>\n");                    SetStatus(Fail);                    goto Done;                }                                if(strstr(m_strOutput,Sim()?"Starting program: ":"Continuing.")){                    SetStatus(NoResult);                }                                m_tBase=GdbTime();                if(!BreakpointsOperational() && strstr(m_strOutput,"EXIT:")){                    goto Done;                }                                if(AtGdbPrompt()){                    m_tBase=GdbTime();                    VTRACE("DriveGdb(): Got gdb prompt\n");                    // gdb's output included one or more prompts                    // Send another command along                    if(0==arstrCmd[nCmdIndex].GetLength()){                        // Nothing further to say to gdb - exit                        VTRACE("DriveGdb():No more commands to send gdb - exit\n");                        goto Done; // case 3                    } else {                        CeCosTestUtils::String strCmd(arstrCmd[nCmdIndex++]);                                                // If at a prompt and we can see a GDB instruction, send it down                        const char *pszGdbcmd=strstr(nLastGdbInst+(const char *)m_strOutput,"GDB:");                        if(pszGdbcmd){                            pszGdbcmd+=4;                            char cTerm;                            if('<'==*pszGdbcmd){                                cTerm='>';                                pszGdbcmd++;                            } else {                                cTerm='\n';                            }                            const char *c=strchr(pszGdbcmd,cTerm);                            if(c){                                int nLen=c-pszGdbcmd;                                nLastGdbInst=c+1-(const char *)m_strOutput;                                char *buf=strCmd.GetBuffer(nLen);                                strncpy(buf,pszGdbcmd,nLen);                                buf[nLen]='\0';                                nCmdIndex--; // undo increment above                            }                        }                        strCmd+='\n';                        LogString(strCmd);                        if(!WritePipe(m_wPipeHandle,strCmd)){                            Trace("Writepipe returned error\n");                            goto Done; // case 5                        }                                                if(0==strcmp(strCmd,"run\n")||0==strcmp(strCmd,"cont\n")){                            m_tBase=GdbTime();                            m_bDownloading=false;                        }                    }                }                break;        }        if (Sim() && GdbTime()-m_tBase>PRIORITYLATCH){            VTRACE("DriveGdb(): Calling LowerGdbPriority()\n");            LowerGdbPriority();        }    } while (GdbProcessAlive() && CheckForTimeout()); // cases 2 and 1    Done:        Trace("DriveGdb() - done\n");    Suck();    if(GdbProcessAlive() && AtGdbPrompt()){        LogString("bt\n");		WritePipe(m_wPipeHandle,"bt\n");        Suck();    }    // Read anything gdb has to say [within limits]    Suck();    // order is important in case (for example to cater for cases     // in which FAIL follows PASS in output)    static const char *arpszKeepAlive[]={"FAIL:","NOTAPPLICABLE:", "PASS:"};     SetStatus(NoResult);    for(int i=0;i<sizeof arpszKeepAlive/sizeof arpszKeepAlive[0];i++){        const char *pszInfo=strstr(m_strOutput,arpszKeepAlive[i]);        if(0!=pszInfo){            Trace("DriveGdb: saw '%s'\n",arpszKeepAlive[i]);            // Reset the active timeout base if we see one of these:            switch(pszInfo[0]){                case 'F': // fail                    SetStatus(Fail);                    break;                case 'N': // notapplicable                    SetStatus(Inapplicable);                    break;                case 'P': // pass                    SetStatus(Pass);                    break;            }        }    }    // Certain output spells failure...    if(CeCosTest::Fail!=Status()){        if(OutputContains("cyg_assert_fail ("))            SetStatus(Fail);    } else {        static const char *arpszSignals[]={"SIGBUS", "SIGSEGV", "SIGILL", "SIGFPE", "SIGSYS", "SIGTRAP"};        for(int i=0;i<sizeof arpszSignals/sizeof arpszSignals[0];i++){            CeCosTestUtils::String str1,str2;            str1.Format("signal %s",arpszSignals[i]);            str2.Format("handle %s nostop",arpszSignals[i]);            if(OutputContains(str1)&&!OutputContains(str2)){                SetStatus(Fail);                break;            }        }    }    // Check for expect: strings    static const char szExpect[]="EXPECT:";    static const int  nExpectLen=sizeof szExpect-1;    for(const char*c=strstr(m_strOutput,szExpect);c;c=strstr(c,szExpect)){        c+=nExpectLen;        if('<'==*c){            c++;            const char *d=strchr(c,'>');            if(d){                unsigned int nLen=d-c;                do {                    d++;                } while (isspace(*d));                // Skip timestamp                if('<'==*d){                    d=strchr(d,'>');                    if(0==d){                        continue;                    }                    do {                        d++;                    } while (isspace(*d));                }                // Now d points to output of length nLen expected to compare equal to that at c                if(strlen(d)>=nLen && 0!=strncmp(c,d,nLen) && '\n'==d[nLen]) {                    LogString("EXPECT:<> failure\n");                    SetStatus(Fail);                }            }        }    }    m_nTotalTime=CeCosTestUtils::Time::Now()-m_tWallClock0;    Trace("Exiting DriveGdb()\n");}CeCosTestUtils::Time CeCosTest::GdbTime(){    return Sim()?GdbCpuTime():CeCosTestUtils::Time::Now();}bool CeCosTest::CheckForTimeout(){    bool rc=false;    if(TimeOut!=m_Status && DownloadTimeOut!=m_Status){        CeCosTestUtils::Duration &dTime=m_bDownloading?m_nDownloadTime:m_nMaxInactiveTime;        dTime=max(dTime,GdbTime()-m_tBase);        CeCosTestUtils::Duration dTimeout=m_bDownloading?ElapsedTimeout():ActiveTimeout();        if(dTimeout!=NOTIMEOUT && dTime>dTimeout) {            Log("\n*** Timeout - %s time " WFS " exceeds limit of " WFS "\n",                m_bDownloading?"download":"max inactive",WF(dTime),WF(dTimeout));            SetStatus(m_bDownloading?DownloadTimeOut:TimeOut);        } else if(CeCosTestUtils::Time::Now()-m_tWallClock0>max(3*dTimeout,15*60*1000)){            Log("\n*** Timeout - total time " WFS " exceeds limit of " WFS "\n",                WF(CeCosTestUtils::Time::Now()-m_tWallClock0),WF(max(3*dTimeout,15*60*1000)));            SetStatus(m_bDownloading?DownloadTimeOut:TimeOut);        } else {            rc=true;        }    }    return rc;}void CeCosTest::Trace(const char * pszFormat, ...){    if(CeCosTestUtils::IsTracingEnabled()){        va_list marker;        va_start (marker, pszFormat);        CeCosTestUtils::String str;        str.vFormat(pszFormat,marker);        va_end 

⌨️ 快捷键说明

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