mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 19:53:22 +08:00
[0.1.x] + breakpoint handler
git-svn-id: https://pykd.svn.codeplex.com/svn@73626 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
961932950b
commit
da5633cc12
@ -48,9 +48,9 @@ static IDebugBreakpoint *setBreakPoint(
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static ULONG getBpId(IDebugBreakpoint *bp, IDebugControl4 *control = NULL)
|
static BPOINT_ID getBpId(IDebugBreakpoint *bp, IDebugControl4 *control = NULL)
|
||||||
{
|
{
|
||||||
ULONG Id;
|
BPOINT_ID Id;
|
||||||
HRESULT hres = bp->GetId(&Id);
|
HRESULT hres = bp->GetId(&Id);
|
||||||
if (S_OK != hres)
|
if (S_OK != hres)
|
||||||
{
|
{
|
||||||
@ -63,17 +63,25 @@ static ULONG getBpId(IDebugBreakpoint *bp, IDebugControl4 *control = NULL)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG DebugClient::setSoftwareBp(ULONG64 addr)
|
BPOINT_ID DebugClient::setSoftwareBp(ULONG64 addr, BpCallback &callback /*= BpCallback()*/)
|
||||||
{
|
{
|
||||||
addr = addr64(addr);
|
addr = addr64(addr);
|
||||||
IDebugBreakpoint *bp = setBreakPoint(m_control, DEBUG_BREAKPOINT_CODE, addr);
|
IDebugBreakpoint *bp = setBreakPoint(m_control, DEBUG_BREAKPOINT_CODE, addr);
|
||||||
|
|
||||||
return getBpId(bp, m_control);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG DebugClient::setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType)
|
BPOINT_ID DebugClient::setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType, BpCallback &callback /*= BpCallback()*/)
|
||||||
{
|
{
|
||||||
addr = addr64(addr);
|
addr = addr64(addr);
|
||||||
IDebugBreakpoint *bp = setBreakPoint(m_control, DEBUG_BREAKPOINT_DATA, addr);
|
IDebugBreakpoint *bp = setBreakPoint(m_control, DEBUG_BREAKPOINT_DATA, addr);
|
||||||
@ -85,7 +93,15 @@ ULONG DebugClient::setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType)
|
|||||||
throw DbgException("IDebugBreakpoint::SetDataParameters", hres);
|
throw DbgException("IDebugBreakpoint::SetDataParameters", hres);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getBpId(bp, m_control);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -113,7 +129,7 @@ python::list DebugClient::getAllBp()
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void DebugClient::removeBp(ULONG Id)
|
void DebugClient::removeBp(BPOINT_ID Id)
|
||||||
{
|
{
|
||||||
IDebugBreakpoint *bp;
|
IDebugBreakpoint *bp;
|
||||||
HRESULT hres = m_control->GetBreakpointById(Id, &bp);
|
HRESULT hres = m_control->GetBreakpointById(Id, &bp);
|
||||||
|
@ -10,14 +10,14 @@ namespace pykd {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
inline ULONG setSoftwareBp(ULONG64 addr) {
|
inline BPOINT_ID setSoftwareBp(ULONG64 addr, BpCallback &callback = BpCallback()) {
|
||||||
return g_dbgClient->setSoftwareBp(addr);
|
return g_dbgClient->setSoftwareBp(addr, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
inline ULONG setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType) {
|
inline BPOINT_ID setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType, BpCallback &callback = BpCallback()) {
|
||||||
return g_dbgClient->setHardwareBp(addr, size, accessType);
|
return g_dbgClient->setHardwareBp(addr, size, accessType, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -28,7 +28,7 @@ inline python::list getAllBp() {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
inline void removeBp(ULONG Id) {
|
inline void removeBp(BPOINT_ID Id) {
|
||||||
return g_dbgClient->removeBp(Id);
|
return g_dbgClient->removeBp(Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ DebugClientPtr g_dbgClient( DebugClient::createDbgClient() );
|
|||||||
DebugClient::DebugClient( IDebugClient4 *client )
|
DebugClient::DebugClient( IDebugClient4 *client )
|
||||||
: DbgObject( client )
|
: DbgObject( client )
|
||||||
, m_symSymbols( new SyntheticSymbols(*m_symbols, *this) )
|
, m_symSymbols( new SyntheticSymbols(*m_symbols, *this) )
|
||||||
, m_internalDbgEventHandler(client, m_symSymbols)
|
, m_internalDbgEventHandler(client, this, m_symSymbols, m_bpCallbacks)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,18 @@ typedef boost::shared_ptr<DebugClient> DebugClientPtr;
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef ULONG BPOINT_ID;
|
||||||
|
typedef python::object BpCallback;
|
||||||
|
typedef std::map<BPOINT_ID, BpCallback> BpCallbackMapIml;
|
||||||
|
struct BpCallbackMap {
|
||||||
|
boost::shared_ptr<boost::recursive_mutex> m_lock;
|
||||||
|
BpCallbackMapIml m_map;
|
||||||
|
|
||||||
|
BpCallbackMap() : m_lock(new boost::recursive_mutex) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class DebugClient : private DbgObject {
|
class DebugClient : private DbgObject {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -298,12 +310,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// breakpoints management
|
// breakpoints management
|
||||||
ULONG setSoftwareBp(ULONG64 addr);
|
BPOINT_ID setSoftwareBp(ULONG64 addr, BpCallback &callback = BpCallback());
|
||||||
ULONG setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType);
|
BPOINT_ID setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType, BpCallback &callback = BpCallback());
|
||||||
|
|
||||||
python::list getAllBp();
|
python::list getAllBp();
|
||||||
|
|
||||||
void removeBp(ULONG Id);
|
void removeBp(BPOINT_ID Id);
|
||||||
void removeAllBp();
|
void removeAllBp();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -314,6 +326,8 @@ private:
|
|||||||
//python::list
|
//python::list
|
||||||
//loadArray( ULONG64 offset, ULONG count, bool phyAddr );
|
//loadArray( ULONG64 offset, ULONG count, bool phyAddr );
|
||||||
|
|
||||||
|
BpCallbackMap m_bpCallbacks;
|
||||||
|
|
||||||
SynSymbolsPtr m_symSymbols; // DebugClient is creator
|
SynSymbolsPtr m_symSymbols; // DebugClient is creator
|
||||||
InternalDbgEventHandler m_internalDbgEventHandler;
|
InternalDbgEventHandler m_internalDbgEventHandler;
|
||||||
|
|
||||||
|
@ -85,6 +85,8 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignDWords_, loadSignDWords, 2, 3 );
|
|||||||
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, loadSignQWords, 2, 3 );
|
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, loadSignQWords, 2, 3 );
|
||||||
BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, compareMemory, 3, 4 );
|
BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, compareMemory, 3, 4 );
|
||||||
BOOST_PYTHON_FUNCTION_OVERLOADS( getLocals_, getLocals, 0, 1 );
|
BOOST_PYTHON_FUNCTION_OVERLOADS( getLocals_, getLocals, 0, 1 );
|
||||||
|
BOOST_PYTHON_FUNCTION_OVERLOADS( setSoftwareBp_, setSoftwareBp, 1, 2 );
|
||||||
|
BOOST_PYTHON_FUNCTION_OVERLOADS( setHardwareBp_, setHardwareBp, 3, 4 );
|
||||||
|
|
||||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadChars, DebugClient::loadChars, 2, 3 );
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadChars, DebugClient::loadChars, 2, 3 );
|
||||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadWChars, DebugClient::loadWChars, 2, 3 );
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadWChars, DebugClient::loadWChars, 2, 3 );
|
||||||
@ -99,6 +101,8 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadSignQWords, DebugClient:
|
|||||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_compareMemory, DebugClient::compareMemory, 3, 4 );
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_compareMemory, DebugClient::compareMemory, 3, 4 );
|
||||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_getLocals, DebugClient::getLocals, 0, 1 );
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_getLocals, DebugClient::getLocals, 0, 1 );
|
||||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( pyDia_Symbol_findChildrenEx, pyDia::Symbol::findChildrenEx, 1, 3 );
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( pyDia_Symbol_findChildrenEx, pyDia::Symbol::findChildrenEx, 1, 3 );
|
||||||
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_setSoftwareBp, DebugClient::setSoftwareBp, 1, 2 );
|
||||||
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_setHardwareBp, DebugClient::setHardwareBp, 3, 4 );
|
||||||
|
|
||||||
#define DEF_PY_CONST_ULONG(x) \
|
#define DEF_PY_CONST_ULONG(x) \
|
||||||
python::scope().attr(#x) = ULONG(##x)
|
python::scope().attr(#x) = ULONG(##x)
|
||||||
@ -300,10 +304,10 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Get context of current thread (register values)" )
|
"Get context of current thread (register values)" )
|
||||||
.def( "getLocals", &DebugClient::getLocals, DebugClient_getLocals( python::args( "ctx" ),
|
.def( "getLocals", &DebugClient::getLocals, DebugClient_getLocals( python::args( "ctx" ),
|
||||||
"Get list of local variables" ) )
|
"Get list of local variables" ) )
|
||||||
.def( "setBp", &DebugClient::setSoftwareBp,
|
.def( "setBp", &DebugClient::setSoftwareBp, DebugClient_setSoftwareBp( python::args( "offset", "callback" ),
|
||||||
"Set software breakpoint on executiont" )
|
"Set software breakpoint on executiont" ) )
|
||||||
.def( "setBp", &DebugClient::setHardwareBp,
|
.def( "setBp", &DebugClient::setHardwareBp, DebugClient_setHardwareBp( python::args( "offset", "size", "accsessType", "callback" ),
|
||||||
"Set hardware breakpoint" )
|
"Set hardware breakpoint" ) )
|
||||||
.def( "getAllBp", &DebugClient::getAllBp,
|
.def( "getAllBp", &DebugClient::getAllBp,
|
||||||
"Get all breapoint IDs" )
|
"Get all breapoint IDs" )
|
||||||
.def( "removeBp", &DebugClient::removeBp,
|
.def( "removeBp", &DebugClient::removeBp,
|
||||||
@ -485,10 +489,10 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Get context of current thread (register values)" );
|
"Get context of current thread (register values)" );
|
||||||
python::def( "getLocals", &getLocals, getLocals_( python::args( "ctx" ),
|
python::def( "getLocals", &getLocals, getLocals_( python::args( "ctx" ),
|
||||||
"Get list of local variables" ) );
|
"Get list of local variables" ) );
|
||||||
python::def( "setBp", &setSoftwareBp,
|
python::def( "setBp", &setSoftwareBp, setSoftwareBp_( python::args( "offset", "callback" ),
|
||||||
"Set software breakpoint on executiont" );
|
"Set software breakpoint on executiont" ) );
|
||||||
python::def( "setBp", &setHardwareBp,
|
python::def( "setBp", &setHardwareBp, setHardwareBp_( python::args( "offset", "size", "accsessType", "callback" ) ,
|
||||||
"Set hardware breakpoint" );
|
"Set hardware breakpoint" ) );
|
||||||
python::def( "getAllBp", &getAllBp,
|
python::def( "getAllBp", &getAllBp,
|
||||||
"Get all breapoint IDs" );
|
"Get all breapoint IDs" );
|
||||||
python::def( "removeBp", &removeBp,
|
python::def( "removeBp", &removeBp,
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#include "inteventhandler.h"
|
#include "dbgclient.h"
|
||||||
#include "dbgexcept.h"
|
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
@ -10,13 +9,21 @@ namespace pykd {
|
|||||||
|
|
||||||
InternalDbgEventHandler::InternalDbgEventHandler(
|
InternalDbgEventHandler::InternalDbgEventHandler(
|
||||||
IDebugClient4 *client,
|
IDebugClient4 *client,
|
||||||
SynSymbolsPtr synSymbols
|
DebugClient *parentClient,
|
||||||
) : m_synSymbols(synSymbols)
|
SynSymbolsPtr synSymbols,
|
||||||
|
BpCallbackMap &bpCallbacks
|
||||||
|
) : m_parentClient(parentClient)
|
||||||
|
, m_synSymbols(synSymbols)
|
||||||
|
, m_bpCallbacks(bpCallbacks)
|
||||||
{
|
{
|
||||||
HRESULT hres = client->CreateClient(&m_client);
|
HRESULT hres = client->CreateClient(&m_client);
|
||||||
if (FAILED(hres))
|
if (FAILED(hres))
|
||||||
throw DbgException("Call IDebugClient::CreateClient failed");
|
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);
|
m_client->SetEventCallbacks(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +41,8 @@ HRESULT InternalDbgEventHandler::GetInterestMask(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
*Mask =
|
*Mask =
|
||||||
|
DEBUG_EVENT_BREAKPOINT |
|
||||||
|
DEBUG_EVENT_CHANGE_ENGINE_STATE |
|
||||||
DEBUG_EVENT_CHANGE_SYMBOL_STATE;
|
DEBUG_EVENT_CHANGE_SYMBOL_STATE;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@ -56,6 +65,46 @@ HRESULT InternalDbgEventHandler::ChangeSymbolState(
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
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())
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
|
||||||
|
hres = python::extract<HRESULT>( it->second(Id) );
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
catch (const python::error_already_set &) {
|
||||||
|
// TODO: some logging, alerting...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DEBUG_STATUS_NO_CHANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
HRESULT InternalDbgEventHandler::symLoaded(
|
HRESULT InternalDbgEventHandler::symLoaded(
|
||||||
__in ULONG64 ModuleAddress
|
__in ULONG64 ModuleAddress
|
||||||
)
|
)
|
||||||
@ -73,4 +122,23 @@ HRESULT InternalDbgEventHandler::symLoaded(
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
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
|
}; // namespace pykd
|
||||||
|
@ -7,14 +7,26 @@
|
|||||||
#include <DbgEng.h>
|
#include <DbgEng.h>
|
||||||
#include "synsymbol.h"
|
#include "synsymbol.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct BpCallbackMap;
|
||||||
|
class DebugClient;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class InternalDbgEventHandler : public DebugBaseEventCallbacks {
|
class InternalDbgEventHandler : public DebugBaseEventCallbacks {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
InternalDbgEventHandler(
|
InternalDbgEventHandler(
|
||||||
IDebugClient4 *client,
|
IDebugClient4 *client,
|
||||||
SynSymbolsPtr synSymbols
|
DebugClient *parentClient,
|
||||||
|
SynSymbolsPtr synSymbols,
|
||||||
|
BpCallbackMap &bpCallbacks
|
||||||
);
|
);
|
||||||
~InternalDbgEventHandler();
|
~InternalDbgEventHandler();
|
||||||
|
|
||||||
@ -32,14 +44,34 @@ protected:
|
|||||||
STDMETHOD(ChangeSymbolState)(
|
STDMETHOD(ChangeSymbolState)(
|
||||||
__in ULONG Flags,
|
__in ULONG Flags,
|
||||||
__in ULONG64 Argument
|
__in ULONG64 Argument
|
||||||
);
|
) override;
|
||||||
|
|
||||||
|
STDMETHOD(ChangeEngineState)(
|
||||||
|
__in ULONG Flags,
|
||||||
|
__in ULONG64 Argument
|
||||||
|
) override;
|
||||||
|
|
||||||
|
STDMETHOD(Breakpoint)(
|
||||||
|
__in IDebugBreakpoint *bp
|
||||||
|
) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
HRESULT symLoaded(__in ULONG64 ModuleAddress);
|
HRESULT symLoaded(__in ULONG64 ModuleAddress);
|
||||||
|
|
||||||
|
HRESULT bpChanged(ULONG Id);
|
||||||
|
|
||||||
IDebugClient *m_client;
|
IDebugClient *m_client;
|
||||||
|
IDebugControl *m_control;
|
||||||
|
|
||||||
|
DebugClient *m_parentClient;
|
||||||
|
|
||||||
SynSymbolsPtr m_synSymbols;
|
SynSymbolsPtr m_synSymbols;
|
||||||
|
BpCallbackMap &m_bpCallbacks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}; // namespace pykd
|
}; // namespace pykd
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
@ -52,3 +52,5 @@ namespace python = boost::python;
|
|||||||
|
|
||||||
#include <boost/regex.hpp>
|
#include <boost/regex.hpp>
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
|
#include <boost\thread\win32\recursive_mutex.hpp>
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
#include <DbgEng.h>
|
#include <DbgEng.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <boost\thread\win32\recursive_mutex.hpp>
|
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
|
@ -43,6 +43,24 @@ class BreakExceptionHandler(pykd.eventHandler):
|
|||||||
|
|
||||||
return pykd.DEBUG_STATUS_BREAK
|
return pykd.DEBUG_STATUS_BREAK
|
||||||
|
|
||||||
|
class BpHandlerTestResult:
|
||||||
|
""" Breakpoint handler test results"""
|
||||||
|
def __init__(self):
|
||||||
|
self.wasCodeBp = None
|
||||||
|
self.wasDataBp = None
|
||||||
|
|
||||||
|
bpHandlerTestResult = BpHandlerTestResult()
|
||||||
|
|
||||||
|
def codeBpHandler(bpId):
|
||||||
|
""" Handler of software breakpoint """
|
||||||
|
bpHandlerTestResult.wasCodeBp = bpId
|
||||||
|
return pykd.DEBUG_STATUS_NO_CHANGE
|
||||||
|
|
||||||
|
def dataBpHandler(bpId):
|
||||||
|
""" Handler of hardware breakpoint """
|
||||||
|
bpHandlerTestResult.wasDataBp = bpId
|
||||||
|
return pykd.DEBUG_STATUS_NO_CHANGE
|
||||||
|
|
||||||
class EhExceptionBreakpointTest(unittest.TestCase):
|
class EhExceptionBreakpointTest(unittest.TestCase):
|
||||||
"""Unit tests of exceptions end breakpoint handling"""
|
"""Unit tests of exceptions end breakpoint handling"""
|
||||||
|
|
||||||
@ -53,7 +71,8 @@ class EhExceptionBreakpointTest(unittest.TestCase):
|
|||||||
|
|
||||||
targetMod = testClient.loadModule( "targetapp" )
|
targetMod = testClient.loadModule( "targetapp" )
|
||||||
|
|
||||||
bpIdSoftware = testClient.setBp( targetMod.offset("changeValueForAccessTesting") )
|
bpIdSoftware = testClient.setBp( targetMod.offset("changeValueForAccessTesting"),
|
||||||
|
codeBpHandler )
|
||||||
|
|
||||||
allBp = testClient.getAllBp()
|
allBp = testClient.getAllBp()
|
||||||
self.assertEqual( 1, len( allBp ) )
|
self.assertEqual( 1, len( allBp ) )
|
||||||
@ -75,13 +94,18 @@ class EhExceptionBreakpointTest(unittest.TestCase):
|
|||||||
1, pykd.DEBUG_BREAK_EXECUTE )
|
1, pykd.DEBUG_BREAK_EXECUTE )
|
||||||
|
|
||||||
bpIdHwWrite = testClient.setBp( targetMod.offset("g_valueForAccessTesting1"),
|
bpIdHwWrite = testClient.setBp( targetMod.offset("g_valueForAccessTesting1"),
|
||||||
1, pykd.DEBUG_BREAK_WRITE )
|
1, pykd.DEBUG_BREAK_WRITE, dataBpHandler )
|
||||||
|
|
||||||
bpIdHwRead = testClient.setBp( targetMod.offset("g_valueForAccessTesting2"),
|
bpIdHwRead = testClient.setBp( targetMod.offset("g_valueForAccessTesting2"),
|
||||||
1, pykd.DEBUG_BREAK_READ )
|
1, pykd.DEBUG_BREAK_READ )
|
||||||
|
|
||||||
|
self.assertTrue( bpIdSoftware != bpIdHwExecute and
|
||||||
|
bpIdHwExecute != bpIdHwWrite and
|
||||||
|
bpIdHwWrite != bpIdHwRead )
|
||||||
|
|
||||||
allBp = testClient.getAllBp()
|
allBp = testClient.getAllBp()
|
||||||
self.assertEqual( 4, len( allBp ) )
|
self.assertEqual( 4, len( allBp ) )
|
||||||
|
|
||||||
self.assertTrue( bpIdSoftware in allBp )
|
self.assertTrue( bpIdSoftware in allBp )
|
||||||
self.assertTrue( bpIdHwExecute in allBp )
|
self.assertTrue( bpIdHwExecute in allBp )
|
||||||
self.assertTrue( bpIdHwWrite in allBp )
|
self.assertTrue( bpIdHwWrite in allBp )
|
||||||
@ -106,3 +130,6 @@ class EhExceptionBreakpointTest(unittest.TestCase):
|
|||||||
|
|
||||||
testClient.removeBp()
|
testClient.removeBp()
|
||||||
self.assertEqual( 0, len( testClient.getAllBp() ) )
|
self.assertEqual( 0, len( testClient.getAllBp() ) )
|
||||||
|
|
||||||
|
self.assertEqual( bpHandlerTestResult.wasCodeBp, bpIdSoftware )
|
||||||
|
self.assertTrue( bpHandlerTestResult.wasDataBp, bpIdHwWrite )
|
||||||
|
Loading…
Reference in New Issue
Block a user