[0.1.x] added : go routine

[0.1.x] added : step routine
[0.1.x] added : trace routine
[0.1.x] added : waitForEvent routine ( Wait for events that breaks into the debugger )
[0.1.x] added : setExecutionStatus routine ( Requests that the debugger engine enter an executable state )
[0.1.x] added : getExecutionStatus routine ( Return information about the execution status of the debugger )


git-svn-id: https://pykd.svn.codeplex.com/svn@70639 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-10-20 06:33:44 +00:00 committed by Mikhail I. Izmestev
parent ff2db46e11
commit 4e072f3ef5
8 changed files with 204 additions and 397 deletions

View File

@ -1,7 +1,7 @@
#include "stdafx.h"
#include <vector>
#include "dbgclient.h"
#include <vector>
namespace pykd {
@ -70,6 +70,26 @@ python::tuple getDebuggeeType()
///////////////////////////////////////////////////////////////////////////////////
ULONG DebugClient::getExecutionStatus()
{
ULONG currentStatus;
HRESULT hres;
hres = m_control->GetExecutionStatus( &currentStatus );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
return currentStatus;
}
ULONG getExecutionStatus()
{
return g_dbgClient->getExecutionStatus();
}
///////////////////////////////////////////////////////////////////////////////////
bool DebugClient::isDumpAnalyzing()
{
HRESULT hres;
@ -190,6 +210,44 @@ void attachKernel( const std::wstring &param ) {
g_dbgClient->attachKernel( param );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::setExecutionStatus( ULONG status )
{
HRESULT hres;
hres = m_control->SetExecutionStatus( status );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::SetExecutionStatus failed" );
}
void setExecutionStatus( ULONG status )
{
g_dbgClient->setExecutionStatus( status );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::waitForEvent()
{
HRESULT hres;
do {
PyThread_StateRestore pyThreadRestore( m_pyThreadState );
hres = m_control->WaitForEvent( 0, INFINITE );
} while( false );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::WaitForEvent failed" );
}
void waitForEvent()
{
g_dbgClient->waitForEvent();
}
///////////////////////////////////////////////////////////////////////////////////

View File

@ -11,6 +11,7 @@
#include "module.h"
#include "dbgio.h"
#include "dbgcmd.h"
#include "pyaux.h"
/////////////////////////////////////////////////////////////////////////////////
@ -50,12 +51,15 @@ public:
void attachKernel( const std::wstring &param );
//createEventHandler();
ULONG64 evaluate( const std::wstring &expression );
python::tuple getDebuggeeType();
ULONG getExecutionStatus();
template<ULONG status>
void changeDebuggerStatus();
bool isKernelDebugging();
bool isDumpAnalyzing();
@ -74,6 +78,14 @@ public:
ULONG64 addr64( ULONG64 addr );
DbgOut dout() {
return DbgOut( m_client );
}
DbgIn din() {
return DbgIn( m_client );
}
void dprint( const std::wstring &str, bool dml = false );
void dprintln( const std::wstring &str, bool dml = false );
@ -82,13 +94,9 @@ public:
void eprintln( const std::wstring &str );
DbgOut dout() {
return DbgOut( m_client );
}
void setExecutionStatus( ULONG status );
DbgIn din() {
return DbgIn( m_client );
}
void waitForEvent();
public:
@ -110,6 +118,8 @@ public:
private:
DebugClient( IDebugClient4 *client ) : DbgObject( client ) {}
PyThreadStateSaver m_pyThreadState;
};
/////////////////////////////////////////////////////////////////////////////////
@ -126,12 +136,51 @@ void attachKernel( const std::wstring &param );
python::tuple getDebuggeeType();
ULONG getExecutionStatus();
bool isKernelDebugging();
bool isDumpAnalyzing();
void setExecutionStatus( ULONG status );
void waitForEvent();
/////////////////////////////////////////////////////////////////////////////////
template<ULONG status>
void DebugClient::changeDebuggerStatus()
{
HRESULT hres;
hres = m_control->SetExecutionStatus( status );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::SetExecutionStatus failed" );
ULONG currentStatus;
do {
waitForEvent();
hres = m_control->GetExecutionStatus( &currentStatus );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
} while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
}
template<ULONG status>
void changeDebuggerStatus()
{
g_dbgClient->changeDebuggerStatus<status>();
}
/////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd

View File

@ -72,6 +72,10 @@ BOOST_PYTHON_MODULE( pykd )
"Evaluate windbg expression" )
.def( "getDebuggeeType", &pykd::DebugClient::getDebuggeeType,
"Return type of the debuggee" )
.def( "getExecutionStatus", &pykd::DebugClient::getExecutionStatus,
"Return information about the execution status of the debugger" )
.def( "go", &pykd::DebugClient::changeDebuggerStatus<DEBUG_STATUS_GO>,
"Change debugger status to DEBUG_STATUS_GO" )
.def( "isDumpAnalyzing", &pykd::DebugClient::isDumpAnalyzing,
"Check if it is a dump analyzing ( not living debuggee )" )
.def( "isKernelDebugging", &pykd::DebugClient::isKernelDebugging,
@ -87,7 +91,15 @@ BOOST_PYTHON_MODULE( pykd )
.def( "dprint", &pykd::DebugClient::dprint,
"Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" )
.def( "dprintln", &pykd::DebugClient::dprintln,
"Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" );
"Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" )
.def( "setExecutionStatus", &pykd::DebugClient::setExecutionStatus,
"Requests that the debugger engine enter an executable state" )
.def( "step", &pykd::DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>,
"Change debugger status to DEBUG_STATUS_STEP_OVER" )
.def( "trace", &pykd::DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_INTO>,
"Change debugger status to DEBUG_STATUS_STEP_INTO" )
.def( "waitForEvent", &pykd::DebugClient::waitForEvent,
"Wait for events that breaks into the debugger" );
python::def( "createDbgClient", (DebugClientPtr(*)())&pykd::DebugClient::createDbgClient,
"create a new instance of the dbgClient class" );
@ -103,6 +115,10 @@ BOOST_PYTHON_MODULE( pykd )
"Evaluate windbg expression" );
python::def( "getDebuggeeType", &pykd::getDebuggeeType,
"Return type of the debuggee" );
python::def( "getExecutionStatus", &pykd::getExecutionStatus,
"Return information about the execution status of the debugger" );
python::def( "go", &pykd::changeDebuggerStatus<DEBUG_STATUS_GO>,
"Change debugger status to DEBUG_STATUS_GO" );
python::def( "isDumpAnalyzing", &pykd::isDumpAnalyzing,
"Check if it is a dump analyzing ( not living debuggee )" );
python::def( "isKernelDebugging", &pykd::isKernelDebugging,
@ -119,6 +135,14 @@ BOOST_PYTHON_MODULE( pykd )
"Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
python::def( "dprintln", &pykd::dprintln, dprintln_( boost::python::args( "str", "dml" ),
"Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
python::def( "setExecutionStatus", &pykd::setExecutionStatus,
"Requests that the debugger engine enter an executable state" );
python::def( "step", &pykd::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>,
"Change debugger status to DEBUG_STATUS_STEP_OVER" );
python::def( "trace", &pykd::changeDebuggerStatus<DEBUG_STATUS_STEP_INTO>,
"Change debugger status to DEBUG_STATUS_STEP_INTO" );
python::def( "waitForEvent", &pykd::waitForEvent,
"Wait for events that breaks into the debugger" );
python::class_<pykd::TypeInfo>("typeInfo", "Class representing typeInfo", python::no_init )
.def( "name", &pykd::TypeInfo::getName )
@ -400,6 +424,22 @@ BOOST_PYTHON_MODULE( pykd )
DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_PROCESS_SERVER );
DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_SMALL_DUMP );
DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_DUMP );
// debug status
DEF_PY_CONST_ULONG(DEBUG_STATUS_NO_CHANGE);
DEF_PY_CONST_ULONG(DEBUG_STATUS_GO);
DEF_PY_CONST_ULONG(DEBUG_STATUS_GO_HANDLED);
DEF_PY_CONST_ULONG(DEBUG_STATUS_GO_NOT_HANDLED);
DEF_PY_CONST_ULONG(DEBUG_STATUS_STEP_OVER);
DEF_PY_CONST_ULONG(DEBUG_STATUS_STEP_INTO);
DEF_PY_CONST_ULONG(DEBUG_STATUS_BREAK);
DEF_PY_CONST_ULONG(DEBUG_STATUS_NO_DEBUGGEE);
DEF_PY_CONST_ULONG(DEBUG_STATUS_STEP_BRANCH);
DEF_PY_CONST_ULONG(DEBUG_STATUS_RESTART_REQUESTED);
DEF_PY_CONST_ULONG(DEBUG_STATUS_REVERSE_GO);
DEF_PY_CONST_ULONG(DEBUG_STATUS_REVERSE_STEP_BRANCH);
DEF_PY_CONST_ULONG(DEBUG_STATUS_REVERSE_STEP_OVER);
DEF_PY_CONST_ULONG(DEBUG_STATUS_REVERSE_STEP_INTO);
}
#undef DEF_PY_CONST_ULONG
@ -601,7 +641,6 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args )
WindbgGlobalSession::RestorePyState();
ULONG mask = 0;
client->GetOutputMask( &mask );

View File

@ -180,371 +180,3 @@ Module::getTypedVarByName( const std::string &symName )
}; // end of namespace pykd
// // try reload module by entered name, "silent mode"
// OutputReader outputReader( dbgExt->client );
// hres = dbgExt->symbols->Reload( reloadParam.c_str() );
//#include <boost/format.hpp>
//
//#include "dbgext.h"
//#include "dbgmem.h"
//#include "dbgmodule.h"
//#include "dbgexcept.h"
//#include "dbgsym.h"
//#include "dbgio.h"
//#include "dbgsynsym.h"
//
///////////////////////////////////////////////////////////////////////////////////
//
//boost::python::object
//loadModule( const std::string &moduleName )
//{
// HRESULT hres;
//
// ULONG64 moduleBase;
// hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
//
// DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
// hres = dbgExt->symbols->GetModuleParameters( 1, &moduleBase, 0, &moduleParam );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
//
//
// return boost::python::object( dbgModuleClass( moduleName, moduleBase, moduleParam.Size ) );
//
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//void queryModuleParams(
// __in ULONG64 addr,
// __out std::string &name,
// __out ULONG64 &base,
// __out ULONG &size
//)
//{
// addr = addr64( addr );
//
// ULONG moduleIndex;
// HRESULT hres =
// dbgExt->symbols->GetModuleByOffset( addr, 0, &moduleIndex, &base);
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleByOffset failed" );
//
// DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
// hres = dbgExt->symbols->GetModuleParameters( 1, &base, 0, &moduleParam );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
// size = moduleParam.Size;
//
// ULONG moduleNameChars = 0;
// dbgExt->symbols->GetModuleNames(
// moduleIndex,
// 0,
// NULL,
// 0,
// NULL,
// NULL,
// 0,
// &moduleNameChars,
// NULL,
// 0,
// NULL );
// name.resize(moduleNameChars + 1);
// hres = dbgExt->symbols->GetModuleNames(
// moduleIndex,
// 0,
// NULL,
// 0,
// NULL,
// &name[0],
// (ULONG)name.size(),
// NULL,
// NULL,
// 0,
// NULL );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::GetModuleNames failed" );
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//boost::python::object
//findModule( ULONG64 addr )
//{
// ULONG64 moduleBase;
// ULONG moduleSize;
// std::string moduleName;
//
// queryModuleParams(addr, moduleName, moduleBase, moduleSize);
//
// return boost::python::object( dbgModuleClass( moduleName, moduleBase, moduleSize ) );
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//dbgModuleClass::dbgModuleClass( const std::string &name, ULONG64 base, ULONG size ) :
// m_name( name ),
// m_base( addr64(base) ),
// m_end( addr64(base) + size )
//{
// reloadSymbols();
//
// std::string pattern = name + "!*";
// ULONG64 enumHandle = 0;
//
// HRESULT hres = dbgExt->symbols->StartSymbolMatch( pattern.c_str(), &enumHandle );
//
// while( SUCCEEDED( hres ) )
// {
// char nameBuf[0x100];
// ULONG64 offset = 0;
//
// hres =
// dbgExt->symbols->GetNextSymbolMatch(
// enumHandle,
// nameBuf,
// sizeof( nameBuf ),
// NULL,
// &offset );
//
// if ( FAILED( hres ) )
// break;
//
// std::string symbolName( nameBuf );
//
// symbolName.erase( 0, name.size() + 1 );
//
// m_offsets.insert( std::make_pair( symbolName, offset ) );
// }
//
// if ( enumHandle )
// dbgExt->symbols->EndSymbolMatch( enumHandle );
//
// memset( &m_debugInfo, 0, sizeof( m_debugInfo ) );
//
// hres = dbgExt->advanced2->GetSymbolInformation(
// DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
// base,
// 0,
// &m_debugInfo,
// sizeof( m_debugInfo ),
// NULL,
// NULL,
// 0,
// NULL );
//
// if ( SUCCEEDED( hres ) )
// getImagePath();
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//void
//dbgModuleClass::reloadSymbols()
//{
// HRESULT hres;
//
// static const char *szReloadParam = "/f "; //"/f /s ";
// std::string reloadParam = szReloadParam;
// reloadParam += m_name;
//
// {
// // try reload module by entered name, "silent mode"
// OutputReader outputReader( dbgExt->client );
// hres = dbgExt->symbols->Reload( reloadParam.c_str() );
// }
// if ( FAILED( hres ) )
// {
// // failed => try reload symbols by image file name
// char szImageName[MAX_PATH/2];
// HRESULT hres2 = dbgExt->symbols2->GetModuleNameString(
// DEBUG_MODNAME_IMAGE,
// DEBUG_ANY_ID,
// m_base,
// szImageName,
// _countof(szImageName),
// NULL);
// if (SUCCEEDED(hres2))
// {
// PCSTR szImageFileName = strrchr(szImageName, '\\');
// if (!szImageFileName)
// szImageFileName = szImageName;
// else
// ++szImageFileName;
//
// reloadParam = szReloadParam;
// reloadParam += szImageFileName;
// hres = dbgExt->symbols->Reload( reloadParam.c_str() );
// }
// }
//
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol::Reload failed" );
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//ULONG64
//dbgModuleClass::getOffset( const std::string &symName )
//{
// OffsetMap::iterator offset = m_offsets.find( symName );
// if ( offset != m_offsets.end() )
// {
// return offset->second;
// }
//
// ModuleInfo moduleInfo(m_debugInfo);
// ULONG64 syntheticOffset = getSyntheticSymbol(moduleInfo, symName);
//
// if ( syntheticOffset == 0 )
// throw DbgException( "failed to find offset for symbol" );
//
// return syntheticOffset;
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//bool dbgModuleClass::addSyntheticSymbol(
// ULONG64 offset,
// ULONG size,
// const std::string &symName
//)
//{
// ModuleInfo moduleInfo(m_debugInfo);
// return ::addSyntheticSymbolForModule(offset, size, symName, moduleInfo);
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//void dbgModuleClass::delAllSyntheticSymbols()
//{
// ModuleInfo moduleInfo(m_debugInfo);
// ::delAllSyntheticSymbolsForModule(moduleInfo);
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//ULONG dbgModuleClass::delSyntheticSymbol(
// ULONG64 offset
//)
//{
// ModuleInfo moduleInfo(m_debugInfo);
// return ::delSyntheticSymbolForModule(offset, moduleInfo);
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//ULONG dbgModuleClass::delSyntheticSymbolsMask( const std::string &symName )
//{
// return ::delSyntheticSymbolsMask(m_name, symName);
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//void
//dbgModuleClass::getImagePath()
//{
// HRESULT hres;
//
// ULONG pathSize = 0;
// hres = dbgExt->symbols3->GetSymbolPathWide( NULL, 0, &pathSize );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol3::GetImagePathWide failed" );
//
// std::vector<WCHAR> pathBuffer(pathSize);
//
// hres = dbgExt->symbols3->GetSymbolPathWide( &pathBuffer[0], pathSize, NULL );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugSymbol3::GetImagePathWide failed" );
//
// std::wstring symPath( &pathBuffer[0], pathSize );
//
// std::wstring altName = m_debugInfo.CVData;
// altName = altName.substr( 0, altName.find_last_of(L".") );
//
// std::wstring imageName = m_debugInfo.LoadedImageName;
// altName += imageName.substr( imageName.find_last_of(L".") );
//
// for ( size_t offset = 0; offset < symPath.length(); )
// {
// size_t newOffset = symPath.find( L";", offset );
// std::wstring subPath = symPath.substr( offset, newOffset - offset );
//
// std::wstringstream sstr;
//
// sstr << subPath << L"\\" << m_debugInfo.LoadedImageName << L"\\" << std::hex <<
// m_debugInfo.TimeDateStamp << m_debugInfo.ImageSize << L"\\" <<
// m_debugInfo.LoadedImageName;
//
// if( (_waccess( sstr.str().c_str(), 0 )) != -1 )
// {
// m_imageFullName = sstr.str();
// break;
// }
//
//
// std::wstringstream altstr;
//
// altstr << subPath << L"\\" << altName << L"\\" << std::hex <<
// m_debugInfo.TimeDateStamp << m_debugInfo.ImageSize << L"\\" <<
// altName;
//
// if( (_waccess( altstr.str().c_str(), 0 )) != -1 )
// {
// m_imageFullName = altstr.str();
// break;
// }
//
// if ( newOffset == std::wstring::npos )
// break;
//
// offset = newOffset + 1;
// }
//}
//
//std::string
//dbgModuleClass::print() const
//{
// const char * format_string(dbgExt->control->IsPointer64Bit() == S_OK ?
// "%1$016x %2$016x %3$20s %4$20s" : "%1$08x %2$08x %3$20s %4$20s");
// boost::format fmt(format_string);
// std::vector<char> v(MAX_PATH);
// ::WideCharToMultiByte(
// CP_ACP,
// 0,
// m_imageFullName.c_str(),
// -1,
// &v[0],
// (ULONG)v.size(),
// 0,
// 0);
// std::string fullname(&v[0]);
// fmt % m_base % (m_end - m_base) % m_name % fullname;
// return fmt.str();
//}
//
///////////////////////////////////////////////////////////////////////////////////

