mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
- implemented ROSBOOT_CHECKPOINT
- implemented ROSBOOT_DELAY_READ - dump reached checkpoint in case of bsod / um-exceptions - add error handling - remove hardcoded constants svn path=/trunk/; revision=24602
This commit is contained in:
parent
98ae58da2b
commit
d966387fc7
3 changed files with 163 additions and 21 deletions
|
@ -53,9 +53,12 @@ namespace Sysreg_
|
||||||
string RosBootTest::DEBUG_FILE = _T("ROSBOOT_DEBUG_FILE");
|
string RosBootTest::DEBUG_FILE = _T("ROSBOOT_DEBUG_FILE");
|
||||||
string RosBootTest::TIME_OUT = _T("ROSBOOT_TIME_OUT");
|
string RosBootTest::TIME_OUT = _T("ROSBOOT_TIME_OUT");
|
||||||
string RosBootTest::PID_FILE= _T("ROSBOOT_PID_FILE");
|
string RosBootTest::PID_FILE= _T("ROSBOOT_PID_FILE");
|
||||||
|
string RosBootTest::DELAY_READ = _T("ROSBOOT_DELAY_READ");
|
||||||
|
string RosBootTest::CHECK_POINT = _T("ROSBOOT_CHECK_POINT");
|
||||||
|
string RosBootTest::SYSREG_CHECKPOINT = _T("SYSREG_CHECKPOINT:");
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
RosBootTest::RosBootTest() : RegressionTest(RosBootTest::CLASS_NAME), m_Timeout(60.0)
|
RosBootTest::RosBootTest() : RegressionTest(RosBootTest::CLASS_NAME), m_Timeout(60.0), m_Delayread(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -72,8 +75,13 @@ namespace Sysreg_
|
||||||
string boot_cmd;
|
string boot_cmd;
|
||||||
string debug_port;
|
string debug_port;
|
||||||
string timeout;
|
string timeout;
|
||||||
|
string delayread;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// read required configuration arguments
|
||||||
|
///
|
||||||
|
|
||||||
if (!conf_parser.getStringValue (RosBootTest::DEBUG_PORT, debug_port))
|
if (!conf_parser.getStringValue (RosBootTest::DEBUG_PORT, debug_port))
|
||||||
{
|
{
|
||||||
cerr << "Error: ROSBOOT_DEBUG_TYPE is not set in configuration file" << endl;
|
cerr << "Error: ROSBOOT_DEBUG_TYPE is not set in configuration file" << endl;
|
||||||
|
@ -96,6 +104,24 @@ namespace Sysreg_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conf_parser.getStringValue(RosBootTest::DELAY_READ, delayread))
|
||||||
|
{
|
||||||
|
TCHAR * stop;
|
||||||
|
m_Delayread = _tcstoul(delayread.c_str (), &stop, 10);
|
||||||
|
if (m_Delayread > 60 || m_Delayread < 0)
|
||||||
|
{
|
||||||
|
cerr << "Warning: disabling delay read" << endl;
|
||||||
|
m_Delayread = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// read optional arguments
|
||||||
|
///
|
||||||
|
|
||||||
|
conf_parser.getStringValue (RosBootTest::CHECK_POINT, m_Checkpoint);
|
||||||
conf_parser.getStringValue (RosBootTest::PID_FILE, m_PidFile);
|
conf_parser.getStringValue (RosBootTest::PID_FILE, m_PidFile);
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,12 +150,27 @@ namespace Sysreg_
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
bool RosBootTest::checkDebugData(vector<string> & debug_data)
|
void RosBootTest::dumpCheckpoints()
|
||||||
|
{
|
||||||
|
if (m_Checkpoints.size ())
|
||||||
|
{
|
||||||
|
cerr << "Dumping list of checkpoints: "<< endl;
|
||||||
|
while(!m_Checkpoints.empty ())
|
||||||
|
{
|
||||||
|
cerr << m_Checkpoints[0] << endl;
|
||||||
|
m_Checkpoints.erase (m_Checkpoints.begin ());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
RosBootTest::DebugState RosBootTest::checkDebugData(vector<string> & debug_data)
|
||||||
{
|
{
|
||||||
/// TBD the information needs to be written into an provided log object
|
/// TBD the information needs to be written into an provided log object
|
||||||
/// which writes the info into HTML/log / sends etc ....
|
/// which writes the info into HTML/log / sends etc ....
|
||||||
|
|
||||||
bool clear = true;
|
bool clear = true;
|
||||||
|
DebugState state = DebugStateContinue;
|
||||||
|
|
||||||
for(size_t i = 0; i < debug_data.size();i++)
|
for(size_t i = 0; i < debug_data.size();i++)
|
||||||
{
|
{
|
||||||
|
@ -137,25 +178,28 @@ namespace Sysreg_
|
||||||
|
|
||||||
cerr << line << endl;
|
cerr << line << endl;
|
||||||
|
|
||||||
if (line.find (_T("SYSREG_CHECKPOINT")) != string::npos)
|
if (line.find (RosBootTest::SYSREG_CHECKPOINT) != string::npos)
|
||||||
{
|
{
|
||||||
line.erase (0, line.find (_T("SYSREG_CHECKPOINT")) + 19);
|
line.erase (0, line.find (RosBootTest::SYSREG_CHECKPOINT) + RosBootTest::SYSREG_CHECKPOINT.length ());
|
||||||
if (!_tcsncmp(line.c_str (), _T("USETUP_COMPLETE"), 15))
|
if (!_tcsncmp(line.c_str (), m_Checkpoint.c_str (), m_Checkpoint.length ()))
|
||||||
{
|
{
|
||||||
///
|
state = DebugStateCPReached;
|
||||||
/// we need to stop the emulator to avoid
|
break;
|
||||||
/// looping again into USETUP (at least with bootcdregtest)
|
}
|
||||||
|
if (line.find (_T("|")) != string::npos)
|
||||||
return false;
|
{
|
||||||
|
string fline = debug_data[i];
|
||||||
|
m_Checkpoints.push_back (fline);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (line.find (_T("*** Fatal System Error")) != string::npos)
|
if (line.find (_T("*** Fatal System Error")) != string::npos)
|
||||||
{
|
{
|
||||||
cerr << "BSOD detected" <<endl;
|
cerr << "BSOD detected" <<endl;
|
||||||
return false;
|
dumpCheckpoints();
|
||||||
|
state = DebugStateBSODDetected;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (line.find (_T("Unhandled exception")) != string::npos)
|
else if (line.find (_T("Unhandled exception")) != string::npos)
|
||||||
{
|
{
|
||||||
|
@ -169,6 +213,7 @@ namespace Sysreg_
|
||||||
}
|
}
|
||||||
|
|
||||||
cerr << "UM detected" <<endl;
|
cerr << "UM detected" <<endl;
|
||||||
|
state = DebugStateUMEDetected;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// extract address from next line
|
/// extract address from next line
|
||||||
|
@ -176,15 +221,38 @@ namespace Sysreg_
|
||||||
|
|
||||||
string address = debug_data[i+2];
|
string address = debug_data[i+2];
|
||||||
string::size_type pos = address.find_last_of (_T(" "));
|
string::size_type pos = address.find_last_of (_T(" "));
|
||||||
|
if (pos == string::npos)
|
||||||
|
{
|
||||||
|
cerr << "Error: trace is not available (corrupted debug info" << endl;
|
||||||
|
dumpCheckpoints();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
address = address.substr (pos, address.length () - 1 - pos);
|
address = address.substr (pos, address.length () - 1 - pos);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// extract module name
|
/// extract module name
|
||||||
///
|
///
|
||||||
string modulename = debug_data[i+3];
|
string modulename = debug_data[i+3];
|
||||||
|
|
||||||
pos = modulename.find_last_of (_T("\\"));
|
pos = modulename.find_last_of (_T("\\"));
|
||||||
|
if (pos == string::npos)
|
||||||
|
{
|
||||||
|
cerr << "Error: trace is not available (corrupted debug info" << endl;
|
||||||
|
dumpCheckpoints();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
modulename = modulename.substr (pos + 1, modulename.length () - pos);
|
modulename = modulename.substr (pos + 1, modulename.length () - pos);
|
||||||
pos = modulename.find_last_of (_T("."));
|
pos = modulename.find_last_of (_T("."));
|
||||||
|
if (pos == string::npos)
|
||||||
|
{
|
||||||
|
cerr << "Error: trace is not available (corrupted debug info" << endl;
|
||||||
|
dumpCheckpoints();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
modulename = modulename.substr (0, pos);
|
modulename = modulename.substr (0, pos);
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -201,16 +269,17 @@ namespace Sysreg_
|
||||||
///
|
///
|
||||||
/// resolve frame addresses
|
/// resolve frame addresses
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clear && debug_data.size () > 5)
|
if (clear && debug_data.size () > 5)
|
||||||
{
|
{
|
||||||
debug_data.clear ();
|
debug_data.clear ();
|
||||||
}
|
}
|
||||||
return true;
|
return state;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
bool RosBootTest::isTimeout(double max_timeout)
|
bool RosBootTest::isTimeout(double max_timeout)
|
||||||
|
@ -253,6 +322,15 @@ namespace Sysreg_
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
vector<string> vect;
|
vector<string> vect;
|
||||||
|
|
||||||
|
if (m_Delayread)
|
||||||
|
{
|
||||||
|
///
|
||||||
|
/// delay reading untill emulator is ready
|
||||||
|
///
|
||||||
|
|
||||||
|
_sleep( (clock_t)m_Delayread * CLOCKS_PER_SEC );
|
||||||
|
}
|
||||||
|
|
||||||
while(!pipe_reader.isEof ())
|
while(!pipe_reader.isEof ())
|
||||||
{
|
{
|
||||||
if (isTimeout(m_Timeout))
|
if (isTimeout(m_Timeout))
|
||||||
|
@ -263,12 +341,17 @@ namespace Sysreg_
|
||||||
pipe_reader.readPipe (Buffer);
|
pipe_reader.readPipe (Buffer);
|
||||||
vect.push_back (Buffer);
|
vect.push_back (Buffer);
|
||||||
|
|
||||||
|
DebugState state = checkDebugData(vect);
|
||||||
|
|
||||||
if (!checkDebugData(vect))
|
if (state == DebugStateBSODDetected || state == DebugStateUMEDetected)
|
||||||
{
|
{
|
||||||
ret = false;
|
ret = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (state == DebugStateCPReached)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pipe_reader.closePipe ();
|
pipe_reader.closePipe ();
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -285,9 +368,15 @@ namespace Sysreg_
|
||||||
cerr << "Error: failed to open pipe with cmd: " << boot_cmd << endl;
|
cerr << "Error: failed to open pipe with cmd: " << boot_cmd << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// FIXXME
|
|
||||||
// give the emulator some time to load freeloadr
|
if (m_Delayread)
|
||||||
_sleep( (clock_t)4 * CLOCKS_PER_SEC );
|
{
|
||||||
|
///
|
||||||
|
/// delay reading untill emulator is ready
|
||||||
|
///
|
||||||
|
|
||||||
|
_sleep( (clock_t)m_Delayread * CLOCKS_PER_SEC );
|
||||||
|
}
|
||||||
|
|
||||||
int pid = 0;
|
int pid = 0;
|
||||||
|
|
||||||
|
@ -343,11 +432,18 @@ namespace Sysreg_
|
||||||
vect.push_back (line);
|
vect.push_back (line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checkDebugData(vect))
|
DebugState state = checkDebugData(vect);
|
||||||
|
|
||||||
|
if (state == DebugStateBSODDetected || state == DebugStateUMEDetected)
|
||||||
{
|
{
|
||||||
ret = false;
|
ret = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (state == DebugStateCPReached)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (isTimeout(m_Timeout))
|
if (isTimeout(m_Timeout))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -34,6 +34,9 @@ namespace Sysreg_
|
||||||
static string DEBUG_FILE;
|
static string DEBUG_FILE;
|
||||||
static string TIME_OUT;
|
static string TIME_OUT;
|
||||||
static string PID_FILE;
|
static string PID_FILE;
|
||||||
|
static string CHECK_POINT;
|
||||||
|
static string SYSREG_CHECKPOINT;
|
||||||
|
static string DELAY_READ;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
|
@ -93,6 +96,22 @@ namespace Sysreg_
|
||||||
|
|
||||||
bool fetchDebugByFile(string BootCmd, string debug_log);
|
bool fetchDebugByFile(string BootCmd, string debug_log);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
/// dumpCheckpoints
|
||||||
|
///
|
||||||
|
/// Description: prints a list of all reached checkpoints so far
|
||||||
|
|
||||||
|
void dumpCheckpoints();
|
||||||
|
|
||||||
|
typedef enum DebugState
|
||||||
|
{
|
||||||
|
DebugStateContinue = 1, /* continue debugging */
|
||||||
|
DebugStateBSODDetected, /* bsod detected */
|
||||||
|
DebugStateUMEDetected, /* user-mode exception detected */
|
||||||
|
DebugStateCPReached /* check-point reached */
|
||||||
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
/// checkDebugData
|
/// checkDebugData
|
||||||
|
@ -103,7 +122,7 @@ namespace Sysreg_
|
||||||
/// Note: the received debug information should be written to an internal log object
|
/// Note: the received debug information should be written to an internal log object
|
||||||
/// to facilate post-processing of the results
|
/// to facilate post-processing of the results
|
||||||
|
|
||||||
bool checkDebugData(vector<string> & debug_data);
|
DebugState checkDebugData(vector<string> & debug_data);
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
|
@ -118,6 +137,9 @@ protected:
|
||||||
|
|
||||||
double m_Timeout;
|
double m_Timeout;
|
||||||
string m_PidFile;
|
string m_PidFile;
|
||||||
|
string m_Checkpoint;
|
||||||
|
vector <string> m_Checkpoints;
|
||||||
|
unsigned long m_Delayread;
|
||||||
|
|
||||||
}; // end of class RosBootTest
|
}; // end of class RosBootTest
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,19 @@ ROSBOOT_DEBUG_PORT=file
|
||||||
;ROSBOOT_DEBUG_FILE=D:\ReactOS\tools\sysreg\bsdebug.log
|
;ROSBOOT_DEBUG_FILE=D:\ReactOS\tools\sysreg\bsdebug.log
|
||||||
ROSBOOT_DEBUG_FILE=D:\ReactOS\tools\sysreg\debug.log
|
ROSBOOT_DEBUG_FILE=D:\ReactOS\tools\sysreg\debug.log
|
||||||
|
|
||||||
|
; ROSBOOT_DELAY_READ;
|
||||||
|
;
|
||||||
|
; When the emulator is started, it spends a little time loading and running through its
|
||||||
|
; BIOS. This time delays reading from the pipe/file untill the specified value
|
||||||
|
;
|
||||||
|
; the value is in seconds
|
||||||
|
;
|
||||||
|
; Note: if the value is not provided, then reading debug info is started immediately
|
||||||
|
|
||||||
|
ROSBOOT_DELAY_READ=4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; ROSBOOT_TIME_OUT
|
; ROSBOOT_TIME_OUT
|
||||||
;
|
;
|
||||||
; This variable is the maximum runtime of the ROSBOOT_CMD. If the command
|
; This variable is the maximum runtime of the ROSBOOT_CMD. If the command
|
||||||
|
@ -68,3 +81,14 @@ ROSBOOT_DEBUG_FILE=D:\ReactOS\tools\sysreg\debug.log
|
||||||
;
|
;
|
||||||
ROSBOOT_TIME_OUT=180.0
|
ROSBOOT_TIME_OUT=180.0
|
||||||
|
|
||||||
|
; ROSBOOT_CHECK_POINT
|
||||||
|
;
|
||||||
|
; RosBoot will stop executing when it finds a string in the form
|
||||||
|
; SYSREG_CHECKPOINT:CP_NAME
|
||||||
|
;
|
||||||
|
; CP_NAME is the value of the ROSBOOT_CHECK_POINT variable
|
||||||
|
|
||||||
|
ROSBOOT_CHECKPOINT=USETUP_COMPLETED
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue