mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-19 19:13:22 +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 )
|
||||
{
|
||||
PyThread_StateSave pyThrdState( dbgExt->getThreadState() );
|
||||
PyThread_StateSave pyThreadSave;
|
||||
|
||||
try {
|
||||
|
||||
breakpointMap::iterator it = m_breakMap.find( bp );
|
||||
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(...)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
return DEBUG_STATUS_NO_CHANGE;
|
||||
}
|
||||
@ -32,11 +39,20 @@ HRESULT dbgBreakpointClass::onBreakpointEvnet( IDebugBreakpoint* bp )
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
dbgBreakpointClass::dbgBreakpointClass( ULONG64 offset, boost::python::object &callback )
|
||||
: m_offset(offset)
|
||||
, m_callback(callback)
|
||||
, m_breakpoint(NULL)
|
||||
{
|
||||
m_offset = offset;
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ class dbgBreakpointClass {
|
||||
public:
|
||||
|
||||
dbgBreakpointClass( ULONG64 offset, boost::python::object &callback );
|
||||
dbgBreakpointClass( ULONG64 offset );
|
||||
|
||||
~dbgBreakpointClass();
|
||||
|
||||
|
@ -16,8 +16,11 @@ dbgCommand( const std::string &command )
|
||||
HRESULT hres;
|
||||
|
||||
OutputReader outReader( dbgExt->client );
|
||||
{
|
||||
PyThread_StateRestore pyThreadRestore;
|
||||
|
||||
hres = dbgExt->control->Execute( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 );
|
||||
}
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugControl::Execute failed" );
|
||||
|
||||
@ -118,7 +121,7 @@ breakin()
|
||||
HRESULT hres;
|
||||
|
||||
{
|
||||
PyThread_StateRestore state;
|
||||
PyThread_StateRestore pyThreadRestore;
|
||||
hres = dbgExt->control->SetInterrupt( DEBUG_INTERRUPT_ACTIVE );
|
||||
}
|
||||
|
||||
|
@ -25,10 +25,8 @@ setExecutionStatus()
|
||||
do {
|
||||
|
||||
{
|
||||
PyThread_StateRestore state(dbgExt->getThreadState());
|
||||
|
||||
PyThread_StateRestore pyThreadRestore;
|
||||
hres = dbgExt->control->WaitForEvent( 0, INFINITE );
|
||||
|
||||
}
|
||||
|
||||
if ( FAILED( hres ) )
|
||||
|
@ -69,8 +69,7 @@ HRESULT debugEvent::LoadModule(
|
||||
dbgModuleClass module(moduleName, moduleBase, moduleSize);
|
||||
silentMode.reset();
|
||||
|
||||
PyThread_StateSave pyThrdState( dbgExt->getThreadState() );
|
||||
|
||||
PyThread_StateSave pyThreadSave;
|
||||
return onLoadModule( module );
|
||||
}
|
||||
|
||||
@ -91,8 +90,7 @@ HRESULT debugEvent::UnloadModule(
|
||||
dbgModuleClass module(moduleName, moduleBase, moduleSize);
|
||||
silentMode.reset();
|
||||
|
||||
PyThread_StateSave pyThrdState( dbgExt->getThreadState() );
|
||||
|
||||
PyThread_StateSave pyThreadSave;
|
||||
return onUnloadModule( module );
|
||||
}
|
||||
|
||||
@ -102,8 +100,7 @@ HRESULT debugEvent::SessionStatus(
|
||||
__in ULONG Status
|
||||
)
|
||||
{
|
||||
PyThread_StateSave pyThrdState( dbgExt->getThreadState() );
|
||||
|
||||
PyThread_StateSave pyThreadSave;
|
||||
return onChangeSessionStatus( Status );
|
||||
}
|
||||
|
||||
@ -114,8 +111,7 @@ HRESULT debugEvent::ChangeDebuggeeState(
|
||||
__in ULONG64 Argument
|
||||
)
|
||||
{
|
||||
PyThread_StateSave pyThrdState( dbgExt->getThreadState() );
|
||||
|
||||
PyThread_StateSave pyThreadSave;
|
||||
return onChangeDebugeeState();
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "dbgeventcb.h"
|
||||
#include "dbgmodule.h"
|
||||
#include "pyaux.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -38,6 +38,9 @@ DbgExt *dbgExt = NULL;
|
||||
// ãëîáàëüíûé êëèåíò
|
||||
dbgClient g_dbgClient;
|
||||
|
||||
// êîíòåñêò èñïîëíåíèÿ íèòè ïèòîíà
|
||||
__declspec( thread ) PyThreadStatePtr ptrPyThreadState = NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( dprint, dbgPrint::dprint, 1, 2 )
|
||||
@ -340,7 +343,9 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
boost::python::class_<dbgBreakpointClass>( "bp",
|
||||
"Class representing breakpoint",
|
||||
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,
|
||||
"Set a breakpoint at the specified address" )
|
||||
.def( "remove", &dbgBreakpointClass::remove,
|
||||
@ -703,7 +708,6 @@ DebugExtensionUninitialize()
|
||||
}
|
||||
|
||||
DbgExt::DbgExt( IDebugClient4 *masterClient )
|
||||
: m_threadState(NULL)
|
||||
{
|
||||
client = NULL;
|
||||
masterClient->QueryInterface( __uuidof(IDebugClient), (void **)&client );
|
||||
@ -753,6 +757,9 @@ DbgExt::DbgExt( IDebugClient4 *masterClient )
|
||||
|
||||
DbgExt::~DbgExt()
|
||||
{
|
||||
BOOST_ASSERT(dbgExt == this);
|
||||
dbgExt = m_previosExt;
|
||||
|
||||
if ( client )
|
||||
client->Release();
|
||||
|
||||
@ -794,8 +801,6 @@ DbgExt::~DbgExt()
|
||||
|
||||
if ( system2 )
|
||||
system2->Release();
|
||||
|
||||
dbgExt = m_previosExt;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -32,16 +32,9 @@ public:
|
||||
|
||||
~DbgExt();
|
||||
|
||||
PyThreadState**
|
||||
getThreadState() {
|
||||
return &m_threadState;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
DbgExt *m_previosExt;
|
||||
|
||||
PyThreadState *m_threadState;
|
||||
};
|
||||
|
||||
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
|
||||
// { PyThread_StateSave state( winext->getThreadState() );
|
||||
// do_callback();
|
||||
@ -15,58 +18,40 @@ class PyThread_StateSave {
|
||||
|
||||
public:
|
||||
|
||||
PyThread_StateSave( PyThreadState **state )
|
||||
: m_state(NULL)
|
||||
PyThread_StateSave()
|
||||
: m_bRestored(false)
|
||||
{
|
||||
if ( *state )
|
||||
if (ptrPyThreadState)
|
||||
{
|
||||
m_state = state;
|
||||
PyEval_RestoreThread( *m_state );
|
||||
PyEval_RestoreThread( ptrPyThreadState );
|
||||
m_bRestored = true;
|
||||
}
|
||||
}
|
||||
|
||||
~PyThread_StateSave() {
|
||||
if ( m_state )
|
||||
*m_state =PyEval_SaveThread();
|
||||
if ( m_bRestored )
|
||||
ptrPyThreadState = PyEval_SaveThread();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
PyThreadState **m_state;
|
||||
bool m_bRestored;
|
||||
};
|
||||
|
||||
// { PyThread_StateRestore state;
|
||||
// long_or_block_opreration();
|
||||
// }
|
||||
|
||||
class PyThread_StateRestore {
|
||||
|
||||
class PyThread_StateRestore
|
||||
{
|
||||
public:
|
||||
|
||||
explicit PyThread_StateRestore() {
|
||||
m_state = &m_ownState;
|
||||
*m_state =PyEval_SaveThread();
|
||||
}
|
||||
|
||||
PyThread_StateRestore( PyThreadState **state ) {
|
||||
if ( *state )
|
||||
{
|
||||
m_state = state;
|
||||
*m_state =PyEval_SaveThread();
|
||||
}
|
||||
PyThread_StateRestore() {
|
||||
ptrPyThreadState = PyEval_SaveThread();
|
||||
}
|
||||
|
||||
~PyThread_StateRestore() {
|
||||
if (*m_state)
|
||||
PyEval_RestoreThread( *m_state );
|
||||
PyEval_RestoreThread( ptrPyThreadState );
|
||||
}
|
||||
|
||||
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