[~] 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:
SND\EreTIk_cp 2011-09-02 07:48:53 +00:00
parent 105ba17ade
commit 5ac233a473
10 changed files with 205 additions and 173 deletions

View File

@ -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();
} }

View File

@ -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();

View File

@ -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 );
} }

View File

@ -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 ) )

View File

@ -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();
} }

View File

@ -4,6 +4,7 @@
#include "dbgeventcb.h" #include "dbgeventcb.h"
#include "dbgmodule.h" #include "dbgmodule.h"
#include "pyaux.h"
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////

View File

@ -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;
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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
View 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")