mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 12:24:52 +08:00
[0.2.x] added : getCurrentProcessId routine ( Return PID of the current process ( user mode only ) )
[0.2.x] added : getCurrentThreadId routine ( Return TID of the current thread ( user mode only ) ) [0.2.x] added : eventHandler.onExecutionStatusChange method ( Triggered execution status changed ) git-svn-id: https://pykd.svn.codeplex.com/svn@82898 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
60963e6a9f
commit
df0be475c8
@ -109,6 +109,7 @@ struct DEBUG_EVENT_CALLBACK {
|
|||||||
virtual DEBUG_CALLBACK_RESULT OnModuleLoad( ULONG64 offset, const std::string &name ) = 0;
|
virtual DEBUG_CALLBACK_RESULT OnModuleLoad( ULONG64 offset, const std::string &name ) = 0;
|
||||||
virtual DEBUG_CALLBACK_RESULT OnModuleUnload( ULONG64 offset, const std::string &name ) = 0;
|
virtual DEBUG_CALLBACK_RESULT OnModuleUnload( ULONG64 offset, const std::string &name ) = 0;
|
||||||
virtual DEBUG_CALLBACK_RESULT OnException( ExceptionInfoPtr exceptInfo ) = 0;
|
virtual DEBUG_CALLBACK_RESULT OnException( ExceptionInfoPtr exceptInfo ) = 0;
|
||||||
|
virtual void onExecutionStatusChange( ULONG executionStatus ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EVENT_TYPE {
|
enum EVENT_TYPE {
|
||||||
@ -133,6 +134,13 @@ EVENT_TYPE getLastEventType();
|
|||||||
ExceptionInfoPtr getLastExceptionInfo();
|
ExceptionInfoPtr getLastExceptionInfo();
|
||||||
|
|
||||||
|
|
||||||
|
enum EXECUTION_STATUS {
|
||||||
|
DebugStatusNoChange = 0,
|
||||||
|
DebugStatusGo = 1,
|
||||||
|
DebugStatusBreak = 6,
|
||||||
|
DebugStatusNoDebuggee = 7
|
||||||
|
};
|
||||||
|
|
||||||
struct BUG_CHECK_DATA
|
struct BUG_CHECK_DATA
|
||||||
{
|
{
|
||||||
ULONG code;
|
ULONG code;
|
||||||
@ -154,7 +162,9 @@ void breakPointRemoveAll();
|
|||||||
|
|
||||||
// processes end threads
|
// processes end threads
|
||||||
ULONG64 getCurrentProcess();
|
ULONG64 getCurrentProcess();
|
||||||
|
ULONG getCurrentProcessId();
|
||||||
ULONG64 getImplicitThread();
|
ULONG64 getImplicitThread();
|
||||||
|
ULONG getCurrentThreadId();
|
||||||
void setCurrentProcess( ULONG64 processAddr );
|
void setCurrentProcess( ULONG64 processAddr );
|
||||||
void setImplicitThread( ULONG64 threadAddr );
|
void setImplicitThread( ULONG64 threadAddr );
|
||||||
void getAllProcessThreads( std::vector<ULONG64> &threadsArray );
|
void getAllProcessThreads( std::vector<ULONG64> &threadsArray );
|
||||||
|
@ -26,6 +26,7 @@ private:
|
|||||||
virtual DEBUG_CALLBACK_RESULT OnModuleLoad( ULONG64 offset, const std::string &name ) = 0;
|
virtual DEBUG_CALLBACK_RESULT OnModuleLoad( ULONG64 offset, const std::string &name ) = 0;
|
||||||
virtual DEBUG_CALLBACK_RESULT OnModuleUnload( ULONG64 offset, const std::string &name ) = 0;
|
virtual DEBUG_CALLBACK_RESULT OnModuleUnload( ULONG64 offset, const std::string &name ) = 0;
|
||||||
virtual DEBUG_CALLBACK_RESULT OnException( ExceptionInfoPtr exceptInfo ) = 0;
|
virtual DEBUG_CALLBACK_RESULT OnException( ExceptionInfoPtr exceptInfo ) = 0;
|
||||||
|
virtual void onExecutionStatusChange( ULONG executionStatus ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -52,15 +53,35 @@ public:
|
|||||||
return handler("onException", exceptInfo );
|
return handler("onException", exceptInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void onExecutionStatusChange( ULONG executionStatus ) {
|
||||||
|
void_handler("onExecutionStatusChange", executionStatus );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
template<typename Arg1Type>
|
||||||
|
void void_handler( const char* handlerName, Arg1Type arg1 )
|
||||||
|
{
|
||||||
|
if (python::override pythonHandler = get_override( handlerName ))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
pythonHandler(arg1);
|
||||||
|
}
|
||||||
|
catch (const python::error_already_set &) {
|
||||||
|
printException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename Arg1Type>
|
template<typename Arg1Type>
|
||||||
DEBUG_CALLBACK_RESULT handler( const char* handlerName, Arg1Type arg1 )
|
DEBUG_CALLBACK_RESULT handler( const char* handlerName, Arg1Type arg1 )
|
||||||
{
|
{
|
||||||
if (python::override pythonHandler = get_override( handlerName ))
|
if (python::override pythonHandler = get_override( handlerName ))
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return pythonHandler(arg1);
|
pythonHandler(arg1);
|
||||||
}
|
}
|
||||||
catch (const python::error_already_set &) {
|
catch (const python::error_already_set &) {
|
||||||
printException();
|
printException();
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define PYKD_VERSION_MAJOR 0
|
#define PYKD_VERSION_MAJOR 0
|
||||||
#define PYKD_VERSION_MINOR 2
|
#define PYKD_VERSION_MINOR 2
|
||||||
#define PYKD_VERSION_SUBVERSION 0
|
#define PYKD_VERSION_SUBVERSION 0
|
||||||
#define PYKD_VERSION_BUILDNO 17
|
#define PYKD_VERSION_BUILDNO 18
|
||||||
|
|
||||||
|
|
||||||
#define __VER_STR2__(x) #x
|
#define __VER_STR2__(x) #x
|
||||||
|
@ -299,6 +299,12 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Set implicit thread for current process" );
|
"Set implicit thread for current process" );
|
||||||
python::def( "getProcessThreads", &pysupport::getProcessThreads,
|
python::def( "getProcessThreads", &pysupport::getProcessThreads,
|
||||||
"Get all process's threads ( user mode only )" );
|
"Get all process's threads ( user mode only )" );
|
||||||
|
python::def( "getCurrentProcessId", &getCurrentProcessId,
|
||||||
|
"Return PID of the current process ( user mode only )" );
|
||||||
|
python::def( "getCurrentThreadId", &getCurrentThreadId,
|
||||||
|
"Return TID of the current thread ( user mode only )" );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// symbol path
|
// symbol path
|
||||||
python::def( "getSymbolPath", &getSymbolPath, "Returns current symbol path");
|
python::def( "getSymbolPath", &getSymbolPath, "Returns current symbol path");
|
||||||
@ -582,6 +588,13 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
.value("Break", DebugCallbackBreak)
|
.value("Break", DebugCallbackBreak)
|
||||||
.export_values();
|
.export_values();
|
||||||
|
|
||||||
|
python::enum_<EXECUTION_STATUS>("executionStatus", "Execution Status")
|
||||||
|
.value("NoChange", DebugStatusNoChange )
|
||||||
|
.value("Go", DebugStatusGo )
|
||||||
|
.value("Break", DebugStatusBreak )
|
||||||
|
.value("NoDebuggee", DebugStatusNoDebuggee )
|
||||||
|
.export_values();
|
||||||
|
|
||||||
python::class_<EventHandlerWrap, EventHandlerPtr, boost::noncopyable>(
|
python::class_<EventHandlerWrap, EventHandlerPtr, boost::noncopyable>(
|
||||||
"eventHandler", "Base class for overriding and handling debug notifications" )
|
"eventHandler", "Base class for overriding and handling debug notifications" )
|
||||||
.def( "onBreakpoint", &EventHandlerWrap::OnBreakpoint,
|
.def( "onBreakpoint", &EventHandlerWrap::OnBreakpoint,
|
||||||
@ -595,7 +608,10 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"For ignore event method must return eventResult.noChange" )
|
"For ignore event method must return eventResult.noChange" )
|
||||||
.def( "onException", &EventHandlerWrap::OnException,
|
.def( "onException", &EventHandlerWrap::OnException,
|
||||||
"Triggered exception event. Parameter - exceptionInfo\n"
|
"Triggered exception event. Parameter - exceptionInfo\n"
|
||||||
"For ignore event method must return eventResult.noChange" );
|
"For ignore event method must return eventResult.noChange" )
|
||||||
|
.def( "onExecutionStatusChange", &EventHandlerWrap::onExecutionStatusChange,
|
||||||
|
"Triggered execution status changed. Parameter - execution status.\n"
|
||||||
|
"There is no return value" );
|
||||||
|
|
||||||
// wrapper for standart python exceptions
|
// wrapper for standart python exceptions
|
||||||
python::register_exception_translator<PyException>( &PyException::exceptionTranslate );
|
python::register_exception_translator<PyException>( &PyException::exceptionTranslate );
|
||||||
|
@ -1235,14 +1235,6 @@ ULONG breakPointSet( ULONG64 offset, bool hardware, ULONG size, ULONG accessType
|
|||||||
throw DbgException("IDebugBreakpoint::GetFlags", hres);
|
throw DbgException("IDebugBreakpoint::GetFlags", hres);
|
||||||
}
|
}
|
||||||
|
|
||||||
bpFlags |= DEBUG_BREAKPOINT_ENABLED;
|
|
||||||
hres = bp->SetFlags(bpFlags);
|
|
||||||
if (S_OK != hres)
|
|
||||||
{
|
|
||||||
g_dbgEng->control->RemoveBreakpoint(bp);
|
|
||||||
throw DbgException("IDebugBreakpoint::SetFlags", hres);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( hardware )
|
if ( hardware )
|
||||||
{
|
{
|
||||||
HRESULT hres = bp->SetDataParameters(size, accessType);
|
HRESULT hres = bp->SetDataParameters(size, accessType);
|
||||||
@ -1253,6 +1245,14 @@ ULONG breakPointSet( ULONG64 offset, bool hardware, ULONG size, ULONG accessType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bpFlags |= DEBUG_BREAKPOINT_ENABLED | DEBUG_BREAKPOINT_GO_ONLY;
|
||||||
|
hres = bp->SetFlags(bpFlags);
|
||||||
|
if (S_OK != hres)
|
||||||
|
{
|
||||||
|
g_dbgEng->control->RemoveBreakpoint(bp);
|
||||||
|
throw DbgException("IDebugBreakpoint::SetFlags", hres);
|
||||||
|
}
|
||||||
|
|
||||||
ULONG breakId;
|
ULONG breakId;
|
||||||
hres = bp->GetId(&breakId);
|
hres = bp->GetId(&breakId);
|
||||||
if (S_OK != hres)
|
if (S_OK != hres)
|
||||||
@ -1513,6 +1513,30 @@ HRESULT STDMETHODCALLTYPE DebugEngine::Exception(
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE DebugEngine::ChangeEngineState(
|
||||||
|
__in ULONG Flags,
|
||||||
|
__in ULONG64 Argument )
|
||||||
|
{
|
||||||
|
boost::recursive_mutex::scoped_lock l(m_handlerLock);
|
||||||
|
|
||||||
|
HandlerList::iterator it = m_handlers.begin();
|
||||||
|
|
||||||
|
for ( ; it != m_handlers.end(); ++it )
|
||||||
|
{
|
||||||
|
if ( ( Flags & DEBUG_CES_EXECUTION_STATUS ) != 0 &&
|
||||||
|
( Argument & DEBUG_STATUS_INSIDE_WAIT ) == 0 )
|
||||||
|
{
|
||||||
|
PyThread_StateSave pyThreadSave( it->pystate );
|
||||||
|
|
||||||
|
it->callback->onExecutionStatusChange( (ULONG)Argument );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG64
|
ULONG64
|
||||||
getCurrentProcess()
|
getCurrentProcess()
|
||||||
{
|
{
|
||||||
@ -1528,6 +1552,24 @@ getCurrentProcess()
|
|||||||
return processAddr;
|
return processAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ULONG getCurrentProcessId()
|
||||||
|
{
|
||||||
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
|
||||||
|
HRESULT hres;
|
||||||
|
ULONG pid;
|
||||||
|
|
||||||
|
hres = g_dbgEng->system->GetCurrentProcessSystemId( &pid );
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugSystemObjects2::GetCurrentProcessSystemId failed" );
|
||||||
|
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG64
|
ULONG64
|
||||||
@ -1547,6 +1589,22 @@ getImplicitThread()
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ULONG getCurrentThreadId()
|
||||||
|
{
|
||||||
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
|
||||||
|
HRESULT hres;
|
||||||
|
ULONG tid;
|
||||||
|
|
||||||
|
hres = g_dbgEng->system->GetCurrentThreadSystemId( &tid );
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugSystemObjects2::GetCurrentThreadSystemId failed" );
|
||||||
|
|
||||||
|
return tid;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void setCurrentProcess( ULONG64 processAddr )
|
void setCurrentProcess( ULONG64 processAddr )
|
||||||
{
|
{
|
||||||
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
@ -1673,8 +1731,6 @@ std::string callExtension( ULONG64 extHandle, const std::wstring command, const
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // end pykd namespace
|
} // end pykd namespace
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ public:
|
|||||||
*Mask |= DEBUG_EVENT_LOAD_MODULE;
|
*Mask |= DEBUG_EVENT_LOAD_MODULE;
|
||||||
*Mask |= DEBUG_EVENT_UNLOAD_MODULE;
|
*Mask |= DEBUG_EVENT_UNLOAD_MODULE;
|
||||||
*Mask |= DEBUG_EVENT_EXCEPTION;
|
*Mask |= DEBUG_EVENT_EXCEPTION;
|
||||||
|
*Mask |= DEBUG_EVENT_CHANGE_ENGINE_STATE;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +80,10 @@ public:
|
|||||||
__in PEXCEPTION_RECORD64 Exception,
|
__in PEXCEPTION_RECORD64 Exception,
|
||||||
__in ULONG FirstChance );
|
__in ULONG FirstChance );
|
||||||
|
|
||||||
|
STDMETHOD(ChangeEngineState)(
|
||||||
|
__in ULONG Flags,
|
||||||
|
__in ULONG64 Argument );
|
||||||
|
|
||||||
DbgEngBind*
|
DbgEngBind*
|
||||||
operator->()
|
operator->()
|
||||||
{
|
{
|
||||||
|
@ -6,15 +6,17 @@ import pykd
|
|||||||
import testutils
|
import testutils
|
||||||
|
|
||||||
class ExceptionHandler(pykd.eventHandler):
|
class ExceptionHandler(pykd.eventHandler):
|
||||||
"""Track load/unload module implementation"""
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pykd.eventHandler.__init__(self)
|
pykd.eventHandler.__init__(self)
|
||||||
self.accessViolationOccured = False
|
self.accessViolationOccured = False
|
||||||
|
|
||||||
def onException(self, exceptInfo):
|
def onException(self, exceptInfo):
|
||||||
"""Exception handler"""
|
"""Exception handler"""
|
||||||
|
|
||||||
self.accessViolationOccured = exceptInfo.ExceptionCode == 0xC0000005
|
self.accessViolationOccured = exceptInfo.ExceptionCode == 0xC0000005
|
||||||
|
|
||||||
|
print exceptInfo
|
||||||
|
|
||||||
if self.accessViolationOccured:
|
if self.accessViolationOccured:
|
||||||
self.param0 = exceptInfo.Parameters[0]
|
self.param0 = exceptInfo.Parameters[0]
|
||||||
self.param1 = exceptInfo.Parameters[1]
|
self.param1 = exceptInfo.Parameters[1]
|
||||||
@ -27,7 +29,7 @@ class EhExceptionTest(unittest.TestCase):
|
|||||||
|
|
||||||
def testException(self):
|
def testException(self):
|
||||||
"""Start new process and track exceptions"""
|
"""Start new process and track exceptions"""
|
||||||
_locProcessId = pykd.startProcess( target.appPath + " -testAccessViolation" )
|
_locProcessId = pykd.startProcess( target.appPath + " -testExceptions" )
|
||||||
with testutils.ContextCallIt( testutils.KillProcess(_locProcessId) ) as killStartedProcess :
|
with testutils.ContextCallIt( testutils.KillProcess(_locProcessId) ) as killStartedProcess :
|
||||||
exceptionHandler = ExceptionHandler()
|
exceptionHandler = ExceptionHandler()
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ class EhExceptionTest(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertTrue( exceptionHandler.accessViolationOccured )
|
self.assertTrue( exceptionHandler.accessViolationOccured )
|
||||||
self.assertEqual( exceptionHandler.param0, 1 ) # write
|
self.assertEqual( exceptionHandler.param0, 1 ) # write
|
||||||
self.assertEqual( exceptionHandler.param1, 6 ) # addr
|
self.assertEqual( exceptionHandler.param1, 2 ) # addr
|
||||||
|
|
||||||
exceptInfo = pykd.lastException()
|
exceptInfo = pykd.lastException()
|
||||||
self.assertEqual( exceptInfo.ExceptionCode, 0xC0000005 )
|
self.assertEqual( exceptInfo.ExceptionCode, 0xC0000005 )
|
||||||
|
36
test/scripts/ehstatustest.py
Normal file
36
test/scripts/ehstatustest.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
"""Execution status event test"""
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
import target
|
||||||
|
import pykd
|
||||||
|
import testutils
|
||||||
|
|
||||||
|
class StatusChangeHandler(pykd.eventHandler):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pykd.eventHandler.__init__(self)
|
||||||
|
self.breakCount = 0
|
||||||
|
|
||||||
|
|
||||||
|
def onExecutionStatusChange(self, executionStatus):
|
||||||
|
if executionStatus == pykd.executionStatus.Break:
|
||||||
|
self.breakCount = self.breakCount + 1
|
||||||
|
|
||||||
|
|
||||||
|
class EhStatusTest(unittest.TestCase):
|
||||||
|
"""Execution status event test"""
|
||||||
|
|
||||||
|
def testException(self):
|
||||||
|
"""Start new process and track exceptions"""
|
||||||
|
_locProcessId = pykd.startProcess( target.appPath + " -testChangeStatus" )
|
||||||
|
with testutils.ContextCallIt( testutils.KillProcess(_locProcessId) ) as killStartedProcess :
|
||||||
|
|
||||||
|
pykd.go() #skip initial break
|
||||||
|
|
||||||
|
statusChangeHandler = StatusChangeHandler()
|
||||||
|
|
||||||
|
pykd.go()
|
||||||
|
pykd.go()
|
||||||
|
|
||||||
|
self.assertEqual( 2, statusChangeHandler.breakCount )
|
||||||
|
|
@ -13,6 +13,9 @@ class handler( pykd.eventHandler ):
|
|||||||
self.counter += 1
|
self.counter += 1
|
||||||
return pykd.DEBUG_STATUS_NO_CHANGE
|
return pykd.DEBUG_STATUS_NO_CHANGE
|
||||||
|
|
||||||
|
def onExecutionStatusChange(self,status):
|
||||||
|
print status
|
||||||
|
|
||||||
class EventTest( unittest.TestCase ):
|
class EventTest( unittest.TestCase ):
|
||||||
|
|
||||||
def testDebugBreak( self ):
|
def testDebugBreak( self ):
|
||||||
|
@ -73,7 +73,7 @@ class ModuleTest( unittest.TestCase ):
|
|||||||
self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
|
self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
|
||||||
self.assertEqual( 2, displacement )
|
self.assertEqual( 2, displacement )
|
||||||
fileName, lineNo, displacement = pykd.getSourceLine()
|
fileName, lineNo, displacement = pykd.getSourceLine()
|
||||||
self.assertEqual( 663, lineNo )
|
self.assertEqual( 673, lineNo )
|
||||||
|
|
||||||
def testEnumSymbols( self ):
|
def testEnumSymbols( self ):
|
||||||
lst = target.module.enumSymbols()
|
lst = target.module.enumSymbols()
|
||||||
|
@ -22,6 +22,7 @@ import regtest
|
|||||||
import localstest
|
import localstest
|
||||||
import customtypestest
|
import customtypestest
|
||||||
import ehexcepttest
|
import ehexcepttest
|
||||||
|
import ehstatustest
|
||||||
|
|
||||||
class StartProcessWithoutParamsTest(unittest.TestCase):
|
class StartProcessWithoutParamsTest(unittest.TestCase):
|
||||||
def testStart(self):
|
def testStart(self):
|
||||||
@ -53,6 +54,7 @@ def getTestSuite( singleName = "" ):
|
|||||||
|
|
||||||
unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ),
|
unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ),
|
||||||
unittest.TestLoader().loadTestsFromTestCase( ehexcepttest.EhExceptionTest ),
|
unittest.TestLoader().loadTestsFromTestCase( ehexcepttest.EhExceptionTest ),
|
||||||
|
unittest.TestLoader().loadTestsFromTestCase( ehstatustest.EhStatusTest ),
|
||||||
] )
|
] )
|
||||||
else:
|
else:
|
||||||
return unittest.TestSuite(
|
return unittest.TestSuite(
|
||||||
|
@ -602,6 +602,16 @@ int doExeptions()
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int doChangeStatus()
|
||||||
|
{
|
||||||
|
__debugbreak();
|
||||||
|
__debugbreak();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
std::map<int, bool> g_map;
|
std::map<int, bool> g_map;
|
||||||
@ -680,6 +690,9 @@ int _tmain(int argc, _TCHAR* argv[])
|
|||||||
|
|
||||||
if ( !_tcsicmp(argv[1], _T("-testExceptions")) )
|
if ( !_tcsicmp(argv[1], _T("-testExceptions")) )
|
||||||
return doExeptions();
|
return doExeptions();
|
||||||
|
|
||||||
|
if ( !_tcsicmp(argv[1], _T("-testChangeStatus")) )
|
||||||
|
return doChangeStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
|
@ -550,12 +550,6 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
|
||||||
Name="Resource Files"
|
|
||||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
|
||||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
|
||||||
>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
<Filter
|
||||||
Name="scripts"
|
Name="scripts"
|
||||||
>
|
>
|
||||||
@ -587,6 +581,10 @@
|
|||||||
RelativePath="..\scripts\ehloadtest.py"
|
RelativePath="..\scripts\ehloadtest.py"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\scripts\ehstatustest.py"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\scripts\eventtest.py"
|
RelativePath="..\scripts\eventtest.py"
|
||||||
>
|
>
|
||||||
@ -640,6 +638,12 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
</Globals>
|
</Globals>
|
||||||
|
Loading…
Reference in New Issue
Block a user