From 49099b07635b8aa6fc979c21897629c46a3e753d Mon Sep 17 00:00:00 2001 From: "SND\\ussrhero_cp" Date: Wed, 18 Feb 2015 20:43:33 +0000 Subject: [PATCH] [0.3.x] added : stepout routine ( The traget is executing while not returned from the current subroutine ) [0.3.x] added : sourceStep ( The target is executing a single source line ) [0.3.x] added : sourceStepOver ( The target is executing a single source line ) [0.3.x] added : eventHandler::onThreadStart method (New thread is started in the current process) [0.3.x] added : eventHandler::onThreadStop ( A thread is stopped in the current thread) git-svn-id: https://pykd.svn.codeplex.com/svn@89758 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/pydbgeng.h | 22 +++++++++ pykd/pyeventhandler.cpp | 102 ++++++++++++++++++++++++++++++++++++++++ pykd/pyeventhandler.h | 7 ++- pykd/pykdver.h | 2 +- pykd/pymod.cpp | 12 ++++- 5 files changed, 142 insertions(+), 3 deletions(-) diff --git a/pykd/pydbgeng.h b/pykd/pydbgeng.h index f9548e0..c3dca93 100644 --- a/pykd/pydbgeng.h +++ b/pykd/pydbgeng.h @@ -304,6 +304,13 @@ kdlib::ExecutionStatus targetStepIn() return kdlib::targetStepIn(); } +inline +kdlib::ExecutionStatus targetStepOut() +{ + AutoRestorePyState pystate; + return kdlib::targetStepOut(); +} + inline kdlib::ExecutionStatus targetExecutionStatus() { @@ -311,6 +318,21 @@ kdlib::ExecutionStatus targetExecutionStatus() return kdlib::targetExecutionStatus(); } +inline +kdlib::ExecutionStatus sourceStep() +{ + AutoRestorePyState pystate; + return kdlib::sourceStepIn(); +} + +inline +kdlib::ExecutionStatus sourceStepOver() +{ + AutoRestorePyState pystate; + return kdlib::sourceStepOver(); +} + + /////////////////////////////////////////////////////////////////////////////// // system properties diff --git a/pykd/pyeventhandler.cpp b/pykd/pyeventhandler.cpp index 9a94222..7276a94 100644 --- a/pykd/pyeventhandler.cpp +++ b/pykd/pyeventhandler.cpp @@ -242,6 +242,108 @@ kdlib::DebugCallbackResult EventHandler::onModuleUnload( kdlib::MEMOFFSET_64 of ///////////////////////////////////////////////////////////////////////////////// +kdlib::DebugCallbackResult EventHandler::onThreadStart() +{ + kdlib::DebugCallbackResult result = kdlib::DebugCallbackNoChange; + + PyEval_RestoreThread(m_pystate); + + try { + + do { + + python::override pythonHandler = get_override("onThreadStart"); + if (!pythonHandler) + { + result = kdlib::EventHandler::onThreadStart(); + break; + } + + python::object resObj = pythonHandler(); + + if (resObj.is_none()) + { + result = kdlib::DebugCallbackNoChange; + break; + } + + int retVal = python::extract(resObj); + + if (retVal >= kdlib::DebugCallbackMax) + { + result = kdlib::DebugCallbackBreak; + break; + } + + result = kdlib::DebugCallbackResult(retVal); + + } while (FALSE); + + } + catch (const python::error_already_set &) + { + printException(); + result = kdlib::DebugCallbackBreak; + } + + m_pystate = PyEval_SaveThread(); + + return result; +} + +///////////////////////////////////////////////////////////////////////////////// + +kdlib::DebugCallbackResult EventHandler::onThreadStop() +{ + kdlib::DebugCallbackResult result = kdlib::DebugCallbackNoChange; + + PyEval_RestoreThread(m_pystate); + + try { + + do { + + python::override pythonHandler = get_override("onThreadStop"); + if (!pythonHandler) + { + result = kdlib::EventHandler::onThreadStop(); + break; + } + + python::object resObj = pythonHandler(); + + if (resObj.is_none()) + { + result = kdlib::DebugCallbackNoChange; + break; + } + + int retVal = python::extract(resObj); + + if (retVal >= kdlib::DebugCallbackMax) + { + result = kdlib::DebugCallbackBreak; + break; + } + + result = kdlib::DebugCallbackResult(retVal); + + } while (FALSE); + + } + catch (const python::error_already_set &) + { + printException(); + result = kdlib::DebugCallbackBreak; + } + + m_pystate = PyEval_SaveThread(); + + return result; +} + +///////////////////////////////////////////////////////////////////////////////// + void EventHandler::onCurrentThreadChange(kdlib::THREAD_DEBUG_ID threadid) { PyEval_RestoreThread( m_pystate ); diff --git a/pykd/pyeventhandler.h b/pykd/pyeventhandler.h index e5db4c7..2e08b50 100644 --- a/pykd/pyeventhandler.h +++ b/pykd/pyeventhandler.h @@ -29,15 +29,20 @@ public: EventHandler(); virtual kdlib::DebugCallbackResult onBreakpoint( kdlib::BREAKPOINT_ID bpId ); - virtual void onExecutionStatusChange( kdlib::ExecutionStatus executionStatus ); virtual kdlib::DebugCallbackResult onException( const kdlib::ExceptionInfo &exceptionInfo ); virtual kdlib::DebugCallbackResult onModuleLoad( kdlib::MEMOFFSET_64 offset, const std::wstring &name ); virtual kdlib::DebugCallbackResult onModuleUnload( kdlib::MEMOFFSET_64 offset, const std::wstring &name ); + virtual kdlib::DebugCallbackResult onThreadStart(); + virtual kdlib::DebugCallbackResult onThreadStop(); + + virtual void onExecutionStatusChange(kdlib::ExecutionStatus executionStatus); virtual void onCurrentThreadChange(kdlib::THREAD_DEBUG_ID threadid); virtual void onChangeLocalScope(); virtual void onChangeBreakpoints(); virtual void onDebugOutput(const std::wstring& text); + + private: PyThreadState* m_pystate; diff --git a/pykd/pykdver.h b/pykd/pykdver.h index 84bb5db..d1aa436 100644 --- a/pykd/pykdver.h +++ b/pykd/pykdver.h @@ -2,7 +2,7 @@ #define PYKD_VERSION_MAJOR 0 #define PYKD_VERSION_MINOR 3 #define PYKD_VERSION_SUBVERSION 0 -#define PYKD_VERSION_BUILDNO 18 +#define PYKD_VERSION_BUILDNO 19 #define __VER_STR2__(x) #x #define __VER_STR1__(x) __VER_STR2__(x) diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index be0dbdb..9dc0a66 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -186,6 +186,12 @@ BOOST_PYTHON_MODULE( pykd ) "The target is executing a single instruction or--if that instruction is a subroutine call--subroutine" ); python::def( "trace", pykd::targetStepIn, "The target is executing a single instruction" ); + python::def("stepout", pykd::targetStepOut, + "The traget is executing while not returned from the current subroutine"); + python::def("sourceStep", pykd::sourceStep, + "The target is executing a single source line"); + python::def("sourceStepOver", pykd::sourceStepOver, + "The target is executing a single source line"); python::def( "getExecutionStatus", pykd::targetExecutionStatus, "Return current execution status" ); @@ -969,7 +975,11 @@ BOOST_PYTHON_MODULE( pykd ) .def("onChangeBreakpoints", &EventHandler::onChangeBreakpoints, "Breakpoints is changed for current process" ) .def( "onDebugOutput", &EventHandler::onDebugOutput, - "Request debug output" ); + "Request debug output" ) + .def("onThreadStart", &EventHandler::onThreadStart, + "New thread is started in the current process" ) + .def("onThreadStop", &EventHandler::onThreadStop, + "A thread is stopped in the current thread") // .def( "onSymbolsLoaded", &EventHandlerWrap::onSymbolsLoaded, // "Triggered debug symbols loaded. Parameter - module base or 0\n"