📄 ecostest.cpp
字号:
//=================================================================//// eCosTest.cpp//// Test class////=================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License. You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the// License for the specific language governing rights and limitations under// the License.// // The Original Code is eCos - Embedded Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus. Portions created// by Cygnus are Copyright (C) 1998, 1999 Cygnus Solutions.// All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//=================================================================//#####DESCRIPTIONBEGIN####//// Author(s): sdf// Contributors: sdf// Date: 1999-04-01// Description: This class abstracts a test for use in the testing infrastructure.// This file contains windows-specific implementations// Usage:////####DESCRIPTIONEND#####include "stdafx.h"#include "eCosTest.h"#include "X10.h"#include "eCosTestUtils.h"int CeCosTest::ReadPipe (void *Handle,CeCosTestUtils::String &str,bool bBlock){ HANDLE hrData=(HANDLE)Handle; DWORD dwAvail; int rc=-1; if(PeekNamedPipe (hrData, NULL, 0, NULL, &dwAvail, NULL)){ if(0==dwAvail){ if(bBlock){ dwAvail=80; } else { return 0; } } DWORD dwRead; char *buf=str.GetBuffer(dwAvail); if(ReadFile (hrData, buf, dwAvail, &dwRead, NULL)){ buf[dwRead]='\0'; rc=dwRead; } str.ReleaseBuffer(); } return rc;}bool CeCosTest::WritePipe (void *Handle,const char *pszBuf){ HANDLE hwCmd=(HANDLE)Handle; int nToWrite=strlen(pszBuf); DWORD dwWritten; const char *c=pszBuf; do { if(!WriteFile(hwCmd,c,nToWrite,&dwWritten,0) || !CheckForTimeout()){ return false; } nToWrite-=(int)dwWritten; c+=(int)dwWritten; } while (nToWrite>0); return true;}void CeCosTest::RunGdb(const CeCosTestUtils::String &strExec, const CeCosTestUtils::String *arpszCmds){ SetPath(m_strPath); STARTUPINFO si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES sa; sa.nLength=sizeof sa; sa.lpSecurityDescriptor=NULL; sa.bInheritHandle=TRUE; HANDLE hrData=NULL; HANDLE hwCmd=NULL; memset(&si,0,sizeof si); si.cb=sizeof si; si.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; si.wShowWindow=SW_HIDE; CeCosTestUtils::String strCmdline; strCmdline.Format("%s -nw %s",(const char *)strExec,(const char *)CygPath(m_strExecutable)); TRACE("RunGdb '%s'\n",(const char *)strCmdline); bool rcCreate=false; if(CreatePipe (&si.hStdInput, &hwCmd, &sa, 80)){ if(CreatePipe (&hrData, &si.hStdOutput, &sa, 80)){ if(DuplicateHandle (GetCurrentProcess(), si.hStdOutput, GetCurrentProcess(), &si.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS)){ if(CreateProcess(NULL,strCmdline.GetBuffer(),NULL,NULL,TRUE,CREATE_NEW_PROCESS_GROUP|NORMAL_PRIORITY_CLASS,NULL,"\\",&si,&pi)){ TRACE("Create process '%s' pid=%d\n",(const char *)strCmdline,pi.dwProcessId); rcCreate=true; // Process is created - gather its output m_pGdbProcesshandle=(void *)(pi.hProcess); m_rPipeHandle=hrData; m_wPipeHandle=hwCmd; m_bDriveGdbComplete=false; // For some unknown reason, PeekNamedPipe returns 0 even when a read will succeed. Since overlapped // IO is not supported on anonymouse pipes, we are then reduced to using blocking reads under win32. // We must reset all the timing-related variables here, lest the thread doesn't get to do it before the // first call of CheckForTimeout() below. m_nMaxInactiveTime=0; m_nDownloadTime=0; m_tWallClock0=CeCosTestUtils::Time::Now(); m_tBase=GdbTime(); HANDLE hThread=RunThread(DriveGdb,(void *)arpszCmds,Callback(0,&m_bDriveGdbComplete)); while(!m_bDriveGdbComplete){ CeCosTestUtils::Sleep(250); if(!GdbProcessAlive()){ if(!CeCosTestUtils::WaitFor(m_bDriveGdbComplete,1*1000)){ LogString("*** gdb has died unexpectedly"); Trace("RunGdb - terminating thread\n"); TerminateThread(hThread,1); break; } } else if(!CheckForTimeout()){ LogTimeStampedOutput("^C\n"); BOOL rc=GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,pi.dwProcessId); Trace("RunGdb - GenerateConsoleCtrlEvent(1) rc=%d\n",rc); if(CeCosTestUtils::WaitFor(m_bDriveGdbComplete,10*1000)){ goto DriveGdbDone; } /* // Closing the handles is capable of hanging Trace("RunGdb - Closing handles\n"); CloseHandle(hrData); // Force any pending read to complete hrData=0; CloseHandle(hwCmd); // Force any pending write to complete hwCmd=0; Trace("Handles closed\n"); if(!CeCosTestUtils::WaitFor(m_bDriveGdbComplete,10*1000)){ goto DriveGdbDone; } */ if(GdbProcessAlive()){ Trace("RunGdb - terminating(1) process %d\n",pi.dwProcessId); BOOL rc=TerminateProcess((HANDLE)m_pGdbProcesshandle,1); Trace("rc=%d\n",rc); if(CeCosTestUtils::WaitFor(m_bDriveGdbComplete,10*1000)){ goto DriveGdbDone; } } Trace("RunGdb - terminating thread\n"); TerminateThread(hThread,1); break; } }DriveGdbDone: Trace("DriveGdbDone\n"); if(GdbProcessAlive()){ Trace("DriveGdbDone - s1\n"); Suck(); if(GdbProcessAlive()){ Trace("DriveGdbDone - s2\n"); if(!AtGdbPrompt()){ BOOL rc=GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,pi.dwProcessId); Trace("RunGdb - GenerateConsoleCtrlEvent(2) rc=%d\n",rc); Suck(); } if(hwCmd && AtGdbPrompt()){ LogString("q\n"); DWORD dwWritten; WriteFile(hwCmd,"q\n",2,&dwWritten,0); Trace("DriveGdbDone - s3\n"); Suck(); if(AtGdbPrompt()){ LogString("y\n"); WriteFile(hwCmd,"y\n",2,&dwWritten,0); Trace("DriveGdbDone - s4\n"); Suck(); } } if(GdbProcessAlive()){ Trace("RunGdb - terminating(2) process %d\n",pi.dwProcessId); TerminateProcess((HANDLE)m_pGdbProcesshandle,1); } } } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } CloseHandle(si.hStdError); } CloseHandle(si.hStdOutput); if(hrData){ CloseHandle(hrData); } } CloseHandle(si.hStdInput); if(hwCmd){ CloseHandle(hwCmd); } } if(!rcCreate){ // failed to create process Log("Failed to create gdb process: cmdline='%s'\n",(const char *)strCmdline); char *pszMsg; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&pszMsg, 0, NULL ); // Display the string. Log("%s\n",pszMsg); // Free the buffer. LocalFree(pszMsg); } }bool CeCosTest::GdbProcessAlive(){ DWORD dwExitRc; GetExitCodeProcess((HANDLE)m_pGdbProcesshandle,&dwExitRc); return STILL_ACTIVE==dwExitRc;}void CeCosTest::LowerGdbPriority(){ SetPriorityClass((HANDLE)m_pGdbProcesshandle,IDLE_PRIORITY_CLASS);}CeCosTestUtils::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 CeCosTestUtils::Time((int)((ftKernel+ftUser)/10000)); } else { return 0; }}void CeCosTest::GetPath(CeCosTestUtils::String &strPath){ int nSize=GetEnvironmentVariable("PATH", NULL, 0); if(nSize>0){ GetEnvironmentVariable("PATH", strPath.GetBuffer(nSize), nSize); strPath.ReleaseBuffer(); } else { strPath=""; }}void CeCosTest::SetPath(const CeCosTestUtils::String &strPath){ SetEnvironmentVariable("PATH", strPath);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -