mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-05-13 22:23:24 +08:00
[~] python thread state moved from dbgExt to TLS
[+] bp without callback - always break when triggered, goLib - demo for this case [+] python thread restore for dbgCommand [~] remove trailing blanks git-svn-id: https://pykd.svn.codeplex.com/svn@69510 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
105ba17ade
commit
5ac233a473
@ -14,34 +14,50 @@ dbgBreakpointClass::breakpointMap dbgBreakpointClass::m_breakMap;
|
|||||||
|
|
||||||
HRESULT dbgBreakpointClass::onBreakpointEvnet( IDebugBreakpoint* bp )
|
HRESULT dbgBreakpointClass::onBreakpointEvnet( IDebugBreakpoint* bp )
|
||||||
{
|
{
|
||||||
PyThread_StateSave pyThrdState( dbgExt->getThreadState() );
|
PyThread_StateSave pyThreadSave;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
breakpointMap::iterator it = m_breakMap.find( bp );
|
breakpointMap::iterator it = m_breakMap.find( bp );
|
||||||
if ( it != m_breakMap.end() )
|
if ( it != m_breakMap.end() )
|
||||||
return boost::python::extract<HRESULT>( it->second->m_callback() );
|
{
|
||||||
|
boost::python::object &callback = it->second->m_callback;
|
||||||
|
if (!callback.is_none())
|
||||||
|
return boost::python::extract<HRESULT>( callback() );
|
||||||
|
|
||||||
|
return DEBUG_STATUS_BREAK;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
return DEBUG_STATUS_NO_CHANGE;
|
|
||||||
|
return DEBUG_STATUS_NO_CHANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
dbgBreakpointClass::dbgBreakpointClass( ULONG64 offset, boost::python::object &callback )
|
dbgBreakpointClass::dbgBreakpointClass( ULONG64 offset, boost::python::object &callback )
|
||||||
|
: m_offset(offset)
|
||||||
|
, m_callback(callback)
|
||||||
|
, m_breakpoint(NULL)
|
||||||
{
|
{
|
||||||
m_offset = offset;
|
set();
|
||||||
m_breakpoint = NULL;
|
|
||||||
m_callback = callback;
|
|
||||||
|
|
||||||
set();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
dbgBreakpointClass::dbgBreakpointClass( ULONG64 offset)
|
||||||
|
: m_offset(offset)
|
||||||
|
, m_breakpoint(NULL)
|
||||||
|
{
|
||||||
|
// m_callback is None, see dbgBreakpointClass::onBreakpointEvnet
|
||||||
|
set();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
dbgBreakpointClass::~dbgBreakpointClass()
|
dbgBreakpointClass::~dbgBreakpointClass()
|
||||||
{
|
{
|
||||||
remove();
|
remove();
|
||||||
@ -53,44 +69,44 @@ bool
|
|||||||
dbgBreakpointClass::set()
|
dbgBreakpointClass::set()
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if ( m_breakpoint )
|
if ( m_breakpoint )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
hres = dbgExt->control->AddBreakpoint( DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &m_breakpoint );
|
hres = dbgExt->control->AddBreakpoint( DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &m_breakpoint );
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugControl::AddBreakpoint failed" );
|
throw DbgException( "IDebugControl::AddBreakpoint failed" );
|
||||||
|
|
||||||
hres = m_breakpoint->SetOffset( m_offset );
|
hres = m_breakpoint->SetOffset( m_offset );
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugBreakpoint::SetOffset failed" );
|
throw DbgException( "IDebugBreakpoint::SetOffset failed" );
|
||||||
|
|
||||||
hres = m_breakpoint->SetFlags( DEBUG_BREAKPOINT_ENABLED );
|
hres = m_breakpoint->SetFlags( DEBUG_BREAKPOINT_ENABLED );
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugBreakpoint::SetFlags failed" );
|
throw DbgException( "IDebugBreakpoint::SetFlags failed" );
|
||||||
|
|
||||||
m_breakMap.insert( std::make_pair( m_breakpoint, this ) );
|
m_breakMap.insert( std::make_pair( m_breakpoint, this ) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch( std::exception &e )
|
catch( std::exception &e )
|
||||||
{
|
{
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
remove();
|
remove();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void
|
void
|
||||||
dbgBreakpointClass::remove()
|
dbgBreakpointClass::remove()
|
||||||
{
|
{
|
||||||
@ -111,36 +127,36 @@ dbgBreakpointClass::remove()
|
|||||||
std::string
|
std::string
|
||||||
dbgBreakpointClass::print() const
|
dbgBreakpointClass::print() const
|
||||||
{
|
{
|
||||||
HRESULT status = S_OK;
|
HRESULT status = S_OK;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!m_breakpoint)
|
if (!m_breakpoint)
|
||||||
return "not set";
|
return "not set";
|
||||||
|
|
||||||
DEBUG_BREAKPOINT_PARAMETERS params;
|
DEBUG_BREAKPOINT_PARAMETERS params;
|
||||||
status = m_breakpoint->GetParameters(¶ms);
|
status = m_breakpoint->GetParameters(¶ms);
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
throw DbgException("IDebugBreakpoint::GetParameters failed");
|
throw DbgException("IDebugBreakpoint::GetParameters failed");
|
||||||
|
|
||||||
boost::format fmt("%1$2d %2%%3% %4%:*** ");
|
boost::format fmt("%1$2d %2%%3% %4%:*** ");
|
||||||
fmt % params.Id
|
fmt % params.Id
|
||||||
% (params.Flags & DEBUG_BREAKPOINT_ENABLED ? 'e' : 'd')
|
% (params.Flags & DEBUG_BREAKPOINT_ENABLED ? 'e' : 'd')
|
||||||
% 'u'
|
% 'u'
|
||||||
% params.CurrentPassCount;
|
% params.CurrentPassCount;
|
||||||
|
|
||||||
return fmt.str();
|
return fmt.str();
|
||||||
}
|
}
|
||||||
catch (std::exception & e)
|
catch (std::exception & e)
|
||||||
{
|
{
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
@ -10,12 +10,13 @@ class dbgBreakpointClass {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
dbgBreakpointClass( ULONG64 offset, boost::python::object &callback );
|
dbgBreakpointClass( ULONG64 offset, boost::python::object &callback );
|
||||||
|
dbgBreakpointClass( ULONG64 offset );
|
||||||
|
|
||||||
~dbgBreakpointClass();
|
~dbgBreakpointClass();
|
||||||
|
|
||||||
bool
|
bool
|
||||||
set();
|
set();
|
||||||
|
|
||||||
void
|
void
|
||||||
remove();
|
remove();
|
||||||
|
|
||||||
|
@ -16,13 +16,16 @@ dbgCommand( const std::string &command )
|
|||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
OutputReader outReader( dbgExt->client );
|
OutputReader outReader( dbgExt->client );
|
||||||
|
{
|
||||||
hres = dbgExt->control->Execute( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 );
|
PyThread_StateRestore pyThreadRestore;
|
||||||
|
|
||||||
|
hres = dbgExt->control->Execute( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 );
|
||||||
|
}
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugControl::Execute failed" );
|
throw DbgException( "IDebugControl::Execute failed" );
|
||||||
|
|
||||||
return std::string( outReader.Line() );
|
return std::string( outReader.Line() );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -87,7 +90,7 @@ evaluate( const std::string &expression )
|
|||||||
&remainderIndex );
|
&remainderIndex );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugControl::Evaluate failed" );
|
throw DbgException( "IDebugControl::Evaluate failed" );
|
||||||
|
|
||||||
if ( remainderIndex == expression.length() )
|
if ( remainderIndex == expression.length() )
|
||||||
value = debugValue.I64;
|
value = debugValue.I64;
|
||||||
@ -101,7 +104,7 @@ evaluate( const std::string &expression )
|
|||||||
&remainderIndex );
|
&remainderIndex );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugControl::Evaluate failed" );
|
throw DbgException( "IDebugControl::Evaluate failed" );
|
||||||
|
|
||||||
if ( remainderIndex == expression.length() )
|
if ( remainderIndex == expression.length() )
|
||||||
value = debugValue.I32;
|
value = debugValue.I32;
|
||||||
@ -118,12 +121,12 @@ breakin()
|
|||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
{
|
{
|
||||||
PyThread_StateRestore state;
|
PyThread_StateRestore pyThreadRestore;
|
||||||
hres = dbgExt->control->SetInterrupt( DEBUG_INTERRUPT_ACTIVE );
|
hres = dbgExt->control->SetInterrupt( DEBUG_INTERRUPT_ACTIVE );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugControl::SetInterrupt" );
|
throw DbgException( "IDebugControl::SetInterrupt" );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
@ -16,29 +16,27 @@ setExecutionStatus()
|
|||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
hres = dbgExt->control->SetExecutionStatus( status );
|
hres = dbgExt->control->SetExecutionStatus( status );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugControl::SetExecutionStatus failed" );
|
throw DbgException( "IDebugControl::SetExecutionStatus failed" );
|
||||||
|
|
||||||
ULONG currentStatus;
|
ULONG currentStatus;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
{
|
{
|
||||||
PyThread_StateRestore state(dbgExt->getThreadState());
|
PyThread_StateRestore pyThreadRestore;
|
||||||
|
|
||||||
hres = dbgExt->control->WaitForEvent( 0, INFINITE );
|
hres = dbgExt->control->WaitForEvent( 0, INFINITE );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
||||||
|
|
||||||
hres = dbgExt->control->GetExecutionStatus( ¤tStatus );
|
hres = dbgExt->control->GetExecutionStatus( ¤tStatus );
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
if ( FAILED( hres ) )
|
||||||
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
|
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
|
||||||
|
|
||||||
} while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
|
} while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,10 +41,10 @@ HRESULT debugEvent::GetInterestMask(
|
|||||||
*Mask = 0;
|
*Mask = 0;
|
||||||
|
|
||||||
*Mask |= DEBUG_EVENT_LOAD_MODULE;
|
*Mask |= DEBUG_EVENT_LOAD_MODULE;
|
||||||
*Mask |= DEBUG_EVENT_UNLOAD_MODULE;
|
*Mask |= DEBUG_EVENT_UNLOAD_MODULE;
|
||||||
*Mask |= DEBUG_EVENT_SESSION_STATUS;
|
*Mask |= DEBUG_EVENT_SESSION_STATUS;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -69,8 +69,7 @@ HRESULT debugEvent::LoadModule(
|
|||||||
dbgModuleClass module(moduleName, moduleBase, moduleSize);
|
dbgModuleClass module(moduleName, moduleBase, moduleSize);
|
||||||
silentMode.reset();
|
silentMode.reset();
|
||||||
|
|
||||||
PyThread_StateSave pyThrdState( dbgExt->getThreadState() );
|
PyThread_StateSave pyThreadSave;
|
||||||
|
|
||||||
return onLoadModule( module );
|
return onLoadModule( module );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,8 +90,7 @@ HRESULT debugEvent::UnloadModule(
|
|||||||
dbgModuleClass module(moduleName, moduleBase, moduleSize);
|
dbgModuleClass module(moduleName, moduleBase, moduleSize);
|
||||||
silentMode.reset();
|
silentMode.reset();
|
||||||
|
|
||||||
PyThread_StateSave pyThrdState( dbgExt->getThreadState() );
|
PyThread_StateSave pyThreadSave;
|
||||||
|
|
||||||
return onUnloadModule( module );
|
return onUnloadModule( module );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,8 +100,7 @@ HRESULT debugEvent::SessionStatus(
|
|||||||
__in ULONG Status
|
__in ULONG Status
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PyThread_StateSave pyThrdState( dbgExt->getThreadState() );
|
PyThread_StateSave pyThreadSave;
|
||||||
|
|
||||||
return onChangeSessionStatus( Status );
|
return onChangeSessionStatus( Status );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +111,7 @@ HRESULT debugEvent::ChangeDebuggeeState(
|
|||||||
__in ULONG64 Argument
|
__in ULONG64 Argument
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PyThread_StateSave pyThrdState( dbgExt->getThreadState() );
|
PyThread_StateSave pyThreadSave;
|
||||||
|
|
||||||
return onChangeDebugeeState();
|
return onChangeDebugeeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,15 +4,16 @@
|
|||||||
|
|
||||||
#include "dbgeventcb.h"
|
#include "dbgeventcb.h"
|
||||||
#include "dbgmodule.h"
|
#include "dbgmodule.h"
|
||||||
|
#include "pyaux.h"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class debugEvent : public DebugBaseEventCallbacks
|
class debugEvent : public DebugBaseEventCallbacks
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
debugEvent();
|
debugEvent();
|
||||||
|
|
||||||
virtual ~debugEvent();
|
virtual ~debugEvent();
|
||||||
|
|
||||||
virtual ULONG onLoadModule(const dbgModuleClass &/* module */) = 0;
|
virtual ULONG onLoadModule(const dbgModuleClass &/* module */) = 0;
|
||||||
@ -30,8 +31,8 @@ private:
|
|||||||
|
|
||||||
STDMETHOD(GetInterestMask)(
|
STDMETHOD(GetInterestMask)(
|
||||||
__out PULONG Mask
|
__out PULONG Mask
|
||||||
);
|
);
|
||||||
|
|
||||||
STDMETHOD(LoadModule)(
|
STDMETHOD(LoadModule)(
|
||||||
__in ULONG64 ImageFileHandle,
|
__in ULONG64 ImageFileHandle,
|
||||||
__in ULONG64 BaseOffset,
|
__in ULONG64 BaseOffset,
|
||||||
@ -46,18 +47,18 @@ private:
|
|||||||
__in PCSTR ImageBaseName,
|
__in PCSTR ImageBaseName,
|
||||||
__in ULONG64 BaseOffset
|
__in ULONG64 BaseOffset
|
||||||
);
|
);
|
||||||
|
|
||||||
STDMETHOD(SessionStatus)(
|
STDMETHOD(SessionStatus)(
|
||||||
__in ULONG Status
|
__in ULONG Status
|
||||||
);
|
);
|
||||||
|
|
||||||
STDMETHOD(ChangeDebuggeeState)(
|
STDMETHOD(ChangeDebuggeeState)(
|
||||||
__in ULONG Flags,
|
__in ULONG Flags,
|
||||||
__in ULONG64 Argument );
|
__in ULONG64 Argument );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
IDebugClient *m_debugClient;
|
IDebugClient *m_debugClient;
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -65,9 +66,9 @@ private:
|
|||||||
class debugEventWrap : public boost::python::wrapper<debugEvent>, public debugEvent
|
class debugEventWrap : public boost::python::wrapper<debugEvent>, public debugEvent
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
ULONG onLoadModule(const dbgModuleClass &module) {
|
ULONG onLoadModule(const dbgModuleClass &module) {
|
||||||
return handler<const dbgModuleClass &>("onLoadModule", module );
|
return handler<const dbgModuleClass &>("onLoadModule", module );
|
||||||
}
|
}
|
||||||
@ -75,33 +76,33 @@ public:
|
|||||||
ULONG onUnloadModule(const dbgModuleClass &module) {
|
ULONG onUnloadModule(const dbgModuleClass &module) {
|
||||||
return handler<const dbgModuleClass &>("onUnloadModule", module );
|
return handler<const dbgModuleClass &>("onUnloadModule", module );
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG onChangeSessionStatus( ULONG status ) {
|
ULONG onChangeSessionStatus( ULONG status ) {
|
||||||
return handler( "onChangeSessionStatus", status );
|
return handler( "onChangeSessionStatus", status );
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG onChangeDebugeeState() {
|
ULONG onChangeDebugeeState() {
|
||||||
return handler( "onChangeDebugeeState" );
|
return handler( "onChangeDebugeeState" );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template<typename Arg1Type>
|
template<typename Arg1Type>
|
||||||
ULONG handler( const char* handlerName, Arg1Type arg1 )
|
ULONG handler( const char* handlerName, Arg1Type arg1 )
|
||||||
{
|
{
|
||||||
if (boost::python::override pythonHandler = get_override( handlerName ))
|
if (boost::python::override pythonHandler = get_override( handlerName ))
|
||||||
return pythonHandler(arg1);
|
return pythonHandler(arg1);
|
||||||
|
|
||||||
return DEBUG_STATUS_NO_CHANGE;
|
return DEBUG_STATUS_NO_CHANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG handler( const char* handlerName )
|
ULONG handler( const char* handlerName )
|
||||||
{
|
{
|
||||||
if (boost::python::override pythonHandler = get_override( handlerName ))
|
if (boost::python::override pythonHandler = get_override( handlerName ))
|
||||||
return pythonHandler();
|
return pythonHandler();
|
||||||
|
|
||||||
return DEBUG_STATUS_NO_CHANGE;
|
return DEBUG_STATUS_NO_CHANGE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -38,6 +38,9 @@ DbgExt *dbgExt = NULL;
|
|||||||
// ãëîáàëüíûé êëèåíò
|
// ãëîáàëüíûé êëèåíò
|
||||||
dbgClient g_dbgClient;
|
dbgClient g_dbgClient;
|
||||||
|
|
||||||
|
// êîíòåñêò èñïîëíåíèÿ íèòè ïèòîíà
|
||||||
|
__declspec( thread ) PyThreadStatePtr ptrPyThreadState = NULL;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
BOOST_PYTHON_FUNCTION_OVERLOADS( dprint, dbgPrint::dprint, 1, 2 )
|
BOOST_PYTHON_FUNCTION_OVERLOADS( dprint, dbgPrint::dprint, 1, 2 )
|
||||||
@ -340,7 +343,9 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
boost::python::class_<dbgBreakpointClass>( "bp",
|
boost::python::class_<dbgBreakpointClass>( "bp",
|
||||||
"Class representing breakpoint",
|
"Class representing breakpoint",
|
||||||
boost::python::init<ULONG64,boost::python::object&>( boost::python::args("offset", "callback"),
|
boost::python::init<ULONG64,boost::python::object&>( boost::python::args("offset", "callback"),
|
||||||
"dbgBreakpointClass constructor" ) )
|
"Break point: user callback" ) )
|
||||||
|
.def( boost::python::init< ULONG64 >( boost::python::args("offset"),
|
||||||
|
"Break point constructor: always break" ) )
|
||||||
.def( "set", &dbgBreakpointClass::set,
|
.def( "set", &dbgBreakpointClass::set,
|
||||||
"Set a breakpoint at the specified address" )
|
"Set a breakpoint at the specified address" )
|
||||||
.def( "remove", &dbgBreakpointClass::remove,
|
.def( "remove", &dbgBreakpointClass::remove,
|
||||||
@ -703,7 +708,6 @@ DebugExtensionUninitialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
DbgExt::DbgExt( IDebugClient4 *masterClient )
|
DbgExt::DbgExt( IDebugClient4 *masterClient )
|
||||||
: m_threadState(NULL)
|
|
||||||
{
|
{
|
||||||
client = NULL;
|
client = NULL;
|
||||||
masterClient->QueryInterface( __uuidof(IDebugClient), (void **)&client );
|
masterClient->QueryInterface( __uuidof(IDebugClient), (void **)&client );
|
||||||
@ -753,21 +757,24 @@ DbgExt::DbgExt( IDebugClient4 *masterClient )
|
|||||||
|
|
||||||
DbgExt::~DbgExt()
|
DbgExt::~DbgExt()
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT(dbgExt == this);
|
||||||
|
dbgExt = m_previosExt;
|
||||||
|
|
||||||
if ( client )
|
if ( client )
|
||||||
client->Release();
|
client->Release();
|
||||||
|
|
||||||
if ( client4 )
|
if ( client4 )
|
||||||
client4->Release();
|
client4->Release();
|
||||||
|
|
||||||
if ( client5 )
|
if ( client5 )
|
||||||
client5->Release();
|
client5->Release();
|
||||||
|
|
||||||
if ( control )
|
if ( control )
|
||||||
control->Release();
|
control->Release();
|
||||||
|
|
||||||
if ( control4 )
|
if ( control4 )
|
||||||
control4->Release();
|
control4->Release();
|
||||||
|
|
||||||
if ( registers )
|
if ( registers )
|
||||||
registers->Release();
|
registers->Release();
|
||||||
|
|
||||||
@ -776,26 +783,24 @@ DbgExt::~DbgExt()
|
|||||||
|
|
||||||
if ( symbols2 )
|
if ( symbols2 )
|
||||||
symbols2->Release();
|
symbols2->Release();
|
||||||
|
|
||||||
if ( symbols3 )
|
if ( symbols3 )
|
||||||
symbols3->Release();
|
symbols3->Release();
|
||||||
|
|
||||||
if ( dataSpaces )
|
if ( dataSpaces )
|
||||||
dataSpaces->Release();
|
dataSpaces->Release();
|
||||||
|
|
||||||
if ( dataSpaces4 )
|
if ( dataSpaces4 )
|
||||||
dataSpaces4->Release();
|
dataSpaces4->Release();
|
||||||
|
|
||||||
if ( advanced2 )
|
if ( advanced2 )
|
||||||
advanced2->Release();
|
advanced2->Release();
|
||||||
|
|
||||||
if ( system )
|
if ( system )
|
||||||
system->Release();
|
system->Release();
|
||||||
|
|
||||||
if ( system2 )
|
if ( system2 )
|
||||||
system2->Release();
|
system2->Release();
|
||||||
|
|
||||||
dbgExt = m_previosExt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -32,16 +32,9 @@ public:
|
|||||||
|
|
||||||
~DbgExt();
|
~DbgExt();
|
||||||
|
|
||||||
PyThreadState**
|
private:
|
||||||
getThreadState() {
|
|
||||||
return &m_threadState;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
DbgExt *m_previosExt;
|
DbgExt *m_previosExt;
|
||||||
|
|
||||||
PyThreadState *m_threadState;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern DbgExt *dbgExt;
|
extern DbgExt *dbgExt;
|
||||||
|
47
pykd/pyaux.h
47
pykd/pyaux.h
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef PyThreadState *PyThreadStatePtr;
|
||||||
|
extern __declspec( thread ) PyThreadStatePtr ptrPyThreadState;
|
||||||
|
|
||||||
// --> call back
|
// --> call back
|
||||||
// { PyThread_StateSave state( winext->getThreadState() );
|
// { PyThread_StateSave state( winext->getThreadState() );
|
||||||
// do_callback();
|
// do_callback();
|
||||||
@ -15,58 +18,40 @@ class PyThread_StateSave {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PyThread_StateSave( PyThreadState **state )
|
PyThread_StateSave()
|
||||||
: m_state(NULL)
|
: m_bRestored(false)
|
||||||
{
|
{
|
||||||
if ( *state )
|
if (ptrPyThreadState)
|
||||||
{
|
{
|
||||||
m_state = state;
|
PyEval_RestoreThread( ptrPyThreadState );
|
||||||
PyEval_RestoreThread( *m_state );
|
m_bRestored = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~PyThread_StateSave() {
|
~PyThread_StateSave() {
|
||||||
if ( m_state )
|
if ( m_bRestored )
|
||||||
*m_state =PyEval_SaveThread();
|
ptrPyThreadState = PyEval_SaveThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_bRestored;
|
||||||
PyThreadState **m_state;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// { PyThread_StateRestore state;
|
// { PyThread_StateRestore state;
|
||||||
// long_or_block_opreration();
|
// long_or_block_opreration();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
class PyThread_StateRestore {
|
class PyThread_StateRestore
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit PyThread_StateRestore() {
|
PyThread_StateRestore() {
|
||||||
m_state = &m_ownState;
|
ptrPyThreadState = PyEval_SaveThread();
|
||||||
*m_state =PyEval_SaveThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
PyThread_StateRestore( PyThreadState **state ) {
|
|
||||||
if ( *state )
|
|
||||||
{
|
|
||||||
m_state = state;
|
|
||||||
*m_state =PyEval_SaveThread();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~PyThread_StateRestore() {
|
~PyThread_StateRestore() {
|
||||||
if (*m_state)
|
PyEval_RestoreThread( ptrPyThreadState );
|
||||||
PyEval_RestoreThread( *m_state );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
PyThreadState **m_state;
|
|
||||||
|
|
||||||
PyThreadState *m_ownState;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
34
samples/goLib.py
Normal file
34
samples/goLib.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
"""
|
||||||
|
Using bp class without callback
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pykd import *
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
if not isKernelDebugging():
|
||||||
|
|
||||||
|
if not isWindbgExt():
|
||||||
|
startProcess("calc.exe")
|
||||||
|
|
||||||
|
kernel32 = loadModule("kernel32")
|
||||||
|
|
||||||
|
bpA = bp( kernel32.LoadLibraryA )
|
||||||
|
bpW = bp( kernel32.LoadLibraryW )
|
||||||
|
|
||||||
|
go()
|
||||||
|
dbgCommand("gu")
|
||||||
|
|
||||||
|
dprintln( dbgCommand("!dlls @$retreg") )
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
dprintln("Script for user mode only")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user