diff --git a/reactos/tools/sysreg/conf_parser.cpp b/reactos/tools/sysreg/conf_parser.cpp index d6020bf64bb..31c8f744bea 100644 --- a/reactos/tools/sysreg/conf_parser.cpp +++ b/reactos/tools/sysreg/conf_parser.cpp @@ -65,7 +65,7 @@ namespace Sysreg_ buf = _fgetts(buffer, sizeof(buffer) / sizeof(TCHAR), file); if (buf) { - if (buffer[0] != ';') + if (buffer[0] != _T(';')) { string s_buffer = string(buffer); string::size_type ws_pos = s_buffer.find_first_of (_T("=")); diff --git a/reactos/tools/sysreg/conf_parser.h b/reactos/tools/sysreg/conf_parser.h index b8e331bce32..18e9fb9189d 100644 --- a/reactos/tools/sysreg/conf_parser.h +++ b/reactos/tools/sysreg/conf_parser.h @@ -10,7 +10,7 @@ * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) */ - +#include "user_types.h" #include #include #include diff --git a/reactos/tools/sysreg/file_reader.cpp b/reactos/tools/sysreg/file_reader.cpp new file mode 100644 index 00000000000..7d36bdeea20 --- /dev/null +++ b/reactos/tools/sysreg/file_reader.cpp @@ -0,0 +1,168 @@ +/* $Id: pipe_reader.cpp 24589 2006-10-21 08:34:00Z janderwald $ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: file reading support + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + +#include "file_reader.h" +#include + +namespace System_ +{ +//--------------------------------------------------------------------------------------- + FileReader::FileReader() : m_File(NULL) + { + } +//--------------------------------------------------------------------------------------- + FileReader::~FileReader() + { + } +//--------------------------------------------------------------------------------------- + bool FileReader::openFile(TCHAR const * filename) + { +#ifdef UNICODE + m_File = _tfopen(filename, _T("rb,ccs=UNICODE")); +#else + m_File = _tfopen(filename, _T("rb")); +#endif + + if (m_File) + { + return true; + } + else + { + return false; + } + } +//--------------------------------------------------------------------------------------- + bool FileReader::closeFile() + { + if (!m_File) + { + return false; + } + + if (!fclose(m_File)) + { + m_File = NULL; + return true; + } + + return false; + } +//--------------------------------------------------------------------------------------- + bool FileReader::readFile(vector & lines) + { + if (!m_File) + { + return false; + } + + bool ret = true; + size_t total_length = 0; + size_t line_count = lines.size(); + size_t num = 0; + char szBuffer[256]; + int readoffset = 0; + +#ifdef UNICODE + wchar_t wbuf[512]; + int wbuf_offset = 0; + + if (m_BufferedLines.length ()) + { + wcscpy(wbuf, m_BufferedLines.c_str ()); + wbuf_offset = m_BufferedLines.length (); + } +#else + if (m_BufferedLines.length()) + { + strcpy(szBuffer, m_BufferedLines.c_str()); + readoffset = m_BufferedLines.length(); + } +#endif + + do + { + if (total_length < num) + { +#ifdef UNICODE + memmove(wbuf, &wbuf[total_length], (num - total_length) * sizeof(wchar_t)); + wbuf_offset = num - total_length; +#else + memmove(szBuffer, &szBuffer[total_length], num - total_length); + readoffset = num - total_length; +#endif + } + + num = fread(&szBuffer[readoffset], + sizeof(char), sizeof(szBuffer)/sizeof(char) - (readoffset+1) * sizeof(char), + m_File); + + szBuffer[num] = L'\0'; + + if (!num) + { + if (line_count == lines.size ()) + { + ret = false; + } + break; + } + TCHAR * ptr; +#ifdef UNICODE + int i = 0; + int conv; + while((conv = mbtowc(&wbuf[wbuf_offset+i], &szBuffer[i], num))) + { + i += conv; + if (i == num) + break; + + assert(wbuf_offset + i < 512); + } + wbuf[wbuf_offset + num] = L'\0'; + + TCHAR * offset = wbuf; +#else + + TCHAR * offset = szBuffer; +#endif + total_length = 0; + while(ptr = _tcsstr(offset, _T("\x0D\x0A"))) + { + int length = ((unsigned)ptr - (unsigned)offset); + length /= sizeof(TCHAR); + + offset[length] = L'\0'; + + string line = offset; + lines.push_back (line); + + offset += length + 2; + total_length += length + 2; + + if (total_length == num) + { + break; + } + } + }while(num ); + + if (total_length < num) + { +#ifdef UNICODE + m_BufferedLines = &wbuf[total_length]; +#else + m_BufferedLines = &szBuffer[total_length]; +#endif + } + + return ret; + } + +} // end of namespace System_ diff --git a/reactos/tools/sysreg/file_reader.h b/reactos/tools/sysreg/file_reader.h new file mode 100644 index 00000000000..22321a91b33 --- /dev/null +++ b/reactos/tools/sysreg/file_reader.h @@ -0,0 +1,91 @@ +#ifndef FILE_READER_H__ +#define FILE_READER_H__ + +/* $Id: pipe_reader.h 24587 2006-10-20 21:14:08Z janderwald $ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: pipe reader support + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + + +#include "user_types.h" + +#include + +namespace System_ +{ + using std::vector; +//--------------------------------------------------------------------------------------- +/// +/// class FileReader +/// +/// Description: this class implements reading from a file + + class FileReader + { + public: +//--------------------------------------------------------------------------------------- +/// +/// FileReader +/// +/// Description: constructor of class FileReader + + FileReader(); + +//--------------------------------------------------------------------------------------- +/// +/// ~FileReader +/// +/// Description: destructor of class FileReader + + virtual ~FileReader(); + +//--------------------------------------------------------------------------------------- +/// +/// openFile +/// +/// Description: attempts to open a file. Returns true on success +/// +/// @param filename name of the file to open +/// @return bool + + bool openFile(TCHAR const * filename); + +//--------------------------------------------------------------------------------------- +/// +/// closeFile +/// +/// Description: attempts to close a file. Returns true on success +/// +/// @return bool + + bool closeFile(); + +//--------------------------------------------------------------------------------------- +/// +/// readFile +/// +/// Description: reads from file. The result is stored in a vector of strings +/// +/// Note: returns true on success +/// + + bool readFile(vector & lines); + + + + protected: + FILE * m_File; + string m_BufferedLines; + + + }; // end of class FileReader + + +} // end of namespace System_ + + +#endif /* end of FILE_READER_H__ */ diff --git a/reactos/tools/sysreg/pipe_reader.h b/reactos/tools/sysreg/pipe_reader.h index 31b83c0b596..e4ccb8ca82a 100644 --- a/reactos/tools/sysreg/pipe_reader.h +++ b/reactos/tools/sysreg/pipe_reader.h @@ -6,7 +6,7 @@ * PROJECT: System regression tool for ReactOS * LICENSE: GPL - See COPYING in the top level directory * FILE: tools/sysreg/conf_parser.h - * PURPOSE: pipe reader support + * PURPOSE: file reading support * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) */ diff --git a/reactos/tools/sysreg/rosboot_test.cpp b/reactos/tools/sysreg/rosboot_test.cpp index 8db7632df4d..5f2e8368d78 100644 --- a/reactos/tools/sysreg/rosboot_test.cpp +++ b/reactos/tools/sysreg/rosboot_test.cpp @@ -12,6 +12,7 @@ #include "rosboot_test.h" #include "pipe_reader.h" #include "sym_file.h" +#include "file_reader.h" #include #include @@ -46,6 +47,7 @@ namespace Sysreg_ using std::vector; using System_::PipeReader; using System_::SymbolFile; + using System_::FileReader; string RosBootTest::VARIABLE_NAME = _T("ROSBOOT_CMD"); string RosBootTest::CLASS_NAME = _T("rosboot"); @@ -56,6 +58,7 @@ namespace Sysreg_ string RosBootTest::DELAY_READ = _T("ROSBOOT_DELAY_READ"); string RosBootTest::CHECK_POINT = _T("ROSBOOT_CHECK_POINT"); string RosBootTest::SYSREG_CHECKPOINT = _T("SYSREG_CHECKPOINT:"); + string RosBootTest::CRITICAL_APP = _T("ROSBOOT_CRITICAL_APP"); //--------------------------------------------------------------------------------------- RosBootTest::RosBootTest() : RegressionTest(RosBootTest::CLASS_NAME), m_Timeout(60.0), m_Delayread(0) @@ -123,6 +126,7 @@ namespace Sysreg_ conf_parser.getStringValue (RosBootTest::CHECK_POINT, m_Checkpoint); conf_parser.getStringValue (RosBootTest::PID_FILE, m_PidFile); + conf_parser.getStringValue (RosBootTest::CRITICAL_APP, m_CriticalApp); if (!_tcscmp(debug_port.c_str(), _T("pipe"))) @@ -203,6 +207,15 @@ namespace Sysreg_ } else if (line.find (_T("Unhandled exception")) != string::npos) { + if (m_CriticalApp == _T("IGNORE")) + { + /// + /// ignoring all user-mode exceptions + /// + continue; + } + + if (i + 3 >= debug_data.size ()) { /// @@ -212,9 +225,6 @@ namespace Sysreg_ break; } - cerr << "UM detected" < 1) + { + /// the application is not in the list of + /// critical apps. Therefore we ignore the user-mode + /// exception + + continue; + } + + pos = appname.find_last_of (_T(".")); if (pos == string::npos) { cerr << "Error: trace is not available (corrupted debug info" << endl; - dumpCheckpoints(); - break; + continue; } - modulename = modulename.substr (0, pos); + modulename = appname.substr (0, pos); + + cerr << "UM detected" < lines; + file.readFile(lines); + if (lines.size()) { - pid = _ttoi(szBuffer); + string line = lines[0]; + pid = _ttoi(line.c_str ()); } - + file.closeFile(); } - fclose(pidfile); } - - FILE * file = _tfopen(debug_log.c_str (), _T("rt")); - if (!file) + FileReader file; + if (!file.openFile (debug_log.c_str ())) { cerr << "Error: failed to open debug log " << debug_log << endl; pipe_reader.closePipe (); return false; } - TCHAR szBuffer[1000]; + vector lines; bool ret = true; - vector vect; while(!pipe_reader.isEof ()) { - if (_fgetts(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), file)) + if (file.readFile (lines)) { - - string line = szBuffer; - - while(line.find (_T("\x10")) != string::npos) - { - line.erase(line.find(_T("\x10")), 1); - } - - if (line[0] != _T('(') && vect.size() >=1) - { - string prev = vect[vect.size () -1]; - prev.insert (prev.length ()-1, line); - vect.pop_back (); - vect.push_back (prev); - - } - else - { - vect.push_back (line); - } - - DebugState state = checkDebugData(vect); + DebugState state = checkDebugData(lines); if (state == DebugStateBSODDetected || state == DebugStateUMEDetected) { @@ -443,14 +440,26 @@ namespace Sysreg_ { break; } - - if (isTimeout(m_Timeout)) + } + if (isTimeout(m_Timeout)) + { + /// + /// timeout has been reached + /// + if (m_Checkpoint != _T("")) { - break; + /// + /// timeout was reached but + /// the checkpoint was not reached + /// we see this as a "hang" + /// + ret = false; } + break; } } - fclose(file); + file.closeFile (); + if (pid) { #ifdef __LINUX__ diff --git a/reactos/tools/sysreg/rosboot_test.h b/reactos/tools/sysreg/rosboot_test.h index 8db13d95ff4..671c3abe344 100644 --- a/reactos/tools/sysreg/rosboot_test.h +++ b/reactos/tools/sysreg/rosboot_test.h @@ -37,6 +37,7 @@ namespace Sysreg_ static string CHECK_POINT; static string SYSREG_CHECKPOINT; static string DELAY_READ; + static string CRITICAL_APP; //--------------------------------------------------------------------------------------- /// @@ -138,6 +139,7 @@ protected: double m_Timeout; string m_PidFile; string m_Checkpoint; + string m_CriticalApp; vector m_Checkpoints; unsigned long m_Delayread; diff --git a/reactos/tools/sysreg/sample.cfg b/reactos/tools/sysreg/sample.cfg index e5fee736c04..12bed262652 100644 --- a/reactos/tools/sysreg/sample.cfg +++ b/reactos/tools/sysreg/sample.cfg @@ -77,9 +77,12 @@ ROSBOOT_DELAY_READ=4 ; This variable is the maximum runtime of the ROSBOOT_CMD. If the command ; runs longer than this value, sysreg exits with success mode; ; +; Note: if you set the variable ROSBOOT_CHECK_POINT and the checkpoint is not reached +; within this time, sysreg exits with failure mode +; ; If the variable is not set, the default timeout is 1 minute ; -ROSBOOT_TIME_OUT=180.0 +ROSBOOT_TIME_OUT=30.0 ; ROSBOOT_CHECK_POINT ; @@ -88,7 +91,23 @@ ROSBOOT_TIME_OUT=180.0 ; ; CP_NAME is the value of the ROSBOOT_CHECK_POINT variable -ROSBOOT_CHECKPOINT=USETUP_COMPLETED +ROSBOOT_CHECK_POINT=USETUP_COMPLETE + +; ROSBOOT_CRITICAL_APP +; +; If an user-mode exception occurs in an critical application, i.e. setup.exe / explorer.exe, sysreg will report +; that the test has failed and quit debugging immediately +; +; if an user-mode exception occurs in any other application, sysreg will report the exception but the exception +; has no effect on the test result +; +; Note: if the value is set to IGNORE, sysreg will ignore all user-mode exceptions +; +; Note: if the variable is not set, then sysreg will stop on the first user-mode exception +; +; seperate each application with an space +ROSBOOT_CRITICAL_APP=setup.exe userinit.exe smss.exe winlogon.exe csrss.exe explorer.exe +;ROSBOOT_CRITICAL_APP=setup.exe userinit.exe smss.exe winlogon.exe csrss.exe explorer.exe lsass.exe diff --git a/reactos/tools/sysreg/user_types.h b/reactos/tools/sysreg/user_types.h new file mode 100644 index 00000000000..8b1e16dca91 --- /dev/null +++ b/reactos/tools/sysreg/user_types.h @@ -0,0 +1,19 @@ +#ifndef USER_TYPES_H__ +#define USER_TYPES_H__ + +/* $Id: rosboot_test.cpp 24585 2006-10-20 19:40:33Z janderwald $ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/user_types.h + * PURPOSE: user types + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + +#include +#include + + typedef std::basic_string string; + + +#endif \ No newline at end of file