mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-29 11:53:23 +08:00
[0.2.x] added : basic debug event handling implementation
git-svn-id: https://pykd.svn.codeplex.com/svn@79635 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
9455aa0fa5
commit
e759e869c8
164
pykd/bpoint.cpp
164
pykd/bpoint.cpp
@ -6,7 +6,6 @@
|
|||||||
#include "bpoint.h"
|
#include "bpoint.h"
|
||||||
#include "dbgengine.h"
|
#include "dbgengine.h"
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
@ -29,167 +28,4 @@ ULONG setHardwareBp(ULONG64 offset, ULONG size, ULONG accessType, BpCallback &ca
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//static IDebugBreakpoint *setBreakPoint(
|
|
||||||
// IDebugControl4 *control,
|
|
||||||
// ULONG bpType,
|
|
||||||
// ULONG64 addr
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
// IDebugBreakpoint *bp;
|
|
||||||
// HRESULT hres = control->AddBreakpoint(bpType, DEBUG_ANY_ID, &bp);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// throw DbgException("IDebugControl::AddBreakpoint", hres);
|
|
||||||
//
|
|
||||||
// hres = bp->SetOffset(addr);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// {
|
|
||||||
// control->RemoveBreakpoint(bp);
|
|
||||||
// throw DbgException("IDebugBreakpoint::SetOffset", hres);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG bpFlags;
|
|
||||||
// hres = bp->GetFlags(&bpFlags);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// {
|
|
||||||
// control->RemoveBreakpoint(bp);
|
|
||||||
// throw DbgException("IDebugBreakpoint::GetFlags", hres);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// bpFlags |= DEBUG_BREAKPOINT_ENABLED;
|
|
||||||
// hres = bp->SetFlags(bpFlags);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// {
|
|
||||||
// control->RemoveBreakpoint(bp);
|
|
||||||
// throw DbgException("IDebugBreakpoint::SetFlags", hres);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return bp;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//static BPOINT_ID getBpId(IDebugBreakpoint *bp, IDebugControl4 *control = NULL)
|
|
||||||
//{
|
|
||||||
// BPOINT_ID Id;
|
|
||||||
// HRESULT hres = bp->GetId(&Id);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// {
|
|
||||||
// if (control)
|
|
||||||
// control->RemoveBreakpoint(bp);
|
|
||||||
// throw DbgException("IDebugBreakpoint::GetId", hres);
|
|
||||||
// }
|
|
||||||
// return Id;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//BPOINT_ID DebugClient::setSoftwareBp(ULONG64 addr, BpCallback &callback /*= BpCallback()*/)
|
|
||||||
//{
|
|
||||||
// addr = addr64(addr);
|
|
||||||
// IDebugBreakpoint *bp = setBreakPoint(m_control, DEBUG_BREAKPOINT_CODE, addr);
|
|
||||||
//
|
|
||||||
// const BPOINT_ID Id = getBpId(bp, m_control);
|
|
||||||
//
|
|
||||||
// if (!callback.is_none())
|
|
||||||
// {
|
|
||||||
// boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
|
|
||||||
// m_bpCallbacks.m_map[Id] = callback;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return Id;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//BPOINT_ID DebugClient::setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType, BpCallback &callback /*= BpCallback()*/)
|
|
||||||
//{
|
|
||||||
// addr = addr64(addr);
|
|
||||||
// IDebugBreakpoint *bp = setBreakPoint(m_control, DEBUG_BREAKPOINT_DATA, addr);
|
|
||||||
//
|
|
||||||
// HRESULT hres = bp->SetDataParameters(size, accessType);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// {
|
|
||||||
// m_control->RemoveBreakpoint(bp);
|
|
||||||
// throw DbgException("IDebugBreakpoint::SetDataParameters", hres);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const BPOINT_ID Id = getBpId(bp, m_control);
|
|
||||||
//
|
|
||||||
// if (!callback.is_none())
|
|
||||||
// {
|
|
||||||
// boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
|
|
||||||
// m_bpCallbacks.m_map[Id] = callback;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return Id;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//python::list DebugClient::getAllBp()
|
|
||||||
//{
|
|
||||||
// ULONG numberOfBps;
|
|
||||||
// HRESULT hres = m_control->GetNumberBreakpoints(&numberOfBps);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// throw DbgException("IDebugControl::GetNumberBreakpoints", hres);
|
|
||||||
//
|
|
||||||
// python::list lstIds;
|
|
||||||
//
|
|
||||||
// for (ULONG i =0; i < numberOfBps; ++i)
|
|
||||||
// {
|
|
||||||
// IDebugBreakpoint *bp;
|
|
||||||
// hres = m_control->GetBreakpointByIndex(i, &bp);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// throw DbgException("IDebugControl::GetBreakpointByIndex", hres);
|
|
||||||
// lstIds.append( getBpId(bp) );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return lstIds;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//void DebugClient::removeBp(BPOINT_ID Id)
|
|
||||||
//{
|
|
||||||
// IDebugBreakpoint *bp;
|
|
||||||
// HRESULT hres = m_control->GetBreakpointById(Id, &bp);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// throw DbgException("IDebugControl::GetBreakpointById", hres);
|
|
||||||
//
|
|
||||||
// hres = m_control->RemoveBreakpoint(bp);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// throw DbgException("IDebugControl::RemoveBreakpoint", hres);
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//void DebugClient::removeAllBp()
|
|
||||||
//{
|
|
||||||
// ULONG numberOfBps;
|
|
||||||
// do {
|
|
||||||
// HRESULT hres = m_control->GetNumberBreakpoints(&numberOfBps);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// throw DbgException("IDebugControl::GetNumberBreakpoints", hres);
|
|
||||||
// if (!numberOfBps)
|
|
||||||
// break;
|
|
||||||
//
|
|
||||||
// IDebugBreakpoint *bp;
|
|
||||||
// hres = m_control->GetBreakpointByIndex(0, &bp);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// throw DbgException("IDebugControl::GetBreakpointByIndex", hres);
|
|
||||||
//
|
|
||||||
// hres = m_control->RemoveBreakpoint(bp);
|
|
||||||
// if (S_OK != hres)
|
|
||||||
// throw DbgException("IDebugControl::RemoveBreakpoint", hres);
|
|
||||||
//
|
|
||||||
// } while (numberOfBps);
|
|
||||||
//}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
} // end pykd namespace
|
} // end pykd namespace
|
||||||
|
@ -61,6 +61,25 @@ struct STACK_FRAME_DESC {
|
|||||||
|
|
||||||
void getStackTrace(std::vector<STACK_FRAME_DESC> &frames);
|
void getStackTrace(std::vector<STACK_FRAME_DESC> &frames);
|
||||||
|
|
||||||
|
// callback events
|
||||||
|
|
||||||
|
#define DEBUG_CALLBACK_METHODTYPE __cdecl
|
||||||
|
|
||||||
|
enum DEBUG_CALLBACK_RESULT {
|
||||||
|
DebugCallbackBreak,
|
||||||
|
DebugCallbackProceed,
|
||||||
|
DebugCallbackNoChange
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct DEBUG_EVENT_CALLBACK {
|
||||||
|
|
||||||
|
virtual DEBUG_CALLBACK_RESULT DEBUG_CALLBACK_METHODTYPE OnBreakpoint( ULONG bpId ) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
void eventRegisterCallbacks( const DEBUG_EVENT_CALLBACK *callbacks );
|
||||||
|
void eventRemoveCallbacks();
|
||||||
|
|
||||||
//breakpoints
|
//breakpoints
|
||||||
ULONG breakPointSet( ULONG64 offset, bool hardware = false, ULONG size = 0, ULONG accessType = 0 );
|
ULONG breakPointSet( ULONG64 offset, bool hardware = false, ULONG size = 0, ULONG accessType = 0 );
|
||||||
void breakPointRemove( ULONG id );
|
void breakPointRemove( ULONG id );
|
||||||
|
@ -100,7 +100,7 @@ HRESULT
|
|||||||
CALLBACK
|
CALLBACK
|
||||||
py( PDEBUG_CLIENT4 client, PCSTR args )
|
py( PDEBUG_CLIENT4 client, PCSTR args )
|
||||||
{
|
{
|
||||||
g_dbgEng.setClient( client );
|
// g_dbgEng.setClient( client );
|
||||||
|
|
||||||
WindbgGlobalSession::RestorePyState();
|
WindbgGlobalSession::RestorePyState();
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ HRESULT
|
|||||||
CALLBACK
|
CALLBACK
|
||||||
pycmd( PDEBUG_CLIENT4 client, PCSTR args )
|
pycmd( PDEBUG_CLIENT4 client, PCSTR args )
|
||||||
{
|
{
|
||||||
g_dbgEng.setClient( client );
|
// g_dbgEng.setClient( client );
|
||||||
|
|
||||||
WindbgGlobalSession::RestorePyState();
|
WindbgGlobalSession::RestorePyState();
|
||||||
|
|
||||||
|
203
pykd/eventhandler.cpp
Normal file
203
pykd/eventhandler.cpp
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "eventhandler.h"
|
||||||
|
|
||||||
|
namespace pykd {
|
||||||
|
|
||||||
|
|
||||||
|
EventHandler *g_eventHandler = NULL;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
EventHandler::EventHandler()
|
||||||
|
{
|
||||||
|
eventRegisterCallbacks( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
EventHandler::~EventHandler()
|
||||||
|
{
|
||||||
|
eventRemoveCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}; // namespace pykd
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//InternalDbgEventHandler::InternalDbgEventHandler(
|
||||||
|
// IDebugClient4 *client,
|
||||||
|
// DebugClient *parentClient,
|
||||||
|
// SynSymbolsPtr synSymbols,
|
||||||
|
// BpCallbackMap &bpCallbacks
|
||||||
|
//) : m_parentClient(parentClient)
|
||||||
|
// , m_synSymbols(synSymbols)
|
||||||
|
// , m_bpCallbacks(bpCallbacks)
|
||||||
|
//{
|
||||||
|
// HRESULT hres = client->CreateClient(&m_client);
|
||||||
|
// if (FAILED(hres))
|
||||||
|
// throw DbgException("Call IDebugClient::CreateClient failed");
|
||||||
|
//
|
||||||
|
// hres = m_client->QueryInterface(__uuidof(IDebugControl), (void**)&m_control);
|
||||||
|
// if ( FAILED( hres ) )
|
||||||
|
// throw DbgException("QueryInterface IDebugControl failed");
|
||||||
|
//
|
||||||
|
// m_client->SetEventCallbacks(this);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//InternalDbgEventHandler::~InternalDbgEventHandler()
|
||||||
|
//{
|
||||||
|
// m_control->Release();
|
||||||
|
// m_client->Release();
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//HRESULT InternalDbgEventHandler::GetInterestMask(
|
||||||
|
// __out PULONG Mask
|
||||||
|
//)
|
||||||
|
//{
|
||||||
|
// *Mask =
|
||||||
|
// DEBUG_EVENT_BREAKPOINT |
|
||||||
|
// DEBUG_EVENT_CHANGE_ENGINE_STATE |
|
||||||
|
// DEBUG_EVENT_CHANGE_SYMBOL_STATE;
|
||||||
|
//
|
||||||
|
// return S_OK;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//HRESULT InternalDbgEventHandler::ChangeSymbolState(
|
||||||
|
// __in ULONG Flags,
|
||||||
|
// __in ULONG64 Argument
|
||||||
|
//)
|
||||||
|
//{
|
||||||
|
// HRESULT hres = S_OK;
|
||||||
|
//
|
||||||
|
// if (DEBUG_CSS_LOADS & Flags)
|
||||||
|
// hres = symLoaded(Argument);
|
||||||
|
//
|
||||||
|
// return hres;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//HRESULT InternalDbgEventHandler::ChangeEngineState(
|
||||||
|
// __in ULONG Flags,
|
||||||
|
// __in ULONG64 Argument
|
||||||
|
//)
|
||||||
|
//{
|
||||||
|
// HRESULT hres = S_OK;
|
||||||
|
//
|
||||||
|
// if (DEBUG_CES_BREAKPOINTS & Flags)
|
||||||
|
// hres = bpChanged(static_cast<BPOINT_ID>(Argument));
|
||||||
|
//
|
||||||
|
// return hres;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//HRESULT InternalDbgEventHandler::Breakpoint(IDebugBreakpoint *bp)
|
||||||
|
//{
|
||||||
|
// BPOINT_ID Id;
|
||||||
|
// HRESULT hres = bp->GetId(&Id);
|
||||||
|
// if (S_OK == hres)
|
||||||
|
// {
|
||||||
|
// boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
|
||||||
|
// BpCallbackMapIml::iterator it = m_bpCallbacks.m_map.find(Id);
|
||||||
|
// if (it != m_bpCallbacks.m_map.end())
|
||||||
|
// {
|
||||||
|
// PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
//
|
||||||
|
// python::object resObj = it->second(Id);
|
||||||
|
//
|
||||||
|
// if (resObj.is_none())
|
||||||
|
// return DEBUG_STATUS_NO_CHANGE;
|
||||||
|
//
|
||||||
|
// python::extract<HRESULT> getRetCode( resObj );
|
||||||
|
// if (getRetCode.check())
|
||||||
|
// return getRetCode();
|
||||||
|
// }
|
||||||
|
// catch (const python::error_already_set &) {
|
||||||
|
// // TODO: some logging, alerting...
|
||||||
|
// return DEBUG_STATUS_BREAK;
|
||||||
|
// }
|
||||||
|
// // TODO: python code return invalid value
|
||||||
|
// // some logging, alerting...
|
||||||
|
// return DEBUG_STATUS_BREAK;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return DEBUG_STATUS_NO_CHANGE;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//HRESULT InternalDbgEventHandler::symLoaded(
|
||||||
|
// __in ULONG64 ModuleAddress
|
||||||
|
//)
|
||||||
|
//{
|
||||||
|
// if (!ModuleAddress)
|
||||||
|
// {
|
||||||
|
// // f.e. is case ".reload /f image.exe", if for image.exe no symbols
|
||||||
|
// m_synSymbols->restoreAll();
|
||||||
|
// return S_OK;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// m_synSymbols->restoreForModule(ModuleAddress);
|
||||||
|
// return S_OK;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//HRESULT InternalDbgEventHandler::bpChanged(BPOINT_ID Id)
|
||||||
|
//{
|
||||||
|
// if (DEBUG_ANY_ID == Id)
|
||||||
|
// return S_OK;
|
||||||
|
//
|
||||||
|
// IDebugBreakpoint *bp;
|
||||||
|
// HRESULT hres = m_control->GetBreakpointById(Id, &bp);
|
||||||
|
// if (E_NOINTERFACE == hres)
|
||||||
|
// {
|
||||||
|
// // breakpoint was removed
|
||||||
|
// boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
|
||||||
|
// m_bpCallbacks.m_map.erase(Id);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return S_OK;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
32
pykd/eventhandler.h
Normal file
32
pykd/eventhandler.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// Internal debug event handler
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dbgengine.h"
|
||||||
|
|
||||||
|
namespace pykd {
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class EventHandler : public DEBUG_EVENT_CALLBACK {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EventHandler();
|
||||||
|
|
||||||
|
virtual ~EventHandler();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual DEBUG_CALLBACK_RESULT DEBUG_CALLBACK_METHODTYPE OnBreakpoint( ULONG bpId ) {
|
||||||
|
return DebugCallbackNoChange;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern EventHandler *g_eventHandler;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}; // namespace pykd
|
@ -1,157 +0,0 @@
|
|||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#include "dbgclient.h"
|
|
||||||
|
|
||||||
namespace pykd {
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
InternalDbgEventHandler::InternalDbgEventHandler(
|
|
||||||
IDebugClient4 *client,
|
|
||||||
DebugClient *parentClient,
|
|
||||||
SynSymbolsPtr synSymbols,
|
|
||||||
BpCallbackMap &bpCallbacks
|
|
||||||
) : m_parentClient(parentClient)
|
|
||||||
, m_synSymbols(synSymbols)
|
|
||||||
, m_bpCallbacks(bpCallbacks)
|
|
||||||
{
|
|
||||||
HRESULT hres = client->CreateClient(&m_client);
|
|
||||||
if (FAILED(hres))
|
|
||||||
throw DbgException("Call IDebugClient::CreateClient failed");
|
|
||||||
|
|
||||||
hres = m_client->QueryInterface(__uuidof(IDebugControl), (void**)&m_control);
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException("QueryInterface IDebugControl failed");
|
|
||||||
|
|
||||||
m_client->SetEventCallbacks(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
InternalDbgEventHandler::~InternalDbgEventHandler()
|
|
||||||
{
|
|
||||||
m_control->Release();
|
|
||||||
m_client->Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT InternalDbgEventHandler::GetInterestMask(
|
|
||||||
__out PULONG Mask
|
|
||||||
)
|
|
||||||
{
|
|
||||||
*Mask =
|
|
||||||
DEBUG_EVENT_BREAKPOINT |
|
|
||||||
DEBUG_EVENT_CHANGE_ENGINE_STATE |
|
|
||||||
DEBUG_EVENT_CHANGE_SYMBOL_STATE;
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT InternalDbgEventHandler::ChangeSymbolState(
|
|
||||||
__in ULONG Flags,
|
|
||||||
__in ULONG64 Argument
|
|
||||||
)
|
|
||||||
{
|
|
||||||
HRESULT hres = S_OK;
|
|
||||||
|
|
||||||
if (DEBUG_CSS_LOADS & Flags)
|
|
||||||
hres = symLoaded(Argument);
|
|
||||||
|
|
||||||
return hres;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT InternalDbgEventHandler::ChangeEngineState(
|
|
||||||
__in ULONG Flags,
|
|
||||||
__in ULONG64 Argument
|
|
||||||
)
|
|
||||||
{
|
|
||||||
HRESULT hres = S_OK;
|
|
||||||
|
|
||||||
if (DEBUG_CES_BREAKPOINTS & Flags)
|
|
||||||
hres = bpChanged(static_cast<BPOINT_ID>(Argument));
|
|
||||||
|
|
||||||
return hres;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT InternalDbgEventHandler::Breakpoint(IDebugBreakpoint *bp)
|
|
||||||
{
|
|
||||||
BPOINT_ID Id;
|
|
||||||
HRESULT hres = bp->GetId(&Id);
|
|
||||||
if (S_OK == hres)
|
|
||||||
{
|
|
||||||
boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
|
|
||||||
BpCallbackMapIml::iterator it = m_bpCallbacks.m_map.find(Id);
|
|
||||||
if (it != m_bpCallbacks.m_map.end())
|
|
||||||
{
|
|
||||||
PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
python::object resObj = it->second(Id);
|
|
||||||
|
|
||||||
if (resObj.is_none())
|
|
||||||
return DEBUG_STATUS_NO_CHANGE;
|
|
||||||
|
|
||||||
python::extract<HRESULT> getRetCode( resObj );
|
|
||||||
if (getRetCode.check())
|
|
||||||
return getRetCode();
|
|
||||||
}
|
|
||||||
catch (const python::error_already_set &) {
|
|
||||||
// TODO: some logging, alerting...
|
|
||||||
return DEBUG_STATUS_BREAK;
|
|
||||||
}
|
|
||||||
// TODO: python code return invalid value
|
|
||||||
// some logging, alerting...
|
|
||||||
return DEBUG_STATUS_BREAK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DEBUG_STATUS_NO_CHANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT InternalDbgEventHandler::symLoaded(
|
|
||||||
__in ULONG64 ModuleAddress
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (!ModuleAddress)
|
|
||||||
{
|
|
||||||
// f.e. is case ".reload /f image.exe", if for image.exe no symbols
|
|
||||||
m_synSymbols->restoreAll();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_synSymbols->restoreForModule(ModuleAddress);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
HRESULT InternalDbgEventHandler::bpChanged(BPOINT_ID Id)
|
|
||||||
{
|
|
||||||
if (DEBUG_ANY_ID == Id)
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
IDebugBreakpoint *bp;
|
|
||||||
HRESULT hres = m_control->GetBreakpointById(Id, &bp);
|
|
||||||
if (E_NOINTERFACE == hres)
|
|
||||||
{
|
|
||||||
// breakpoint was removed
|
|
||||||
boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
|
|
||||||
m_bpCallbacks.m_map.erase(Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}; // namespace pykd
|
|
@ -1,76 +0,0 @@
|
|||||||
//
|
|
||||||
// Internal debug event handler
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "synsymbol.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
namespace pykd {
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct BpCallbackMap;
|
|
||||||
class DebugClient;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class InternalDbgEventHandler : public DebugBaseEventCallbacks {
|
|
||||||
public:
|
|
||||||
|
|
||||||
InternalDbgEventHandler(
|
|
||||||
IDebugClient4 *client,
|
|
||||||
DebugClient *parentClient,
|
|
||||||
SynSymbolsPtr synSymbols,
|
|
||||||
BpCallbackMap &bpCallbacks
|
|
||||||
);
|
|
||||||
~InternalDbgEventHandler();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// IUnknown impls
|
|
||||||
STDMETHOD_(ULONG, AddRef)() { return 1; }
|
|
||||||
STDMETHOD_(ULONG, Release)() { return 1; }
|
|
||||||
|
|
||||||
// IDebugEventCallbacks impls
|
|
||||||
STDMETHOD(GetInterestMask)(
|
|
||||||
__out PULONG Mask
|
|
||||||
);
|
|
||||||
|
|
||||||
STDMETHOD(ChangeSymbolState)(
|
|
||||||
__in ULONG Flags,
|
|
||||||
__in ULONG64 Argument
|
|
||||||
) override;
|
|
||||||
|
|
||||||
STDMETHOD(ChangeEngineState)(
|
|
||||||
__in ULONG Flags,
|
|
||||||
__in ULONG64 Argument
|
|
||||||
) override;
|
|
||||||
|
|
||||||
STDMETHOD(Breakpoint)(
|
|
||||||
__in IDebugBreakpoint *bp
|
|
||||||
) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
HRESULT symLoaded(__in ULONG64 ModuleAddress);
|
|
||||||
|
|
||||||
HRESULT bpChanged(ULONG Id);
|
|
||||||
|
|
||||||
IDebugClient *m_client;
|
|
||||||
IDebugControl *m_control;
|
|
||||||
|
|
||||||
DebugClient *m_parentClient;
|
|
||||||
|
|
||||||
SynSymbolsPtr m_synSymbols;
|
|
||||||
BpCallbackMap &m_bpCallbacks;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}; // namespace pykd
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
254
pykd/process.cpp
254
pykd/process.cpp
@ -1,254 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "dbgclient.h"
|
|
||||||
#include "stkframe.h"
|
|
||||||
|
|
||||||
namespace pykd {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ULONG64
|
|
||||||
DebugClient::getCurrentProcess()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG64 processAddr = 0;
|
|
||||||
|
|
||||||
hres = m_system->GetImplicitProcessDataOffset( &processAddr );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSystemObjects2::GetImplicitProcessDataOffset failed" );
|
|
||||||
|
|
||||||
return processAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG64
|
|
||||||
getCurrentProcess()
|
|
||||||
{
|
|
||||||
return g_dbgClient->getCurrentProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ULONG64
|
|
||||||
DebugClient::getImplicitThread()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG64 threadOffset = -1;
|
|
||||||
|
|
||||||
hres = m_system->GetImplicitThreadDataOffset( &threadOffset );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSystemObjects2::GetImplicitThreadDataOffset failed" );
|
|
||||||
|
|
||||||
return threadOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG64
|
|
||||||
getImplicitThread() {
|
|
||||||
return g_dbgClient->getImplicitThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
python::list
|
|
||||||
DebugClient::getCurrentStack()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
ULONG filledFrames;
|
|
||||||
std::vector<DEBUG_STACK_FRAME> frames(1000);
|
|
||||||
|
|
||||||
hres = m_control->GetStackTrace( 0, 0, 0, &frames[0], 1000, &filledFrames );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::GetStackTrace failed" );
|
|
||||||
|
|
||||||
python::list frameList;
|
|
||||||
|
|
||||||
for ( ULONG i = 0; i < filledFrames; ++i )
|
|
||||||
{
|
|
||||||
python::object frameObj( StackFrame(shared_from_this(), frames[i]) );
|
|
||||||
|
|
||||||
frameList.append( frameObj );
|
|
||||||
}
|
|
||||||
|
|
||||||
return frameList;
|
|
||||||
}
|
|
||||||
|
|
||||||
python::list
|
|
||||||
getCurrentStack()
|
|
||||||
{
|
|
||||||
return g_dbgClient->getCurrentStack();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::string processorToStr(ULONG processorMode)
|
|
||||||
{
|
|
||||||
switch( processorMode )
|
|
||||||
{
|
|
||||||
case IMAGE_FILE_MACHINE_I386:
|
|
||||||
return "X86";
|
|
||||||
|
|
||||||
case IMAGE_FILE_MACHINE_ARM:
|
|
||||||
return "ARM";
|
|
||||||
|
|
||||||
case IMAGE_FILE_MACHINE_IA64:
|
|
||||||
return "IA64";
|
|
||||||
|
|
||||||
case IMAGE_FILE_MACHINE_AMD64:
|
|
||||||
return "X64";
|
|
||||||
}
|
|
||||||
|
|
||||||
throw DbgException( "Unknown CPU type" );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::string DebugClient::getProcessorMode()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG processorMode;
|
|
||||||
|
|
||||||
hres = m_control->GetEffectiveProcessorType( &processorMode );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::GetEffectiveProcessorType failed" );
|
|
||||||
|
|
||||||
return processorToStr(processorMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getProcessorMode()
|
|
||||||
{
|
|
||||||
return g_dbgClient->getProcessorMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::string DebugClient::getProcessorType()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG processorMode;
|
|
||||||
|
|
||||||
hres = m_control->GetActualProcessorType( &processorMode );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::GetActualProcessorType failed" );
|
|
||||||
|
|
||||||
return processorToStr(processorMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getProcessorType()
|
|
||||||
{
|
|
||||||
return g_dbgClient->getProcessorType();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
python::list DebugClient::getThreadList()
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG i;
|
|
||||||
ULONG oldThreadId = 0;
|
|
||||||
ULONG threadCount;
|
|
||||||
|
|
||||||
hres = m_system->GetNumberThreads( &threadCount );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSystemObjects::GetNumberThreads failed" );
|
|
||||||
|
|
||||||
std::vector<ULONG> threadIds(threadCount);
|
|
||||||
hres = m_system->GetThreadIdsByIndex( 0, threadCount, &threadIds[0], NULL );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSystemObjects::GetThreadIdsByIndex failed" );
|
|
||||||
|
|
||||||
hres = m_system->GetCurrentThreadId( &oldThreadId );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSystemObjects::GetCurrentThreadId failed" );
|
|
||||||
|
|
||||||
boost::python::list threadList;
|
|
||||||
|
|
||||||
for ( i = 0; i < threadCount; ++i )
|
|
||||||
{
|
|
||||||
m_system->SetCurrentThreadId( threadIds[i] );
|
|
||||||
|
|
||||||
ULONG64 threadOffset;
|
|
||||||
hres = m_system->GetCurrentThreadDataOffset( &threadOffset );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
{
|
|
||||||
m_system->SetCurrentThreadId( oldThreadId );
|
|
||||||
throw DbgException( "IDebugSystemObjects::GetCurrentThreadDataOffset failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
threadList.append( threadOffset );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_system->SetCurrentThreadId( oldThreadId );
|
|
||||||
|
|
||||||
return threadList;
|
|
||||||
}
|
|
||||||
|
|
||||||
python::list getThreadList()
|
|
||||||
{
|
|
||||||
return g_dbgClient->getThreadList();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DebugClient::setCurrentProcess( ULONG64 processAddr )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
processAddr = addr64(processAddr);
|
|
||||||
hres = m_system->SetImplicitProcessDataOffset( processAddr );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSystemObjects2::SetImplicitProcessDataOffset failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCurrentProcess( ULONG64 processAddr )
|
|
||||||
{
|
|
||||||
g_dbgClient->setCurrentProcess( processAddr );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DebugClient::setImplicitThread( ULONG64 threadAddr )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
threadAddr = addr64(threadAddr);
|
|
||||||
hres = m_system->SetImplicitThreadDataOffset( threadAddr );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSystemObjects2::SetImplicitThreadDataOffset failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void setImplicitThread( ULONG64 threadAddr )
|
|
||||||
{
|
|
||||||
g_dbgClient->setImplicitThread( threadAddr );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DebugClient::setProcessorMode( const std::wstring &mode )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG processorMode;
|
|
||||||
|
|
||||||
if ( mode == L"X86" )
|
|
||||||
processorMode = IMAGE_FILE_MACHINE_I386;
|
|
||||||
else if ( mode == L"ARM" )
|
|
||||||
processorMode = IMAGE_FILE_MACHINE_ARM;
|
|
||||||
else if ( mode == L"IA64" )
|
|
||||||
processorMode = IMAGE_FILE_MACHINE_IA64;
|
|
||||||
else if ( mode == L"X64" )
|
|
||||||
processorMode = IMAGE_FILE_MACHINE_AMD64;
|
|
||||||
else
|
|
||||||
throw DbgException( "Unknown processor type" );
|
|
||||||
|
|
||||||
hres = m_control->SetEffectiveProcessorType( processorMode );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugControl::SetEffectiveProcessorType failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void setProcessorMode( const std::wstring &mode )
|
|
||||||
{
|
|
||||||
g_dbgClient->setProcessorMode( mode );
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace pykd {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ULONG64 getCurrentProcess();
|
|
||||||
|
|
||||||
ULONG64 getImplicitThread();
|
|
||||||
|
|
||||||
python::list getCurrentStack();
|
|
||||||
|
|
||||||
std::string getProcessorMode();
|
|
||||||
|
|
||||||
std::string getProcessorType();
|
|
||||||
|
|
||||||
python::list getThreadList();
|
|
||||||
|
|
||||||
void setCurrentProcess( ULONG64 processAddr );
|
|
||||||
|
|
||||||
void setImplicitThread( ULONG64 threadAddr );
|
|
||||||
|
|
||||||
void setProcessorMode( const std::wstring &mode );
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="windows-1251"?>
|
<?xml version="1.0" encoding="windows-1251"?>
|
||||||
<VisualStudioProject
|
<VisualStudioProject
|
||||||
ProjectType="Visual C++"
|
ProjectType="Visual C++"
|
||||||
Version="9.00"
|
Version="9,00"
|
||||||
Name="pykd"
|
Name="pykd"
|
||||||
ProjectGUID="{FE961905-666F-4908-A212-961465F46F13}"
|
ProjectGUID="{FE961905-666F-4908-A212-961465F46F13}"
|
||||||
RootNamespace="pykd"
|
RootNamespace="pykd"
|
||||||
@ -385,6 +385,10 @@
|
|||||||
RelativePath=".\disasm.cpp"
|
RelativePath=".\disasm.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\eventhandler.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\localvar.cpp"
|
RelativePath=".\localvar.cpp"
|
||||||
>
|
>
|
||||||
@ -499,6 +503,10 @@
|
|||||||
RelativePath=".\disasmengine.h"
|
RelativePath=".\disasmengine.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\eventhandler.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\localvar.h"
|
RelativePath=".\localvar.h"
|
||||||
>
|
>
|
||||||
|
@ -852,6 +852,77 @@ void breakPointRemoveAll()
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void eventRegisterCallbacks( const DEBUG_EVENT_CALLBACK *callbacks )
|
||||||
|
{
|
||||||
|
g_dbgEng.registerCallbacks( callbacks );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DebugEngine::registerCallbacks( const DEBUG_EVENT_CALLBACK *callbacks )
|
||||||
|
{
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
m_eventCallbacks = callbacks;
|
||||||
|
|
||||||
|
hres = operator->()->client->SetEventCallbacks( &m_callbacks );
|
||||||
|
|
||||||
|
if ( S_OK != hres)
|
||||||
|
throw DbgException("IDebugClient::SetEventCallbacks", hres );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void eventRemoveCallbacks()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline
|
||||||
|
ULONG ConvertCallbackResult( DEBUG_CALLBACK_RESULT result )
|
||||||
|
{
|
||||||
|
switch( result )
|
||||||
|
{
|
||||||
|
case DebugCallbackBreak:
|
||||||
|
return DEBUG_STATUS_BREAK;
|
||||||
|
|
||||||
|
case DebugCallbackProceed:
|
||||||
|
return DEBUG_STATUS_GO_HANDLED;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert( 0 );
|
||||||
|
|
||||||
|
case DebugCallbackNoChange:
|
||||||
|
return DEBUG_STATUS_NO_CHANGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE DebugEngine::DbgEventCallbacks::Breakpoint(
|
||||||
|
__in IDebugBreakpoint *bp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DEBUG_EVENT_CALLBACK* eventCallback = const_cast<DEBUG_EVENT_CALLBACK*>( g_dbgEng.getCallbacks() );
|
||||||
|
|
||||||
|
ULONG id;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
hres = bp->GetId( &id );
|
||||||
|
|
||||||
|
if ( hres == S_OK )
|
||||||
|
{
|
||||||
|
DEBUG_CALLBACK_RESULT result = eventCallback->OnBreakpoint( id );
|
||||||
|
|
||||||
|
return ConvertCallbackResult( result );
|
||||||
|
}
|
||||||
|
|
||||||
|
return DEBUG_STATUS_NO_CHANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
} // end pykd namespace
|
} // end pykd namespace
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "dbgengine.h"
|
#include "dbgengine.h"
|
||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
#include "pyaux.h"
|
#include "pyaux.h"
|
||||||
|
#include "eventhandler.h"
|
||||||
|
|
||||||
#include <dbgeng.h>
|
#include <dbgeng.h>
|
||||||
#include <dbghelp.h>
|
#include <dbghelp.h>
|
||||||
@ -39,6 +40,26 @@ public:
|
|||||||
PyThreadStateSaver pystate;
|
PyThreadStateSaver pystate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DbgEventCallbacks : public DebugBaseEventCallbacks
|
||||||
|
{
|
||||||
|
// IUnknown impls
|
||||||
|
STDMETHOD_(ULONG, AddRef)() { return 1; }
|
||||||
|
STDMETHOD_(ULONG, Release)() { return 1; }
|
||||||
|
|
||||||
|
// IDebugEventCallbacks impls
|
||||||
|
STDMETHOD(GetInterestMask)(
|
||||||
|
__out PULONG Mask
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*Mask = DEBUG_EVENT_BREAKPOINT;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHOD(Breakpoint)(
|
||||||
|
__in IDebugBreakpoint *bp
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
DbgEngBind*
|
DbgEngBind*
|
||||||
operator->()
|
operator->()
|
||||||
{
|
{
|
||||||
@ -56,20 +77,36 @@ public:
|
|||||||
return m_bind.get();
|
return m_bind.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClient( PDEBUG_CLIENT4 client )
|
void registerCallbacks( const DEBUG_EVENT_CALLBACK *callbacks );
|
||||||
|
void removeCallbacks();
|
||||||
|
const DEBUG_EVENT_CALLBACK* getCallbacks() const {
|
||||||
|
return m_eventCallbacks;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugEngine() :
|
||||||
|
m_callbacks()
|
||||||
{
|
{
|
||||||
m_bind.reset(new DbgEngBind(client) );
|
g_eventHandler = new EventHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
~DebugEngine()
|
||||||
|
{
|
||||||
|
delete g_eventHandler;
|
||||||
|
g_eventHandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::auto_ptr<DbgEngBind> m_bind;
|
std::auto_ptr<DbgEngBind> m_bind;
|
||||||
|
|
||||||
|
DbgEventCallbacks m_callbacks;
|
||||||
|
|
||||||
|
const DEBUG_EVENT_CALLBACK *m_eventCallbacks;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
extern DebugEngine g_dbgEng;
|
extern DebugEngine g_dbgEng;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ def printBreakLine():
|
|||||||
|
|
||||||
def printNdisObj():
|
def printNdisObj():
|
||||||
|
|
||||||
ndis=loadModule("ndis")
|
ndis=module("ndis")
|
||||||
|
|
||||||
ndisMajorVersion = ptrByte( ndis.NdisGetVersion + 1 )
|
ndisMajorVersion = ptrByte( ndis.NdisGetVersion + 1 )
|
||||||
ndisMinorVersion = ptrByte( ndis.NdisGetVersion + 3 )
|
ndisMinorVersion = ptrByte( ndis.NdisGetVersion + 3 )
|
||||||
|
Loading…
Reference in New Issue
Block a user