[~] 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 )
{
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();
}

View File

@ -10,6 +10,7 @@ class dbgBreakpointClass {
public:
dbgBreakpointClass( ULONG64 offset, boost::python::object &callback );
dbgBreakpointClass( ULONG64 offset );
~dbgBreakpointClass();

View File

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

View File

@ -25,10 +25,8 @@ setExecutionStatus()
do {
{
PyThread_StateRestore state(dbgExt->getThreadState());
PyThread_StateRestore pyThreadRestore;
hres = dbgExt->control->WaitForEvent( 0, INFINITE );
}
if ( FAILED( hres ) )

View File

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

View File

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

View File

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

View File

@ -32,16 +32,9 @@ public:
~DbgExt();
PyThreadState**
getThreadState() {
return &m_threadState;
}
private:
DbgExt *m_previosExt;
PyThreadState *m_threadState;
};
extern DbgExt *dbgExt;

View File

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