View File

@ -2,6 +2,10 @@
#include <windows.h>
#include "windbg.h"
namespace pykd {
///////////////////////////////////////////////////////////////////////////////
class PyThreadStateSaver {
@ -17,14 +21,14 @@ public:
}
void saveState() {
if ( !isWindbgExt() )
if ( !WindbgGlobalSession::isInit() )
TlsSetValue( m_index, PyEval_SaveThread() );
else
WindbgGlobalSession::SavePyState();
}
void restoreState() {
if ( !isWindbgExt() )
if ( !WindbgGlobalSession::isInit() )
{
PyThreadState* state = (PyThreadState*)TlsGetValue( m_index );
if ( state )
@ -41,33 +45,33 @@ private:
DWORD m_index;
};
extern PyThreadStateSaver g_pyThreadState;
//typedef PyThreadState *PyThreadStatePtr;
//extern __declspec( thread ) PyThreadStatePtr ptrPyThreadState;
// --> call back
// { PyThread_StateSave state( winext->getThreadState() );
// do_callback();
// }
//
// Ĺńëč ęîëáĺę áűë âűçâŕí č ďđč ýňîě ó ňĺęůĺăî ďîňîęŕ ńîőđŕíĺí ęîíňĺęńň ( áűë âűçîâ setExecutionStatus )
// ňî ďĺđĺä âűďîëíĺíčĺě ďčňîíîâńęîăî ęîäŕ íóćíî âîńńňŕíîâčňü ęîíňĺęńň, ŕ ďîńëĺ âîçâđŕňŕ óďđŕâëĺíč˙,
// ńíîâŕ ńîőđŕíčňü ĺăî
// Ĺńëč áűë âűçâŕí ęîëáĺę ňî ďĺđĺä âűďîëíĺíčĺě ďčňîíîâńęîăî ęîäŕ íóćíî âîńńňŕíîâčňü ęîíňĺęńň,
// ŕ ďîńëĺ âîçâđŕňŕ óďđŕâëĺíč˙, ńíîâŕ ńîőđŕíčňü ĺăî
class PyThread_StateSave {
public:
PyThread_StateSave()
PyThread_StateSave( PyThreadStateSaver &threadState) :
m_threadState( threadState )
{
g_pyThreadState.restoreState();
m_threadState.restoreState();
}
~PyThread_StateSave() {
g_pyThreadState.saveState();
m_threadState.saveState();
}
private:
PyThreadStateSaver &m_threadState;
};
// { PyThread_StateRestore state;
@ -78,13 +82,20 @@ class PyThread_StateRestore
{
public:
PyThread_StateRestore() {
g_pyThreadState.saveState();
PyThread_StateRestore(PyThreadStateSaver &threadState) :
m_threadState( threadState )
{
m_threadState.saveState();
}
~PyThread_StateRestore() {
g_pyThreadState.restoreState();
m_threadState.restoreState();
}
private:
PyThreadStateSaver &m_threadState;
};
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
}; //end namespace pykd

View File

@ -495,6 +495,10 @@
RelativePath=".\module.h"
>
</File>
<File
RelativePath=".\pyaux.h"
>
</File>
<File
RelativePath=".\resource.h"
>

View File

@ -112,7 +112,10 @@ class BaseTest( unittest.TestCase ):
self.assertTrue( hasattr(pykd, 'createDbgClient') )
self.assertTrue( hasattr(pykd, 'diaLoadPdb') )
self.assertTrue( hasattr(pykd, 'getDebuggeeType' ) )
self.assertTrue( hasattr(pykd, 'getExecutionStatus' ) )
self.assertTrue( hasattr(pykd, 'loadExt') )
self.assertTrue( hasattr(pykd, 'setExecutionStatus') )
self.assertTrue( hasattr(pykd, 'waitForEvent') )
self.assertTrue( hasattr(pykd, 'DiaException') )
self.assertTrue( hasattr(pykd, 'DiaScope') )

View File

@ -16,3 +16,14 @@ class DbgClientTest( unittest.TestCase ):
def testIsDumpAnalyzing( self ):
self.assertFalse( pykd.isDumpAnalyzing() )
def testExecutionStatus( self ):
self.assertEqual( pykd.DEBUG_STATUS_BREAK, pykd.getExecutionStatus() )
pykd.setExecutionStatus( pykd.DEBUG_STATUS_GO )
pykd.waitForEvent()
self.assertEqual( pykd.DEBUG_STATUS_BREAK, pykd.getExecutionStatus() )