mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +08:00
[0.1.x]
+ exception/breakpoint handling test for separate client + eventHandler catch python exception git-svn-id: https://pykd.svn.codeplex.com/svn@73527 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
bbd6dde6e9
commit
0107a6cb1f
@ -1,15 +1,18 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//// Load/Unload module events
|
// User-customizing debug event handler
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "dbgevent.h"
|
#include "dbgevent.h"
|
||||||
#include "dbgclient.h"
|
#include "dbgclient.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::wstring fetchPythonExceptionStrings( python::object &tracebackModule );
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
EventHandler::EventHandler()
|
EventHandler::EventHandler()
|
||||||
{
|
{
|
||||||
@ -26,7 +29,7 @@ EventHandler::EventHandler()
|
|||||||
m_parentClient = g_dbgClient;
|
m_parentClient = g_dbgClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
EventHandler::EventHandler( DebugClientPtr &client )
|
EventHandler::EventHandler( DebugClientPtr &client )
|
||||||
{
|
{
|
||||||
@ -43,14 +46,14 @@ EventHandler::EventHandler( DebugClientPtr &client )
|
|||||||
m_parentClient = client;
|
m_parentClient = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
EventHandler::~EventHandler()
|
EventHandler::~EventHandler()
|
||||||
{
|
{
|
||||||
m_handlerClient->SetEventCallbacks( NULL );
|
m_handlerClient->SetEventCallbacks( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
HRESULT EventHandler::GetInterestMask(
|
HRESULT EventHandler::GetInterestMask(
|
||||||
__out PULONG Mask
|
__out PULONG Mask
|
||||||
@ -67,79 +70,24 @@ HRESULT EventHandler::GetInterestMask(
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
HRESULT EventHandler::Breakpoint(
|
HRESULT EventHandler::Breakpoint(
|
||||||
__in PDEBUG_BREAKPOINT Bp
|
__in PDEBUG_BREAKPOINT Bp
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// boost::python::dict bpParameters;
|
ULONG Id;
|
||||||
//
|
HRESULT hres = Bp->GetId(&Id);
|
||||||
// HRESULT hres;
|
if (S_OK == hres)
|
||||||
// ULONG Value = 0;
|
{
|
||||||
// ULONG Value2 = 0;
|
PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
|
||||||
// ULONG64 Value64 = 0;
|
return onBreakpoint(Id);
|
||||||
// std::string str;
|
}
|
||||||
//
|
|
||||||
//#define _ADD_BP_ULONG(x) \
|
|
||||||
// hres = Bp->Get##x(&Value); \
|
|
||||||
// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
|
|
||||||
// if (SUCCEEDED( hres )) \
|
|
||||||
// bpParameters[#x] = Value;
|
|
||||||
//
|
|
||||||
//#define _ADD_BP_ULONG2(x, n1, n2) \
|
|
||||||
// hres = Bp->Get##x(&Value, &Value2); \
|
|
||||||
// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
|
|
||||||
// if (SUCCEEDED( hres )) \
|
|
||||||
// { \
|
|
||||||
// bpParameters[n1] = Value; bpParameters[n2] = Value2; \
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//#define _ADD_BP_ULONG64(x) \
|
|
||||||
// hres = Bp->Get##x(&Value64); \
|
|
||||||
// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
|
|
||||||
// if (SUCCEEDED( hres )) \
|
|
||||||
// bpParameters[#x] = Value64;
|
|
||||||
//
|
|
||||||
//#define _ADD_BP_STR(x) \
|
|
||||||
// Value = 0; \
|
|
||||||
// Bp->Get##x(NULL, 0, &Value); \
|
|
||||||
// if (Value) \
|
|
||||||
// { \
|
|
||||||
// str.resize(Value + 1); \
|
|
||||||
// BOOST_VERIFY( SUCCEEDED( \
|
|
||||||
// Bp->Get##x(&str[0], (ULONG)str.size(), NULL) \
|
|
||||||
// ) ); \
|
|
||||||
// if (!str.empty()) bpParameters[#x] = str.c_str(); \
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// _ADD_BP_ULONG(Id);
|
|
||||||
// _ADD_BP_ULONG2(Type, "BreakType", "ProcType");
|
|
||||||
// _ADD_BP_ULONG(Flags);
|
|
||||||
// _ADD_BP_ULONG64(Offset);
|
|
||||||
// _ADD_BP_ULONG2(DataParameters, "Size", "AccessType");
|
|
||||||
// _ADD_BP_ULONG(PassCount);
|
|
||||||
// _ADD_BP_ULONG(CurrentPassCount);
|
|
||||||
// _ADD_BP_ULONG(MatchThreadId);
|
|
||||||
// _ADD_BP_STR(Command);
|
|
||||||
// _ADD_BP_STR(OffsetExpression);
|
|
||||||
//
|
|
||||||
//#undef _ADD_BP_ULONG
|
|
||||||
//#undef _ADD_BP_ULONG2
|
|
||||||
//#undef _ADD_BP_ULONG64
|
|
||||||
//#undef _ADD_BP_STR
|
|
||||||
//
|
|
||||||
//PyThread_StateSave pyThreadSave;
|
|
||||||
|
|
||||||
boost::python::dict bpParameters;
|
return DEBUG_STATUS_NO_CHANGE;
|
||||||
|
|
||||||
return onBreakpoint( bpParameters );
|
|
||||||
|
|
||||||
//onException(bpParameters);
|
|
||||||
//return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
HRESULT EventHandler::Exception(
|
HRESULT EventHandler::Exception(
|
||||||
__in PEXCEPTION_RECORD64 Exception,
|
__in PEXCEPTION_RECORD64 Exception,
|
||||||
@ -151,7 +99,7 @@ HRESULT EventHandler::Exception(
|
|||||||
|
|
||||||
// build list of parameters
|
// build list of parameters
|
||||||
for (ULONG i = 0; i < Exception->NumberParameters; ++i)
|
for (ULONG i = 0; i < Exception->NumberParameters; ++i)
|
||||||
exceptParams.append(Exception->ExceptionInformation[i]);
|
exceptParams.append( Exception->ExceptionInformation[i] );
|
||||||
|
|
||||||
exceptData["Code"] = Exception->ExceptionCode;
|
exceptData["Code"] = Exception->ExceptionCode;
|
||||||
exceptData["Flags"] = Exception->ExceptionFlags;
|
exceptData["Flags"] = Exception->ExceptionFlags;
|
||||||
@ -165,7 +113,7 @@ HRESULT EventHandler::Exception(
|
|||||||
return onException(exceptData);
|
return onException(exceptData);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
HRESULT EventHandler::LoadModule(
|
HRESULT EventHandler::LoadModule(
|
||||||
__in ULONG64 ImageFileHandle,
|
__in ULONG64 ImageFileHandle,
|
||||||
@ -181,7 +129,7 @@ HRESULT EventHandler::LoadModule(
|
|||||||
return onLoadModule( m_parentClient->loadModuleByOffset(BaseOffset) );
|
return onLoadModule( m_parentClient->loadModuleByOffset(BaseOffset) );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
HRESULT EventHandler::UnloadModule(
|
HRESULT EventHandler::UnloadModule(
|
||||||
__in PCSTR ImageBaseName,
|
__in PCSTR ImageBaseName,
|
||||||
@ -193,7 +141,7 @@ HRESULT EventHandler::UnloadModule(
|
|||||||
return onUnloadModule( BaseOffset );
|
return onUnloadModule( BaseOffset );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
HRESULT EventHandler::SessionStatus(
|
HRESULT EventHandler::SessionStatus(
|
||||||
__in ULONG Status
|
__in ULONG Status
|
||||||
@ -205,7 +153,7 @@ HRESULT EventHandler::SessionStatus(
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
HRESULT EventHandler::ChangeDebuggeeState(
|
HRESULT EventHandler::ChangeDebuggeeState(
|
||||||
__in ULONG Flags,
|
__in ULONG Flags,
|
||||||
@ -218,229 +166,14 @@ HRESULT EventHandler::ChangeDebuggeeState(
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void EventHandlerWrap::onHandlerException()
|
||||||
|
{
|
||||||
|
// TODO: some logging, alerting....
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
}; // end pykd namespace
|
}; // end pykd namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#include "dbgevent.h"
|
|
||||||
//#include "dbgio.h"
|
|
||||||
//#include "dbgexcept.h"
|
|
||||||
//#include "pyaux.h"
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//debugEvent::debugEvent()
|
|
||||||
//{
|
|
||||||
// HRESULT hres;
|
|
||||||
//
|
|
||||||
// hres = dbgExt->client->CreateClient( &m_debugClient );
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// throw DbgException( "IDebugClient::CreateClient" );
|
|
||||||
//
|
|
||||||
// hres = m_debugClient->SetEventCallbacks(this);
|
|
||||||
// if (FAILED(hres))
|
|
||||||
// throw DbgException( "IDebugClient::SetEventCallbacks" );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//debugEvent::~debugEvent()
|
|
||||||
//{
|
|
||||||
// m_debugClient->SetEventCallbacks( NULL );
|
|
||||||
//
|
|
||||||
// m_debugClient->Release();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//HRESULT debugEvent::GetInterestMask(
|
|
||||||
// __out PULONG Mask
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
// *Mask = 0;
|
|
||||||
//
|
|
||||||
// *Mask |= DEBUG_EVENT_LOAD_MODULE;
|
|
||||||
// *Mask |= DEBUG_EVENT_UNLOAD_MODULE;
|
|
||||||
// *Mask |= DEBUG_EVENT_SESSION_STATUS;
|
|
||||||
// *Mask |= DEBUG_EVENT_EXCEPTION;
|
|
||||||
// *Mask |= DEBUG_EVENT_BREAKPOINT;
|
|
||||||
//
|
|
||||||
// return S_OK;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//HRESULT debugEvent::Breakpoint(
|
|
||||||
// __in PDEBUG_BREAKPOINT Bp
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
// boost::python::dict bpParameters;
|
|
||||||
//
|
|
||||||
// HRESULT hres;
|
|
||||||
// ULONG Value = 0;
|
|
||||||
// ULONG Value2 = 0;
|
|
||||||
// ULONG64 Value64 = 0;
|
|
||||||
// std::string str;
|
|
||||||
//
|
|
||||||
//#define _ADD_BP_ULONG(x) \
|
|
||||||
// hres = Bp->Get##x(&Value); \
|
|
||||||
// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
|
|
||||||
// if (SUCCEEDED( hres )) \
|
|
||||||
// bpParameters[#x] = Value;
|
|
||||||
//
|
|
||||||
//#define _ADD_BP_ULONG2(x, n1, n2) \
|
|
||||||
// hres = Bp->Get##x(&Value, &Value2); \
|
|
||||||
// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
|
|
||||||
// if (SUCCEEDED( hres )) \
|
|
||||||
// { \
|
|
||||||
// bpParameters[n1] = Value; bpParameters[n2] = Value2; \
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//#define _ADD_BP_ULONG64(x) \
|
|
||||||
// hres = Bp->Get##x(&Value64); \
|
|
||||||
// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
|
|
||||||
// if (SUCCEEDED( hres )) \
|
|
||||||
// bpParameters[#x] = Value64;
|
|
||||||
//
|
|
||||||
//#define _ADD_BP_STR(x) \
|
|
||||||
// Value = 0; \
|
|
||||||
// Bp->Get##x(NULL, 0, &Value); \
|
|
||||||
// if (Value) \
|
|
||||||
// { \
|
|
||||||
// str.resize(Value + 1); \
|
|
||||||
// BOOST_VERIFY( SUCCEEDED( \
|
|
||||||
// Bp->Get##x(&str[0], (ULONG)str.size(), NULL) \
|
|
||||||
// ) ); \
|
|
||||||
// if (!str.empty()) bpParameters[#x] = str.c_str(); \
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// _ADD_BP_ULONG(Id);
|
|
||||||
// _ADD_BP_ULONG2(Type, "BreakType", "ProcType");
|
|
||||||
// _ADD_BP_ULONG(Flags);
|
|
||||||
// _ADD_BP_ULONG64(Offset);
|
|
||||||
// _ADD_BP_ULONG2(DataParameters, "Size", "AccessType");
|
|
||||||
// _ADD_BP_ULONG(PassCount);
|
|
||||||
// _ADD_BP_ULONG(CurrentPassCount);
|
|
||||||
// _ADD_BP_ULONG(MatchThreadId);
|
|
||||||
// _ADD_BP_STR(Command);
|
|
||||||
// _ADD_BP_STR(OffsetExpression);
|
|
||||||
//
|
|
||||||
//#undef _ADD_BP_ULONG
|
|
||||||
//#undef _ADD_BP_ULONG2
|
|
||||||
//#undef _ADD_BP_ULONG64
|
|
||||||
//#undef _ADD_BP_STR
|
|
||||||
//
|
|
||||||
// PyThread_StateSave pyThreadSave;
|
|
||||||
// return onException(bpParameters);
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//HRESULT debugEvent::Exception(
|
|
||||||
// __in PEXCEPTION_RECORD64 Exception,
|
|
||||||
// __in ULONG FirstChance
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
// boost::python::list exceptParams;
|
|
||||||
// boost::python::dict exceptData;
|
|
||||||
//
|
|
||||||
// // build list of parameters
|
|
||||||
// for (ULONG i = 0; i < Exception->NumberParameters; ++i)
|
|
||||||
// exceptParams.append(Exception->ExceptionInformation[i]);
|
|
||||||
//
|
|
||||||
// // build dict of exception data
|
|
||||||
//#define _ADD_EXCEPTION_ENTRY(x) exceptData[#x] = Exception->Exception##x
|
|
||||||
// _ADD_EXCEPTION_ENTRY(Code);
|
|
||||||
// _ADD_EXCEPTION_ENTRY(Flags);
|
|
||||||
// _ADD_EXCEPTION_ENTRY(Record);
|
|
||||||
// _ADD_EXCEPTION_ENTRY(Address);
|
|
||||||
//#undef _ADD_EXCEPTION_ENTRY
|
|
||||||
//
|
|
||||||
// exceptData["Parameters"] = exceptParams;
|
|
||||||
//
|
|
||||||
// exceptData["FirstChance"] = (0 != FirstChance);
|
|
||||||
//
|
|
||||||
// PyThread_StateSave pyThreadSave;
|
|
||||||
// return onException(exceptData);
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//HRESULT debugEvent::LoadModule(
|
|
||||||
// __in ULONG64 ImageFileHandle,
|
|
||||||
// __in ULONG64 BaseOffset,
|
|
||||||
// __in ULONG ModuleSize,
|
|
||||||
// __in PCSTR ModuleName,
|
|
||||||
// __in PCSTR ImageName,
|
|
||||||
// __in ULONG CheckSum,
|
|
||||||
// __in ULONG TimeDateStamp
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
// std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
|
|
||||||
//
|
|
||||||
// ULONG64 moduleBase;
|
|
||||||
// ULONG moduleSize;
|
|
||||||
// std::string moduleName;
|
|
||||||
//
|
|
||||||
// queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
|
|
||||||
// dbgModuleClass module(moduleName, moduleBase, moduleSize);
|
|
||||||
// silentMode.reset();
|
|
||||||
//
|
|
||||||
// PyThread_StateSave pyThreadSave;
|
|
||||||
// return onLoadModule( module );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//HRESULT debugEvent::UnloadModule(
|
|
||||||
// __in PCSTR ImageBaseName,
|
|
||||||
// __in ULONG64 BaseOffset
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
// std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
|
|
||||||
//
|
|
||||||
// ULONG64 moduleBase;
|
|
||||||
// ULONG moduleSize;
|
|
||||||
// std::string moduleName;
|
|
||||||
//
|
|
||||||
// queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
|
|
||||||
// dbgModuleClass module(moduleName, moduleBase, moduleSize);
|
|
||||||
// silentMode.reset();
|
|
||||||
//
|
|
||||||
// PyThread_StateSave pyThreadSave;
|
|
||||||
// return onUnloadModule( module );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//HRESULT debugEvent::SessionStatus(
|
|
||||||
// __in ULONG Status
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
// PyThread_StateSave pyThreadSave;
|
|
||||||
// return onChangeSessionStatus( Status );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//HRESULT debugEvent::ChangeDebuggeeState(
|
|
||||||
// __in ULONG Flags,
|
|
||||||
// __in ULONG64 Argument
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
// PyThread_StateSave pyThreadSave;
|
|
||||||
// return onChangeDebugeeState();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
|
176
pykd/dbgevent.h
176
pykd/dbgevent.h
@ -1,6 +1,6 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// user-customizing debug event handler
|
// User-customizing debug event handler
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class EventHandler : public DebugBaseEventCallbacks
|
class EventHandler : public DebugBaseEventCallbacks
|
||||||
{
|
{
|
||||||
@ -69,7 +69,7 @@ protected:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual ULONG onBreakpoint(const python::dict &/*bpParameters*/) = 0;
|
virtual ULONG onBreakpoint(ULONG Id) = 0;
|
||||||
|
|
||||||
virtual ULONG onException(const python::dict &/*exceptData*/) = 0;
|
virtual ULONG onException(const python::dict &/*exceptData*/) = 0;
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ protected:
|
|||||||
DebugClientPtr m_parentClient;
|
DebugClientPtr m_parentClient;
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class EventHandlerWrap : public python::wrapper<EventHandler>, public EventHandler
|
class EventHandlerWrap : public python::wrapper<EventHandler>, public EventHandler
|
||||||
{
|
{
|
||||||
@ -101,8 +101,8 @@ public:
|
|||||||
EventHandlerWrap( DebugClientPtr &client ) : EventHandler( client )
|
EventHandlerWrap( DebugClientPtr &client ) : EventHandler( client )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ULONG onBreakpoint(const python::dict &bpParameters) {
|
ULONG onBreakpoint(ULONG Id) {
|
||||||
return handler<const python::dict&>("onBreakpoint", bpParameters);
|
return handler("onBreakpoint", Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG onException(const python::dict &exceptData) {
|
ULONG onException(const python::dict &exceptData) {
|
||||||
@ -125,163 +125,41 @@ public:
|
|||||||
return handler( "onChangeDebugeeState" );
|
return handler( "onChangeDebugeeState" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onHandlerException();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template<typename Arg1Type>
|
template<typename Arg1Type>
|
||||||
ULONG handler( const char* handlerName, Arg1Type arg1 )
|
ULONG handler( const char* handlerName, Arg1Type arg1 )
|
||||||
{
|
{
|
||||||
if (python::override pythonHandler = get_override( handlerName ))
|
if (python::override pythonHandler = get_override( handlerName ))
|
||||||
return pythonHandler(arg1);
|
{
|
||||||
|
try {
|
||||||
|
return pythonHandler(arg1);
|
||||||
|
}
|
||||||
|
catch (const python::error_already_set &) {
|
||||||
|
onHandlerException();
|
||||||
|
}
|
||||||
|
}
|
||||||
return DEBUG_STATUS_NO_CHANGE;
|
return DEBUG_STATUS_NO_CHANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG handler( const char* handlerName )
|
ULONG handler( const char* handlerName )
|
||||||
{
|
{
|
||||||
if (python::override pythonHandler = get_override( handlerName ))
|
if (python::override pythonHandler = get_override( handlerName ))
|
||||||
return pythonHandler();
|
{
|
||||||
|
try {
|
||||||
|
return pythonHandler();
|
||||||
|
}
|
||||||
|
catch (const python::error_already_set &) {
|
||||||
|
onHandlerException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return DEBUG_STATUS_NO_CHANGE;
|
return DEBUG_STATUS_NO_CHANGE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}; // end namespace pykd
|
}; // end namespace pykd
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#include "dbgeventcb.h"
|
|
||||||
//#include "dbgmodule.h"
|
|
||||||
//#include "pyaux.h"
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//class debugEvent : public DebugBaseEventCallbacks
|
|
||||||
//{
|
|
||||||
//public:
|
|
||||||
//
|
|
||||||
// debugEvent();
|
|
||||||
//
|
|
||||||
// virtual ~debugEvent();
|
|
||||||
//
|
|
||||||
// virtual ULONG onBreakpoint(boost::python::dict &/*bpParameters*/) = 0;
|
|
||||||
//
|
|
||||||
// virtual ULONG onException(boost::python::dict &/*exceptData*/) = 0;
|
|
||||||
//
|
|
||||||
// virtual ULONG onLoadModule(const dbgModuleClass &/* module */) = 0;
|
|
||||||
//
|
|
||||||
// virtual ULONG onUnloadModule(const dbgModuleClass &/* module */) = 0;
|
|
||||||
//
|
|
||||||
// virtual ULONG onChangeSessionStatus( ULONG status ) = 0;
|
|
||||||
//
|
|
||||||
// virtual ULONG onChangeDebugeeState() = 0;
|
|
||||||
//
|
|
||||||
//private:
|
|
||||||
//
|
|
||||||
// STDMETHOD_(ULONG, AddRef)() { return 1; }
|
|
||||||
// STDMETHOD_(ULONG, Release)() { return 1; }
|
|
||||||
//
|
|
||||||
// STDMETHOD(GetInterestMask)(
|
|
||||||
// __out PULONG Mask
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// STDMETHOD(Breakpoint)(
|
|
||||||
// __in PDEBUG_BREAKPOINT Bp
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// STDMETHOD(Exception)(
|
|
||||||
// __in PEXCEPTION_RECORD64 Exception,
|
|
||||||
// __in ULONG FirstChance
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// STDMETHOD(LoadModule)(
|
|
||||||
// __in ULONG64 ImageFileHandle,
|
|
||||||
// __in ULONG64 BaseOffset,
|
|
||||||
// __in ULONG ModuleSize,
|
|
||||||
// __in PCSTR ModuleName,
|
|
||||||
// __in PCSTR ImageName,
|
|
||||||
// __in ULONG CheckSum,
|
|
||||||
// __in ULONG TimeDateStamp
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// STDMETHOD(UnloadModule)(
|
|
||||||
// __in PCSTR ImageBaseName,
|
|
||||||
// __in ULONG64 BaseOffset
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// STDMETHOD(SessionStatus)(
|
|
||||||
// __in ULONG Status
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// STDMETHOD(ChangeDebuggeeState)(
|
|
||||||
// __in ULONG Flags,
|
|
||||||
// __in ULONG64 Argument );
|
|
||||||
//
|
|
||||||
//private:
|
|
||||||
//
|
|
||||||
// IDebugClient *m_debugClient;
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//class debugEventWrap : public boost::python::wrapper<debugEvent>, public debugEvent
|
|
||||||
//{
|
|
||||||
//
|
|
||||||
//public:
|
|
||||||
//
|
|
||||||
// ULONG onBreakpoint(boost::python::dict &bpParameters) {
|
|
||||||
// return handler<boost::python::dict &>("onBreakpoint", bpParameters);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG onException(boost::python::dict &exceptData) {
|
|
||||||
// return handler<boost::python::dict &>("onException", exceptData);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG onLoadModule(const dbgModuleClass &module) {
|
|
||||||
// return handler<const dbgModuleClass &>("onLoadModule", module );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG onUnloadModule(const dbgModuleClass &module) {
|
|
||||||
// return handler<const dbgModuleClass &>("onUnloadModule", module );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG onChangeSessionStatus( ULONG status ) {
|
|
||||||
// return handler( "onChangeSessionStatus", status );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG onChangeDebugeeState() {
|
|
||||||
// return handler( "onChangeDebugeeState" );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//private:
|
|
||||||
//
|
|
||||||
// template<typename Arg1Type>
|
|
||||||
// ULONG handler( const char* handlerName, Arg1Type arg1 )
|
|
||||||
// {
|
|
||||||
// if (boost::python::override pythonHandler = get_override( handlerName ))
|
|
||||||
// return pythonHandler(arg1);
|
|
||||||
//
|
|
||||||
// return DEBUG_STATUS_NO_CHANGE;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG handler( const char* handlerName )
|
|
||||||
// {
|
|
||||||
// if (boost::python::override pythonHandler = get_override( handlerName ))
|
|
||||||
// return pythonHandler();
|
|
||||||
//
|
|
||||||
// return DEBUG_STATUS_NO_CHANGE;
|
|
||||||
// }
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -569,11 +569,7 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
.def( python::init<>() )
|
.def( python::init<>() )
|
||||||
.def( python::init<DebugClientPtr&>() )
|
.def( python::init<DebugClientPtr&>() )
|
||||||
.def( "onBreakpoint", &pykd::EventHandlerWrap::onBreakpoint,
|
.def( "onBreakpoint", &pykd::EventHandlerWrap::onBreakpoint,
|
||||||
"Triggered breakpoint event. Parameter is dict:\n"
|
"Triggered breakpoint event. Parameter is int: ID of breakpoint\n"
|
||||||
"{\"Id\":int, \"BreakType\":int, \"ProcType\":int, \"Flags\":int, \"Offset\":int,"
|
|
||||||
" \"Size\":int, \"AccessType\":int, \"PassCount\":int, \"CurrentPassCount\":int,"
|
|
||||||
" \"MatchThreadId\":int, \"Command\":str, \"OffsetExpression\":str}\n"
|
|
||||||
"Detailed information: http://msdn.microsoft.com/en-us/library/ff539284(VS.85).aspx \n"
|
|
||||||
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
|
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
|
||||||
.def( "onException", &pykd::EventHandlerWrap::onException,
|
.def( "onException", &pykd::EventHandlerWrap::onException,
|
||||||
"Exception event. Parameter is dict:\n"
|
"Exception event. Parameter is dict:\n"
|
||||||
@ -837,6 +833,30 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_SMALL_DUMP );
|
DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_SMALL_DUMP );
|
||||||
DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_DUMP );
|
DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_DUMP );
|
||||||
|
|
||||||
|
// exception codes
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_ACCESS_VIOLATION);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_DATATYPE_MISALIGNMENT);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_BREAKPOINT);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_SINGLE_STEP);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_ARRAY_BOUNDS_EXCEEDED);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_FLT_DENORMAL_OPERAND);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_FLT_DIVIDE_BY_ZERO);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_FLT_INEXACT_RESULT);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_FLT_INVALID_OPERATION);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_FLT_OVERFLOW);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_FLT_STACK_CHECK);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_FLT_UNDERFLOW);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_INT_DIVIDE_BY_ZERO);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_INT_OVERFLOW);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_PRIV_INSTRUCTION);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_IN_PAGE_ERROR);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_ILLEGAL_INSTRUCTION);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_NONCONTINUABLE_EXCEPTION);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_STACK_OVERFLOW);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_INVALID_DISPOSITION);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_GUARD_PAGE);
|
||||||
|
DEF_PY_CONST_ULONG(EXCEPTION_INVALID_HANDLE);
|
||||||
|
|
||||||
// debug status
|
// debug status
|
||||||
DEF_PY_CONST_ULONG(DEBUG_STATUS_NO_CHANGE);
|
DEF_PY_CONST_ULONG(DEBUG_STATUS_NO_CHANGE);
|
||||||
DEF_PY_CONST_ULONG(DEBUG_STATUS_GO);
|
DEF_PY_CONST_ULONG(DEBUG_STATUS_GO);
|
||||||
@ -859,30 +879,30 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
WindbgGlobalSession::WindbgGlobalSession() {
|
WindbgGlobalSession::WindbgGlobalSession() {
|
||||||
|
|
||||||
PyImport_AppendInittab("pykd", initpykd );
|
PyImport_AppendInittab("pykd", initpykd );
|
||||||
|
|
||||||
PyEval_InitThreads();
|
PyEval_InitThreads();
|
||||||
|
|
||||||
Py_Initialize();
|
Py_Initialize();
|
||||||
|
|
||||||
main = boost::python::import("__main__");
|
main = boost::python::import("__main__");
|
||||||
|
|
||||||
python::object main_namespace = main.attr("__dict__");
|
python::object main_namespace = main.attr("__dict__");
|
||||||
|
|
||||||
// äåëàåì àíàëîã from pykd import *
|
// äåëàåì àíàëîã from pykd import *
|
||||||
python::object pykd = boost::python::import( "pykd" );
|
python::object pykd = boost::python::import( "pykd" );
|
||||||
|
|
||||||
python::dict pykd_namespace( pykd.attr("__dict__") );
|
python::dict pykd_namespace( pykd.attr("__dict__") );
|
||||||
|
|
||||||
python::list iterkeys( pykd_namespace.iterkeys() );
|
python::list iterkeys( pykd_namespace.iterkeys() );
|
||||||
|
|
||||||
for (int i = 0; i < boost::python::len(iterkeys); i++)
|
for (int i = 0; i < boost::python::len(iterkeys); i++)
|
||||||
{
|
{
|
||||||
std::string key = boost::python::extract<std::string>(iterkeys[i]);
|
std::string key = boost::python::extract<std::string>(iterkeys[i]);
|
||||||
|
|
||||||
main_namespace[ key ] = pykd_namespace[ key ];
|
main_namespace[ key ] = pykd_namespace[ key ];
|
||||||
}
|
}
|
||||||
|
|
||||||
pyState = PyEval_SaveThread();
|
pyState = PyEval_SaveThread();
|
||||||
}
|
}
|
||||||
@ -941,23 +961,23 @@ py( PDEBUG_CLIENT4 client, PCSTR args )
|
|||||||
// íàñòðàèâàåì ââîä/âûâîä ( ÷òîáû â ñêðèïòå ìîæíî áûëî ïèñàòü print )
|
// íàñòðàèâàåì ââîä/âûâîä ( ÷òîáû â ñêðèïòå ìîæíî áûëî ïèñàòü print )
|
||||||
|
|
||||||
python::object sys = python::import("sys");
|
python::object sys = python::import("sys");
|
||||||
|
|
||||||
sys.attr("stdout") = python::object( dbgClient->dout() );
|
sys.attr("stdout") = python::object( dbgClient->dout() );
|
||||||
sys.attr("stderr") = python::object( dbgClient->dout() );
|
sys.attr("stderr") = python::object( dbgClient->dout() );
|
||||||
sys.attr("stdin") = python::object( dbgClient->din() );
|
sys.attr("stdin") = python::object( dbgClient->din() );
|
||||||
|
|
||||||
// èìïîðòèðóåì ìîäóëü îáðàáîòêè èñêëþ÷åíèé ( íóæåí äëÿ âûâîäà traceback à )
|
// èìïîðòèðóåì ìîäóëü îáðàáîòêè èñêëþ÷åíèé ( íóæåí äëÿ âûâîäà traceback à )
|
||||||
boost::python::object tracebackModule = python::import("traceback");
|
boost::python::object tracebackModule = python::import("traceback");
|
||||||
|
|
||||||
// ðàçáîð ïàðàìåòðîâ
|
// ðàçáîð ïàðàìåòðîâ
|
||||||
typedef boost::escaped_list_separator<char> char_separator_t;
|
typedef boost::escaped_list_separator<char> char_separator_t;
|
||||||
typedef boost::tokenizer< char_separator_t > char_tokenizer_t;
|
typedef boost::tokenizer< char_separator_t > char_tokenizer_t;
|
||||||
|
|
||||||
std::string argsStr( args );
|
std::string argsStr( args );
|
||||||
|
|
||||||
char_tokenizer_t token( argsStr , char_separator_t( "", " \t", "\"" ) );
|
char_tokenizer_t token( argsStr , char_separator_t( "", " \t", "\"" ) );
|
||||||
std::vector<std::string> argsList;
|
std::vector<std::string> argsList;
|
||||||
|
|
||||||
for ( char_tokenizer_t::iterator it = token.begin(); it != token.end(); ++it )
|
for ( char_tokenizer_t::iterator it = token.begin(); it != token.end(); ++it )
|
||||||
{
|
{
|
||||||
if ( *it != "" )
|
if ( *it != "" )
|
||||||
@ -971,31 +991,31 @@ py( PDEBUG_CLIENT4 client, PCSTR args )
|
|||||||
|
|
||||||
for ( size_t i = 0; i < argsList.size(); ++i )
|
for ( size_t i = 0; i < argsList.size(); ++i )
|
||||||
pythonArgs[i] = const_cast<char*>( argsList[i].c_str() );
|
pythonArgs[i] = const_cast<char*>( argsList[i].c_str() );
|
||||||
|
|
||||||
PySys_SetArgv( (int)argsList.size(), pythonArgs );
|
PySys_SetArgv( (int)argsList.size(), pythonArgs );
|
||||||
|
|
||||||
delete[] pythonArgs;
|
delete[] pythonArgs;
|
||||||
|
|
||||||
// íàéòè ïóòü ê ôàéëó
|
// íàéòè ïóòü ê ôàéëó
|
||||||
std::string fullScriptName;
|
std::string fullScriptName;
|
||||||
DbgPythonPath dbgPythonPath;
|
DbgPythonPath dbgPythonPath;
|
||||||
|
|
||||||
if ( !dbgPythonPath.getFullFileName( argsList[0], fullScriptName ) )
|
if ( !dbgPythonPath.getFullFileName( argsList[0], fullScriptName ) )
|
||||||
{
|
{
|
||||||
dbgClient->eprintln( L"script file not found" );
|
dbgClient->eprintln( L"script file not found" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
try {
|
try {
|
||||||
|
|
||||||
python::object result;
|
python::object result;
|
||||||
|
|
||||||
result = python::exec_file( fullScriptName.c_str(), global, global );
|
result = python::exec_file( fullScriptName.c_str(), global, global );
|
||||||
}
|
}
|
||||||
catch( boost::python::error_already_set const & )
|
catch( boost::python::error_already_set const & )
|
||||||
{
|
{
|
||||||
// îøèáêà â ñêðèïòå
|
// îøèáêà â ñêðèïòå
|
||||||
PyObject *errtype = NULL, *errvalue = NULL, *traceback = NULL;
|
PyObject *errtype = NULL, *errvalue = NULL, *traceback = NULL;
|
||||||
|
|
||||||
PyErr_Fetch( &errtype, &errvalue, &traceback );
|
PyErr_Fetch( &errtype, &errvalue, &traceback );
|
||||||
|
|
||||||
PyErr_NormalizeException( &errtype, &errvalue, &traceback );
|
PyErr_NormalizeException( &errtype, &errvalue, &traceback );
|
||||||
@ -1013,15 +1033,14 @@ py( PDEBUG_CLIENT4 client, PCSTR args )
|
|||||||
|
|
||||||
for ( long i = 0; i < python::len(lst); ++i )
|
for ( long i = 0; i < python::len(lst); ++i )
|
||||||
sstr << std::wstring( python::extract<std::wstring>(lst[i]) ) << std::endl;
|
sstr << std::wstring( python::extract<std::wstring>(lst[i]) ) << std::endl;
|
||||||
|
|
||||||
dbgClient->eprintln( sstr.str() );
|
dbgClient->eprintln( sstr.str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
dbgClient->eprintln( L"unexpected error" );
|
dbgClient->eprintln( L"unexpected error" );
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_EndInterpreter( localInterpreter );
|
Py_EndInterpreter( localInterpreter );
|
||||||
PyThreadState_Swap( globalInterpreter );
|
PyThreadState_Swap( globalInterpreter );
|
||||||
|
65
test/scripts/ehexcepttest.py
Normal file
65
test/scripts/ehexcepttest.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
"""Debug events handler: test exceptions and debug breaks"""
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
import target
|
||||||
|
import pykd
|
||||||
|
|
||||||
|
class BreakExceptionHandler(pykd.eventHandler):
|
||||||
|
"""Track load/unload module implementation"""
|
||||||
|
def __init__(self, client):
|
||||||
|
pykd.eventHandler.__init__(self, client)
|
||||||
|
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
self.wasSecondChance = False
|
||||||
|
|
||||||
|
self.wasBreakpoint = False
|
||||||
|
|
||||||
|
self.bpLastModuleName = ""
|
||||||
|
self.bpCount = 0
|
||||||
|
|
||||||
|
self.firstChanceAccessAddresses = []
|
||||||
|
self.secondChanceAccessAddresses = []
|
||||||
|
|
||||||
|
def onBreakpoint(self, bpId):
|
||||||
|
"""Breakpoint handler"""
|
||||||
|
self.wasBreakpoint = True
|
||||||
|
return pykd.DEBUG_STATUS_NO_CHANGE
|
||||||
|
|
||||||
|
def onException(self, exceptParams):
|
||||||
|
"""Exception handler"""
|
||||||
|
|
||||||
|
self.wasSecondChance = not exceptParams["FirstChance"]
|
||||||
|
|
||||||
|
if exceptParams["Code"] == pykd.EXCEPTION_ACCESS_VIOLATION:
|
||||||
|
if self.wasSecondChance:
|
||||||
|
print exceptParams["Parameters"]
|
||||||
|
self.secondChanceAccessAddresses.append( exceptParams["Parameters"][1] )
|
||||||
|
else:
|
||||||
|
self.firstChanceAccessAddresses.append( exceptParams["Parameters"][1] )
|
||||||
|
elif exceptParams["Code"] == pykd.EXCEPTION_BREAKPOINT:
|
||||||
|
self.bpCount += 1
|
||||||
|
|
||||||
|
return pykd.DEBUG_STATUS_BREAK if self.wasSecondChance else pykd.DEBUG_STATUS_NO_CHANGE
|
||||||
|
|
||||||
|
class EhExceptionBreakpointTest(unittest.TestCase):
|
||||||
|
"""Unit tests of exceptions end breakpoint handling"""
|
||||||
|
|
||||||
|
def testBreakpointException(self):
|
||||||
|
"""Start new process and track exceptions/breakpoints"""
|
||||||
|
testClient = pykd.createDbgClient()
|
||||||
|
testClient.startProcess( target.appPath + " -testExceptions" )
|
||||||
|
|
||||||
|
testClient.dbgCommand( ".reload /f; bp targetapp!doExeptions" )
|
||||||
|
|
||||||
|
breakExceptionHandler = BreakExceptionHandler( testClient )
|
||||||
|
while not breakExceptionHandler.wasSecondChance:
|
||||||
|
testClient.go()
|
||||||
|
|
||||||
|
self.assertTrue( breakExceptionHandler.wasBreakpoint )
|
||||||
|
|
||||||
|
self.assertEqual( [2, 3], breakExceptionHandler.firstChanceAccessAddresses )
|
||||||
|
|
||||||
|
self.assertEqual( 2, breakExceptionHandler.bpCount ) # main and doExeptions
|
||||||
|
|
||||||
|
self.assertEqual( [3, ], breakExceptionHandler.secondChanceAccessAddresses )
|
@ -26,6 +26,7 @@ import synsymtest
|
|||||||
import ehloadtest
|
import ehloadtest
|
||||||
import thrdctxtest
|
import thrdctxtest
|
||||||
import localstest
|
import localstest
|
||||||
|
import ehexcepttest
|
||||||
|
|
||||||
def getTestSuite( singleName = "" ):
|
def getTestSuite( singleName = "" ):
|
||||||
if singleName == "":
|
if singleName == "":
|
||||||
@ -43,7 +44,8 @@ def getTestSuite( singleName = "" ):
|
|||||||
unittest.TestLoader().loadTestsFromTestCase( synsymtest.SynSymTest ),
|
unittest.TestLoader().loadTestsFromTestCase( synsymtest.SynSymTest ),
|
||||||
unittest.TestLoader().loadTestsFromTestCase( thrdctxtest.ThreadContextTest ),
|
unittest.TestLoader().loadTestsFromTestCase( thrdctxtest.ThreadContextTest ),
|
||||||
unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest ),
|
unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest ),
|
||||||
unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest )
|
unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ),
|
||||||
|
unittest.TestLoader().loadTestsFromTestCase( ehexcepttest.EhExceptionBreakpointTest )
|
||||||
] )
|
] )
|
||||||
else:
|
else:
|
||||||
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
|
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
|
||||||
@ -73,4 +75,4 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )
|
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )
|
||||||
|
|
||||||
#raw_input("\npress return\n")
|
# raw_input("\npress return\n")
|
||||||
|
@ -416,6 +416,10 @@
|
|||||||
RelativePath="..\scripts\diatest.py"
|
RelativePath="..\scripts\diatest.py"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\scripts\ehexcepttest.py"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\scripts\ehloadtest.py"
|
RelativePath="..\scripts\ehloadtest.py"
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user