mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[pykd] added : callback for bp class ( breakpoint )
[pykd] changed: refactored callbacks engine git-svn-id: https://pykd.svn.codeplex.com/svn@63638 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
a820ed3fdd
commit
60599dcfb6
@ -122,14 +122,32 @@ dbgExtensionClass::print() const
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
dbgBreakpointClass::breakpointMap dbgBreakpointClass::m_breakMap;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
dbgBreakpointClass::dbgBreakpointClass( ULONG64 offset )
|
||||
HRESULT dbgBreakpointClass::onBreakpointEvnet( IDebugBreakpoint* bp )
|
||||
{
|
||||
try {
|
||||
|
||||
breakpointMap::iterator it = m_breakMap.find( bp );
|
||||
if ( it != m_breakMap.end() )
|
||||
return boost::python::extract<HRESULT>( it->second->m_callback() );
|
||||
|
||||
}
|
||||
catch(...)
|
||||
{}
|
||||
|
||||
return DEBUG_STATUS_NO_CHANGE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
dbgBreakpointClass::dbgBreakpointClass( ULONG64 offset, boost::python::object &callback )
|
||||
{
|
||||
m_offset = offset;
|
||||
m_breakpoint = NULL;
|
||||
m_callback = callback;
|
||||
|
||||
set();
|
||||
}
|
||||
@ -163,7 +181,9 @@ dbgBreakpointClass::set()
|
||||
|
||||
hres = m_breakpoint->SetFlags( DEBUG_BREAKPOINT_ENABLED );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugBreakpoint::SetFlags failed" );
|
||||
throw DbgException( "IDebugBreakpoint::SetFlags failed" );
|
||||
|
||||
m_breakMap.insert( std::make_pair( m_breakpoint, this ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -189,6 +209,11 @@ dbgBreakpointClass::remove()
|
||||
if ( m_breakpoint )
|
||||
{
|
||||
dbgExt->control->RemoveBreakpoint( m_breakpoint );
|
||||
|
||||
breakpointMap::iterator bp = m_breakMap.find( m_breakpoint );
|
||||
if ( bp != m_breakMap.end() )
|
||||
m_breakMap.erase( bp );
|
||||
|
||||
m_breakpoint = NULL;
|
||||
}
|
||||
}
|
||||
@ -284,4 +309,5 @@ evaluate( const std::string &expression )
|
||||
return value;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -76,12 +77,11 @@ private:
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class dbgBreakpointClass {
|
||||
|
||||
public:
|
||||
|
||||
dbgBreakpointClass( ULONG64 offset );
|
||||
dbgBreakpointClass( ULONG64 offset, boost::python::object &callback );
|
||||
|
||||
~dbgBreakpointClass();
|
||||
|
||||
@ -99,7 +99,18 @@ private:
|
||||
ULONG64 m_offset;
|
||||
|
||||
IDebugBreakpoint *m_breakpoint;
|
||||
|
||||
boost::python::object m_callback;
|
||||
|
||||
private:
|
||||
|
||||
typedef std::map<IDebugBreakpoint*, dbgBreakpointClass*> breakpointMap;
|
||||
static breakpointMap m_breakMap;
|
||||
|
||||
public:
|
||||
|
||||
static HRESULT onBreakpointEvnet( IDebugBreakpoint* bp );
|
||||
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "dbgsystem.h"
|
||||
#include "dbgcmd.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool
|
||||
@ -18,9 +19,17 @@ dbgLoadDump( const std::wstring &fileName )
|
||||
HRESULT hres;
|
||||
|
||||
try {
|
||||
|
||||
if ( !dbgSessionStarted )
|
||||
dbgCreateSession();
|
||||
|
||||
if ( dbgExt )
|
||||
return false;
|
||||
|
||||
IDebugClient4 *client = NULL;
|
||||
hres = DebugCreate( __uuidof(IDebugClient4), (void **)&client );
|
||||
if ( FAILED( hres ) )
|
||||
return false;
|
||||
|
||||
dbgExt = new DbgExt( client );
|
||||
new DbgEventCallbacksManager( (IDebugClient*)client );
|
||||
|
||||
hres = dbgExt->client4->OpenDumpFileWide( fileName.c_str(), NULL );
|
||||
|
||||
@ -53,8 +62,16 @@ startProcess( const std::wstring &processName )
|
||||
|
||||
try {
|
||||
|
||||
if ( !dbgSessionStarted )
|
||||
dbgCreateSession();
|
||||
if ( dbgExt )
|
||||
return false;
|
||||
|
||||
IDebugClient4 *client = NULL;
|
||||
hres = DebugCreate( __uuidof(IDebugClient4), (void **)&client );
|
||||
if ( FAILED( hres ) )
|
||||
return false;
|
||||
|
||||
dbgExt = new DbgExt( client );
|
||||
new DbgEventCallbacksManager( (IDebugClient*)client );
|
||||
|
||||
ULONG opt;
|
||||
hres = dbgExt->control->GetEngineOptions( &opt );
|
||||
|
@ -1,202 +1,120 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "dbgeng.h"
|
||||
#include "dbgext.h"
|
||||
#include "dbgmem.h"
|
||||
#include "dbgmodule.h"
|
||||
#include "dbgexcept.h"
|
||||
#include "dbgsynsym.h"
|
||||
#include "dbgeventcb.h"
|
||||
#include "dbgexcept.h"
|
||||
#include "dbgmodule.h"
|
||||
#include "dbgsynsym.h"
|
||||
#include "dbgcmd.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DbgEventCallbacks *DbgEventCallbacks::dbgEventCallbacks = NULL;
|
||||
volatile LONG DbgEventCallbacks::dbgEventCallbacksStartCount = 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT DbgEventCallbacks::Start()
|
||||
DbgEventCallbacksManager::DbgEventCallbacksManager( IDebugClient *client )
|
||||
{
|
||||
HRESULT hres;
|
||||
try
|
||||
{
|
||||
if (1 == InterlockedIncrement(&dbgEventCallbacksStartCount))
|
||||
HRESULT hres;
|
||||
|
||||
m_debugClient = NULL;
|
||||
|
||||
try {
|
||||
|
||||
if ( client == NULL )
|
||||
{
|
||||
_ASSERT(!dbgEventCallbacks);
|
||||
dbgEventCallbacks = new DbgEventCallbacks;
|
||||
// ñëó÷àé, êîãäà ìû ðàáîòàåì â windbg. Ìû íå õîòèì ìåíÿòü ïîâåäåíèå êëèåíòà îòëàä÷èêà - îí
|
||||
// äîëæåí ïðîäîëæàòü îáðàáîòêó ñîáûòèé, ïîýòîìó ìû ñîçäàåì ñâîåãî êëèåíòà
|
||||
hres = DebugCreate( __uuidof(IDebugClient4), reinterpret_cast<PVOID*>(&m_debugClient));
|
||||
if (FAILED(hres))
|
||||
throw DbgException( "DebugCreate failed" );
|
||||
}
|
||||
hres = S_OK;
|
||||
}
|
||||
catch (HRESULT _hres)
|
||||
{
|
||||
hres = _hres;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
hres = E_OUTOFMEMORY;
|
||||
}
|
||||
return hres;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DbgEventCallbacks::Stop()
|
||||
{
|
||||
if (0 == InterlockedDecrement(&dbgEventCallbacksStartCount))
|
||||
{
|
||||
_ASSERT(dbgEventCallbacks);
|
||||
if (dbgEventCallbacks)
|
||||
dbgEventCallbacks->Deregister();
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DbgEventCallbacks::DbgEventCallbacks()
|
||||
: m_ReferenceCount(1)
|
||||
, m_dbgClient(NULL)
|
||||
, m_dbgSymbols3(NULL)
|
||||
, m_dbgControl(NULL)
|
||||
{
|
||||
HRESULT hres;
|
||||
try
|
||||
{
|
||||
// monitor "global" WinDbg events
|
||||
hres = DebugCreate(
|
||||
__uuidof(IDebugClient),
|
||||
reinterpret_cast<PVOID *>(&m_dbgClient));
|
||||
else
|
||||
{
|
||||
// ñëó÷àé, êîãäà ìû ðàáîòàåì îòäåëüíî.  ýòîì ñëó÷àå êëèåíò âåñü â íàøåì ðàñïîðÿæåíèè
|
||||
hres =client->QueryInterface( __uuidof(IDebugClient4), reinterpret_cast<PVOID*>(&m_debugClient));
|
||||
if (FAILED(hres))
|
||||
throw DbgException( "DebugCreate failed" );
|
||||
}
|
||||
|
||||
hres = m_debugClient->SetEventCallbacks(this);
|
||||
if (FAILED(hres))
|
||||
throw hres;
|
||||
|
||||
hres = m_dbgClient->QueryInterface(
|
||||
__uuidof(IDebugSymbols3),
|
||||
reinterpret_cast<PVOID *>(&m_dbgSymbols3));
|
||||
if (FAILED(hres))
|
||||
throw hres;
|
||||
|
||||
hres = m_dbgClient->QueryInterface(
|
||||
__uuidof(IDebugControl),
|
||||
reinterpret_cast<PVOID *>(&m_dbgControl));
|
||||
if (FAILED(hres))
|
||||
throw hres;
|
||||
|
||||
hres = m_dbgClient->SetEventCallbacks(this);
|
||||
if (FAILED(hres))
|
||||
throw hres;
|
||||
|
||||
hres = S_OK;
|
||||
}
|
||||
catch(HRESULT _hres)
|
||||
{
|
||||
hres = _hres;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
hres = S_FALSE;
|
||||
}
|
||||
if (S_OK != hres)
|
||||
{
|
||||
Deregister();
|
||||
throw hres;
|
||||
}
|
||||
throw DbgException( "IDebugClient::SetEventCallbacks" );
|
||||
|
||||
}
|
||||
catch( std::exception& )
|
||||
{
|
||||
//dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
//dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DbgEventCallbacks::Deregister()
|
||||
DbgEventCallbacksManager::~DbgEventCallbacksManager()
|
||||
{
|
||||
if (m_dbgSymbols3)
|
||||
{
|
||||
m_dbgSymbols3->Release();
|
||||
m_dbgSymbols3 = NULL;
|
||||
}
|
||||
if (m_dbgControl)
|
||||
{
|
||||
m_dbgControl->Release();
|
||||
m_dbgControl = NULL;
|
||||
}
|
||||
if (m_dbgClient)
|
||||
{
|
||||
m_dbgClient->Release();
|
||||
m_dbgClient = NULL;
|
||||
}
|
||||
Release();
|
||||
if ( m_debugClient )
|
||||
m_debugClient->Release();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG DbgEventCallbacks::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_ReferenceCount);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG DbgEventCallbacks::Release()
|
||||
{
|
||||
ULONG nResult = InterlockedDecrement(&m_ReferenceCount);
|
||||
if (!nResult)
|
||||
{
|
||||
dbgEventCallbacks = NULL;
|
||||
delete this;
|
||||
}
|
||||
return nResult;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT DbgEventCallbacks::GetInterestMask(
|
||||
HRESULT DbgEventCallbacksManager::GetInterestMask(
|
||||
__out PULONG Mask
|
||||
)
|
||||
{
|
||||
*Mask = DEBUG_EVENT_CHANGE_SYMBOL_STATE;
|
||||
*Mask = DEBUG_EVENT_CHANGE_SYMBOL_STATE | DEBUG_EVENT_BREAKPOINT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT DbgEventCallbacks::ChangeSymbolState(
|
||||
HRESULT DbgEventCallbacksManager::ChangeSymbolState(
|
||||
__in ULONG Flags,
|
||||
__in ULONG64 Argument
|
||||
)
|
||||
{
|
||||
DbgExt ext( m_debugClient );
|
||||
|
||||
if ((DEBUG_CSS_LOADS & Flags))
|
||||
{
|
||||
if (Argument)
|
||||
return doSymbolsLoaded(Argument);
|
||||
{
|
||||
DEBUG_MODULE_PARAMETERS dbgModuleParameters={};
|
||||
|
||||
HRESULT hres = dbgExt->symbols3->GetModuleParameters(
|
||||
1,
|
||||
&Argument,
|
||||
0,
|
||||
&dbgModuleParameters);
|
||||
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
ModuleInfo moduleInfo(dbgModuleParameters);
|
||||
|
||||
restoreSyntheticSymbolForModule(moduleInfo);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// f.e. is case ".reload /f image.exe", if for image.exe no symbols
|
||||
restoreSyntheticSymbolForAllModules(m_dbgSymbols3, m_dbgControl);
|
||||
//// f.e. is case ".reload /f image.exe", if for image.exe no symbols
|
||||
restoreSyntheticSymbolForAllModules();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT DbgEventCallbacks::doSymbolsLoaded(
|
||||
ULONG64 moduleBase
|
||||
HRESULT DbgEventCallbacksManager::Breakpoint(
|
||||
__in IDebugBreakpoint * bp
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
DEBUG_MODULE_PARAMETERS dbgModuleParameters;
|
||||
HRESULT hres = m_dbgSymbols3->GetModuleParameters(
|
||||
1,
|
||||
&moduleBase,
|
||||
0,
|
||||
&dbgModuleParameters);
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
ModuleInfo moduleInfo(dbgModuleParameters, m_dbgControl);
|
||||
restoreSyntheticSymbolForModule(moduleInfo, m_dbgSymbols3);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
return dbgBreakpointClass::onBreakpointEvnet( bp );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,57 +1,44 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// monitoring and processing debug events
|
||||
class DbgEventCallbacks : public DebugBaseEventCallbacks
|
||||
class DbgEventCallbacksManager : public DebugBaseEventCallbacks
|
||||
{
|
||||
public:
|
||||
|
||||
static HRESULT Start();
|
||||
static void Stop();
|
||||
DbgEventCallbacksManager( IDebugClient *client = NULL );
|
||||
|
||||
virtual ~DbgEventCallbacksManager();
|
||||
|
||||
private:
|
||||
|
||||
// may generate HRESULT exception if not registered
|
||||
DbgEventCallbacks();
|
||||
void Deregister();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// IUnknown interface implementation
|
||||
|
||||
STDMETHOD_(ULONG, AddRef)();
|
||||
STDMETHOD_(ULONG, Release)();
|
||||
|
||||
STDMETHOD_(ULONG, AddRef)() { return 1; }
|
||||
STDMETHOD_(ULONG, Release)() { return 1; }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// IDebugEventCallbacks interface implementation
|
||||
|
||||
STDMETHOD(GetInterestMask)(
|
||||
__out PULONG Mask
|
||||
);
|
||||
);
|
||||
|
||||
STDMETHOD(ChangeSymbolState)(
|
||||
__in ULONG Flags,
|
||||
__in ULONG64 Argument
|
||||
);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT doSymbolsLoaded(
|
||||
ULONG64 moduleBase
|
||||
|
||||
STDMETHOD(Breakpoint)(
|
||||
__in PDEBUG_BREAKPOINT Bp
|
||||
);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
volatile LONG m_ReferenceCount;
|
||||
|
||||
IDebugClient *m_dbgClient;
|
||||
IDebugSymbols3 *m_dbgSymbols3;
|
||||
IDebugControl *m_dbgControl;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// global singleton
|
||||
|
||||
static DbgEventCallbacks *dbgEventCallbacks;
|
||||
static volatile LONG dbgEventCallbacksStartCount;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private:
|
||||
|
||||
IDebugClient4 *m_debugClient;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
206
pykd/dbgext.cpp
206
pykd/dbgext.cpp
@ -29,48 +29,15 @@
|
||||
#include "dbgprocess.h"
|
||||
#include "dbgsynsym.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// óêàçàòåëü íà òåêóùéè èíòåðôåéñ
|
||||
// óêàçàòåëü íà òåêóùèé èíòåðôåéñ
|
||||
DbgExt *dbgExt = NULL;
|
||||
|
||||
static bool isWindbgExt();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class WindbgGlobalSession
|
||||
{
|
||||
public:
|
||||
|
||||
WindbgGlobalSession() {
|
||||
|
||||
boost::python::import( "pykd" );
|
||||
|
||||
main = boost::python::import("__main__");
|
||||
|
||||
// ïåðåíàïðàâëåíèå ñòàíäàðòíûõ ïîòîêîâ ÂÂ
|
||||
boost::python::object sys = boost::python::import( "sys");
|
||||
|
||||
dbgOut dout;
|
||||
sys.attr("stdout") = boost::python::object( dout );
|
||||
|
||||
dbgIn din;
|
||||
sys.attr("stdin") = boost::python::object( din );
|
||||
}
|
||||
|
||||
boost::python::object
|
||||
global() {
|
||||
return main.attr("__dict__");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
boost::python::object main;
|
||||
|
||||
};
|
||||
|
||||
WindbgGlobalSession *windbgGlobalSession = NULL;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( dprint, DbgPrint::dprint, 1, 2 )
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln, DbgPrint::dprintln, 1, 2 )
|
||||
|
||||
@ -94,8 +61,8 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
boost::python::def( "trace", &setExecutionStatus<DEBUG_STATUS_STEP_INTO> );
|
||||
boost::python::def( "step", &setExecutionStatus<DEBUG_STATUS_STEP_OVER> );
|
||||
boost::python::def( "expr", &evaluate );
|
||||
boost::python::def( "createSession", &dbgCreateSession ); // deprecated
|
||||
boost::python::def( "isSessionStart", &dbgIsSessionStart );
|
||||
boost::python::def( "isWindbgExt", &isWindbgExt );
|
||||
boost::python::def( "isSessionStart", &isWindbgExt );
|
||||
boost::python::def( "symbolsPath", &dbgSymPath );
|
||||
boost::python::def( "dprint", &DbgPrint::dprint, dprint( boost::python::args( "str", "dml" ), "" ) );
|
||||
boost::python::def( "dprintln", &DbgPrint::dprintln, dprintln( boost::python::args( "str", "dml" ), "" ) );
|
||||
@ -200,7 +167,7 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
boost::python::class_<dbgBreakpointClass>(
|
||||
"bp",
|
||||
"break point",
|
||||
boost::python::init<ULONG64>( boost::python::args("offset"), "__init__ dbgBreakpointClass" ) )
|
||||
boost::python::init<ULONG64,boost::python::object&>( boost::python::args("offset", "callback"), "__init__ dbgBreakpointClass" ) )
|
||||
.def( "set", &dbgBreakpointClass::set )
|
||||
.def( "remove", &dbgBreakpointClass::remove )
|
||||
.def( "__str__", &dbgBreakpointClass::print );
|
||||
@ -268,6 +235,86 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class WindbgGlobalSession
|
||||
{
|
||||
public:
|
||||
|
||||
static
|
||||
boost::python::object
|
||||
global() {
|
||||
return windbgGlobalSession->main.attr("__dict__");
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
StartWindbgSession() {
|
||||
if ( 1 == InterlockedIncrement( &sessionCount ) )
|
||||
{
|
||||
windbgGlobalSession = new WindbgGlobalSession();
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
StopWindbgSession() {
|
||||
if ( 0 == InterlockedDecrement( &sessionCount ) )
|
||||
{
|
||||
delete windbgGlobalSession;
|
||||
windbgGlobalSession = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
bool isInit() {
|
||||
return windbgGlobalSession != NULL;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
WindbgGlobalSession() {
|
||||
|
||||
PyImport_AppendInittab("pykd", initpykd );
|
||||
|
||||
Py_Initialize();
|
||||
|
||||
boost::python::import( "pykd" );
|
||||
|
||||
main = boost::python::import("__main__");
|
||||
|
||||
// ïåðåíàïðàâëåíèå ñòàíäàðòíûõ ïîòîêîâ ÂÂ
|
||||
boost::python::object sys = boost::python::import( "sys");
|
||||
|
||||
dbgOut dout;
|
||||
sys.attr("stdout") = boost::python::object( dout );
|
||||
|
||||
dbgIn din;
|
||||
sys.attr("stdin") = boost::python::object( din );
|
||||
}
|
||||
|
||||
~WindbgGlobalSession() {
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
boost::python::object main;
|
||||
|
||||
DbgEventCallbacksManager callbackMgr;
|
||||
|
||||
static volatile LONG sessionCount;
|
||||
|
||||
static WindbgGlobalSession *windbgGlobalSession;
|
||||
};
|
||||
|
||||
volatile LONG WindbgGlobalSession::sessionCount = 0;
|
||||
|
||||
WindbgGlobalSession *WindbgGlobalSession::windbgGlobalSession = NULL;
|
||||
|
||||
bool isWindbgExt() {
|
||||
return WindbgGlobalSession::isInit();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT
|
||||
CALLBACK
|
||||
DebugExtensionInitialize(
|
||||
@ -276,14 +323,10 @@ DebugExtensionInitialize(
|
||||
{
|
||||
*Version = DEBUG_EXTENSION_VERSION( 1, 0 );
|
||||
*Flags = 0;
|
||||
|
||||
PyImport_AppendInittab("pykd", initpykd );
|
||||
|
||||
Py_Initialize();
|
||||
|
||||
windbgGlobalSession = new WindbgGlobalSession();
|
||||
|
||||
return setDbgSessionStarted();
|
||||
|
||||
WindbgGlobalSession::StartWindbgSession();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -291,38 +334,34 @@ VOID
|
||||
CALLBACK
|
||||
DebugExtensionUninitialize()
|
||||
{
|
||||
DbgEventCallbacks::Stop();
|
||||
|
||||
delete windbgGlobalSession;
|
||||
windbgGlobalSession = NULL;
|
||||
|
||||
Py_Finalize();
|
||||
WindbgGlobalSession::StopWindbgSession();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SetupDebugEngine( IDebugClient4 *client, DbgExt *dbgExt )
|
||||
DbgExt::DbgExt( IDebugClient4 *masterClient )
|
||||
{
|
||||
client->QueryInterface( __uuidof(IDebugClient), (void **)&dbgExt->client );
|
||||
client->QueryInterface( __uuidof(IDebugClient4), (void **)&dbgExt->client4 );
|
||||
masterClient->QueryInterface( __uuidof(IDebugClient), (void **)&client );
|
||||
masterClient->QueryInterface( __uuidof(IDebugClient4), (void **)&client4 );
|
||||
|
||||
|
||||
client->QueryInterface( __uuidof(IDebugControl), (void **)&dbgExt->control );
|
||||
client->QueryInterface( __uuidof(IDebugControl4), (void **)&dbgExt->control4 );
|
||||
masterClient->QueryInterface( __uuidof(IDebugControl), (void **)&control );
|
||||
masterClient->QueryInterface( __uuidof(IDebugControl4), (void **)&control4 );
|
||||
|
||||
client->QueryInterface( __uuidof(IDebugRegisters), (void **)&dbgExt->registers );
|
||||
masterClient->QueryInterface( __uuidof(IDebugRegisters), (void **)®isters );
|
||||
|
||||
client->QueryInterface( __uuidof(IDebugSymbols), (void ** )&dbgExt->symbols );
|
||||
client->QueryInterface( __uuidof(IDebugSymbols2), (void ** )&dbgExt->symbols2 );
|
||||
client->QueryInterface( __uuidof(IDebugSymbols3), (void ** )&dbgExt->symbols3 );
|
||||
masterClient->QueryInterface( __uuidof(IDebugSymbols), (void ** )&symbols );
|
||||
masterClient->QueryInterface( __uuidof(IDebugSymbols2), (void ** )&symbols2 );
|
||||
masterClient->QueryInterface( __uuidof(IDebugSymbols3), (void ** )&symbols3 );
|
||||
|
||||
client->QueryInterface( __uuidof(IDebugDataSpaces), (void **)&dbgExt->dataSpaces );
|
||||
client->QueryInterface( __uuidof(IDebugDataSpaces4), (void **)&dbgExt->dataSpaces4 );
|
||||
masterClient->QueryInterface( __uuidof(IDebugDataSpaces), (void **)&dataSpaces );
|
||||
masterClient->QueryInterface( __uuidof(IDebugDataSpaces4), (void **)&dataSpaces4 );
|
||||
|
||||
client->QueryInterface( __uuidof(IDebugAdvanced2), (void **)&dbgExt->advanced2 );
|
||||
masterClient->QueryInterface( __uuidof(IDebugAdvanced2), (void **)&advanced2 );
|
||||
|
||||
client->QueryInterface( __uuidof(IDebugSystemObjects), (void**)&dbgExt->system );
|
||||
client->QueryInterface( __uuidof(IDebugSystemObjects2), (void**)&dbgExt->system2 );
|
||||
masterClient->QueryInterface( __uuidof(IDebugSystemObjects), (void**)&system );
|
||||
masterClient->QueryInterface( __uuidof(IDebugSystemObjects2), (void**)&system2 );
|
||||
|
||||
m_previosExt = dbgExt;
|
||||
dbgExt = this;
|
||||
}
|
||||
|
||||
DbgExt::~DbgExt()
|
||||
@ -365,6 +404,8 @@ DbgExt::~DbgExt()
|
||||
|
||||
if ( system2 )
|
||||
system2->Release();
|
||||
|
||||
dbgExt = m_previosExt;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@ -373,15 +414,12 @@ HRESULT
|
||||
CALLBACK
|
||||
py( PDEBUG_CLIENT4 client, PCSTR args)
|
||||
{
|
||||
DbgExt ext( client );
|
||||
|
||||
PyThreadState *globalInterpreter = PyThreadState_Swap( NULL );
|
||||
PyThreadState *localInterpreter = Py_NewInterpreter();
|
||||
|
||||
try {
|
||||
|
||||
DbgExt ext;
|
||||
SetupDebugEngine( client, &ext );
|
||||
dbgExt = &ext;
|
||||
|
||||
boost::python::import( "pykd" );
|
||||
|
||||
@ -435,7 +473,7 @@ py( PDEBUG_CLIENT4 client, PCSTR args)
|
||||
{
|
||||
DWORD oldCurDirLen = GetCurrentDirectoryA( 0, NULL );
|
||||
|
||||
std::vector<char> oldCurDirCstr(oldCurDirLen);
|
||||
std::vector<char> oldCurDirCstr(oldCurDirLen);
|
||||
|
||||
GetCurrentDirectoryA( oldCurDirLen, &oldCurDirCstr[0] );
|
||||
|
||||
@ -495,16 +533,14 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args )
|
||||
{
|
||||
try {
|
||||
|
||||
DbgExt ext;
|
||||
|
||||
SetupDebugEngine( client, &ext );
|
||||
dbgExt = &ext;
|
||||
DbgExt ext( client );
|
||||
|
||||
|
||||
if ( !std::string( args ).empty() )
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::python::exec( args, windbgGlobalSession->global(), windbgGlobalSession->global() );
|
||||
boost::python::exec( args, WindbgGlobalSession::global(), WindbgGlobalSession::global() );
|
||||
}
|
||||
catch( boost::python::error_already_set const & )
|
||||
{
|
||||
@ -555,7 +591,7 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args )
|
||||
|
||||
if ( !stopInput )
|
||||
try {
|
||||
boost::python::exec( str, windbgGlobalSession->global(), windbgGlobalSession->global() );
|
||||
boost::python::exec( str, WindbgGlobalSession::global(), WindbgGlobalSession::global() );
|
||||
}
|
||||
catch( boost::python::error_already_set const & )
|
||||
{
|
||||
@ -596,12 +632,12 @@ HRESULT
|
||||
CALLBACK
|
||||
pythonpath( PDEBUG_CLIENT4 client, PCSTR args )
|
||||
{
|
||||
DbgExt ext;
|
||||
//DbgExt ext;
|
||||
|
||||
SetupDebugEngine( client, &ext );
|
||||
dbgExt = &ext;
|
||||
//SetupDebugEngine( client, &ext );
|
||||
//dbgExt = &ext;
|
||||
|
||||
//DbgPrint::dprintln( dbgPythonPath.getStr() );
|
||||
////DbgPrint::dprintln( dbgPythonPath.getStr() );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -3,7 +3,9 @@
|
||||
#include <dbgeng.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
struct DbgExt {
|
||||
class DbgExt {
|
||||
|
||||
public:
|
||||
|
||||
IDebugClient *client;
|
||||
IDebugClient4 *client4;
|
||||
@ -24,28 +26,15 @@ struct DbgExt {
|
||||
|
||||
IDebugSystemObjects *system;
|
||||
IDebugSystemObjects2 *system2;
|
||||
|
||||
DbgExt() :
|
||||
client( NULL ),
|
||||
client4( NULL ),
|
||||
control( NULL ),
|
||||
control4( NULL ),
|
||||
registers( NULL ),
|
||||
symbols( NULL ),
|
||||
symbols2( NULL ),
|
||||
symbols3( NULL ),
|
||||
dataSpaces( NULL ),
|
||||
dataSpaces4( NULL ),
|
||||
advanced2( NULL ),
|
||||
system( NULL ),
|
||||
system2( NULL )
|
||||
{}
|
||||
|
||||
DbgExt( IDebugClient4 *client );
|
||||
|
||||
~DbgExt();
|
||||
|
||||
private:
|
||||
|
||||
DbgExt *m_previosExt;
|
||||
};
|
||||
|
||||
extern DbgExt *dbgExt;
|
||||
|
||||
void
|
||||
SetupDebugEngine( IDebugClient4 *client, DbgExt *dbgExt );
|
||||
|
||||
|
@ -3,6 +3,9 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "dbgext.h"
|
||||
#include "dbgmem.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// global unique module data
|
||||
|
@ -24,7 +24,7 @@ getThreadList()
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSystemObjects::GetNumberThreads failed" );
|
||||
|
||||
boost::scoped_array<ULONG> ids(new ULONG[threadCount]);
|
||||
boost::scoped_array<ULONG> ids(new ULONG[threadCount]);
|
||||
hres = dbgExt->system->GetThreadIdsByIndex( 0, threadCount, ids.get(), NULL );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSystemObjects::GetThreadIdsByIndex failed" );
|
||||
|
@ -1,27 +1,27 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "dbgext.h"
|
||||
#include "dbgeventcb.h"
|
||||
#include "dbgsession.h"
|
||||
|
||||
DbgExt dbgGlobalSession;
|
||||
|
||||
bool dbgSessionStarted = false;
|
||||
|
||||
void
|
||||
dbgCreateSession()
|
||||
{
|
||||
IDebugClient4 *client = NULL;
|
||||
DebugCreate( __uuidof(IDebugClient4), (void **)&client );
|
||||
|
||||
SetupDebugEngine( client, &dbgGlobalSession );
|
||||
dbgExt = &dbgGlobalSession;
|
||||
|
||||
setDbgSessionStarted();
|
||||
}
|
||||
|
||||
bool
|
||||
dbgIsSessionStart()
|
||||
{
|
||||
return dbgSessionStarted;
|
||||
}
|
||||
//#include "dbgext.h"
|
||||
//#include "dbgeventcb.h"
|
||||
//#include "dbgsession.h"
|
||||
//
|
||||
//DbgExt dbgGlobalSession;
|
||||
//
|
||||
//bool dbgSessionStarted = false;
|
||||
//
|
||||
//void
|
||||
//dbgCreateSession()
|
||||
//{
|
||||
// IDebugClient4 *client = NULL;
|
||||
// DebugCreate( __uuidof(IDebugClient4), (void **)&client );
|
||||
//
|
||||
// SetupDebugEngine( client, &dbgGlobalSession );
|
||||
// dbgExt = &dbgGlobalSession;
|
||||
//
|
||||
// setDbgSessionStarted();
|
||||
//}
|
||||
//
|
||||
//bool
|
||||
//dbgIsSessionStart()
|
||||
//{
|
||||
// return dbgSessionStarted;
|
||||
//}
|
@ -1,19 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
void
|
||||
dbgCreateSession();
|
||||
|
||||
extern
|
||||
bool dbgSessionStarted;
|
||||
|
||||
inline HRESULT setDbgSessionStarted()
|
||||
{
|
||||
HRESULT hres = DbgEventCallbacks::Start();
|
||||
if (SUCCEEDED(hres))
|
||||
dbgSessionStarted = true;
|
||||
return hres;
|
||||
}
|
||||
|
||||
bool
|
||||
dbgIsSessionStart();
|
||||
//void
|
||||
//dbgCreateSession();
|
||||
//
|
||||
//extern
|
||||
//bool dbgSessionStarted;
|
||||
//
|
||||
//inline HRESULT setDbgSessionStarted()
|
||||
//{
|
||||
// HRESULT hres = DbgEventCallbacks::Start();
|
||||
// if (SUCCEEDED(hres))
|
||||
// dbgSessionStarted = true;
|
||||
// return hres;
|
||||
//}
|
||||
//
|
||||
//bool
|
||||
//dbgIsSessionStart();
|
||||
|
||||
|
@ -574,8 +574,7 @@ ULONG delSyntheticSymbolsMask(
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void restoreSyntheticSymbolForModuleNoLock(
|
||||
const ModuleInfo &moduleInfo,
|
||||
IDebugSymbols3 *symbols3
|
||||
const ModuleInfo &moduleInfo
|
||||
)
|
||||
{
|
||||
SynSymbolsMap::const_iterator itSynSymbols =
|
||||
@ -587,7 +586,7 @@ static void restoreSyntheticSymbolForModuleNoLock(
|
||||
while (itSynSymbol != itSynSymbols->second.end())
|
||||
{
|
||||
DEBUG_MODULE_AND_ID dbgModuleAndId;
|
||||
symbols3->AddSyntheticSymbol(
|
||||
dbgExt->symbols3->AddSyntheticSymbol(
|
||||
moduleInfo.m_base + itSynSymbol->first,
|
||||
itSynSymbol->second.m_size,
|
||||
itSynSymbol->second.m_name.c_str(),
|
||||
@ -602,22 +601,18 @@ static void restoreSyntheticSymbolForModuleNoLock(
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void restoreSyntheticSymbolForModule(
|
||||
const ModuleInfo &moduleInfo,
|
||||
IDebugSymbols3 *symbols3
|
||||
const ModuleInfo &moduleInfo
|
||||
)
|
||||
{
|
||||
_SynSymbolsMapScopedLock();
|
||||
|
||||
// see (**1)
|
||||
restoreSyntheticSymbolForModuleNoLock(moduleInfo, symbols3);
|
||||
restoreSyntheticSymbolForModuleNoLock(moduleInfo);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void restoreSyntheticSymbolForAllModules(
|
||||
IDebugSymbols3 *symbols3,
|
||||
IDebugControl *control
|
||||
)
|
||||
void restoreSyntheticSymbolForAllModules()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -629,12 +624,12 @@ void restoreSyntheticSymbolForAllModules(
|
||||
ULONG nLoaded;
|
||||
ULONG nUnloaded;
|
||||
|
||||
HRESULT hres = symbols3->GetNumberModules(&nLoaded, &nUnloaded);
|
||||
HRESULT hres = dbgExt->symbols3->GetNumberModules(&nLoaded, &nUnloaded);
|
||||
if (SUCCEEDED(hres) && (nLoaded || nUnloaded))
|
||||
{
|
||||
std::vector<DEBUG_MODULE_PARAMETERS> arrModules(nLoaded + nUnloaded);
|
||||
hres =
|
||||
symbols3->GetModuleParameters(
|
||||
dbgExt->symbols3->GetModuleParameters(
|
||||
(ULONG)arrModules.size(),
|
||||
NULL,
|
||||
0,
|
||||
@ -643,8 +638,8 @@ void restoreSyntheticSymbolForAllModules(
|
||||
{
|
||||
for (ULONG i = 0; i < arrModules.size(); ++i)
|
||||
{
|
||||
ModuleInfo moduleInfo(arrModules[i], control);
|
||||
restoreSyntheticSymbolForModuleNoLock(moduleInfo, symbols3);
|
||||
ModuleInfo moduleInfo(arrModules[i]);
|
||||
restoreSyntheticSymbolForModuleNoLock(moduleInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,13 +49,8 @@ void delAllSyntheticSymbolsForModule(
|
||||
// External callbacks
|
||||
|
||||
void restoreSyntheticSymbolForModule(
|
||||
const ModuleInfo &moduleInfo,
|
||||
IDebugSymbols3 *symbols3
|
||||
);
|
||||
const ModuleInfo &moduleInfo );
|
||||
|
||||
void restoreSyntheticSymbolForAllModules(
|
||||
IDebugSymbols3 *symbols3,
|
||||
IDebugControl *control
|
||||
);
|
||||
void restoreSyntheticSymbolForAllModules();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Version="8,00"
|
||||
Name="pykd"
|
||||
ProjectGUID="{C0A12E93-4B76-4B17-B837-37020F957AD2}"
|
||||
RootNamespace="pykd"
|
||||
@ -396,10 +396,6 @@
|
||||
RelativePath=".\dbgreg.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dbgsession.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dbgsym.cpp"
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user