mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 12:24:52 +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,17 +14,24 @@ 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;
|
||||||
}
|
}
|
||||||
@ -32,11 +39,20 @@ HRESULT dbgBreakpointClass::onBreakpointEvnet( IDebugBreakpoint* bp )
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
dbgBreakpointClass::dbgBreakpointClass( ULONG64 offset)
|
||||||
|
: m_offset(offset)
|
||||||
|
, m_breakpoint(NULL)
|
||||||
|
{
|
||||||
|
// m_callback is None, see dbgBreakpointClass::onBreakpointEvnet
|
||||||
set();
|
set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ class dbgBreakpointClass {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
dbgBreakpointClass( ULONG64 offset, boost::python::object &callback );
|
dbgBreakpointClass( ULONG64 offset, boost::python::object &callback );
|
||||||
|
dbgBreakpointClass( ULONG64 offset );
|
||||||
|
|
||||||
~dbgBreakpointClass();
|
~dbgBreakpointClass();
|
||||||
|
|
||||||
|
@ -16,8 +16,11 @@ dbgCommand( const std::string &command )
|
|||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
OutputReader outReader( dbgExt->client );
|
OutputReader outReader( dbgExt->client );
|
||||||
|
{
|
||||||
|
PyThread_StateRestore pyThreadRestore;
|
||||||
|
|
||||||
hres = dbgExt->control->Execute( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 );
|
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" );
|
||||||
|
|
||||||
@ -118,7 +121,7 @@ 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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,10 +25,8 @@ setExecutionStatus()
|
|||||||
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 ) )
|
||||||
|
@ -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,6 +4,7 @@
|
|||||||
|
|
||||||
#include "dbgeventcb.h"
|
#include "dbgeventcb.h"
|
||||||
#include "dbgmodule.h"
|
#include "dbgmodule.h"
|
||||||
|
#include "pyaux.h"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -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,6 +757,9 @@ DbgExt::DbgExt( IDebugClient4 *masterClient )
|
|||||||
|
|
||||||
DbgExt::~DbgExt()
|
DbgExt::~DbgExt()
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT(dbgExt == this);
|
||||||
|
dbgExt = m_previosExt;
|
||||||
|
|
||||||
if ( client )
|
if ( client )
|
||||||
client->Release();
|
client->Release();
|
||||||
|
|
||||||
@ -794,8 +801,6 @@ DbgExt::~DbgExt()
|
|||||||
|
|
||||||
if ( system2 )
|
if ( system2 )
|
||||||
system2->Release();
|
system2->Release();
|
||||||
|
|
||||||
dbgExt = m_previosExt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -32,16 +32,9 @@ public:
|
|||||||
|
|
||||||
~DbgExt();
|
~DbgExt();
|
||||||
|
|
||||||
PyThreadState**
|
|
||||||
getThreadState() {
|
|
||||||
return &m_threadState;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
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