[0.3.x] added : onDebugOutput callback

[0.3.x] added : dbgCommand optional parameter suppressOutput 

git-svn-id: https://pykd.svn.codeplex.com/svn@89531 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2014-12-23 10:00:43 +00:00 committed by Mikhail I. Izmestev
parent f4473c8d89
commit e4c8bd3ff9
8 changed files with 117 additions and 30 deletions

View File

@ -103,10 +103,19 @@ bool isKernelDebugging()
} }
inline inline
std::wstring debugCommand( const std::wstring &command ) python::object debugCommand( const std::wstring &command, bool suppressOutput = true)
{ {
std::wstring debugResult;
{
AutoRestorePyState pystate; AutoRestorePyState pystate;
return kdlib::debugCommand(command); debugResult = kdlib::debugCommand(command, suppressOutput);
}
if (debugResult.size() > 0 )
return python::object(debugResult);
return python::object();
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -378,8 +387,6 @@ std::wstring callExtension( kdlib::EXTENSION_ID extId, const std::wstring comman
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
std::wstring debugCommand( const std::wstring &command );
python::object evaluate( const std::wstring &expression, bool cplusplus = false ); python::object evaluate( const std::wstring &expression, bool cplusplus = false );
python::tuple getSourceLine( kdlib::MEMOFFSET_64 offset = 0 ); python::tuple getSourceLine( kdlib::MEMOFFSET_64 offset = 0 );

View File

@ -12,6 +12,16 @@ class DbgOut : public kdlib::windbg::WindbgOut
{ {
public: public:
virtual void write( const std::wstring& str ) {
AutoRestorePyState pystate;
kdlib::windbg::WindbgOut::write(str);
}
virtual void writedml( const std::wstring& str ) {
AutoRestorePyState pystate;
kdlib::windbg::WindbgOut::writedml(str);
}
void flush() { void flush() {
} }
@ -42,14 +52,24 @@ class SysDbgOut : public DbgOut
{ {
public: public:
SysDbgOut() {
m_state = PyThreadState_Get();
}
virtual void write( const std::wstring& str) { virtual void write( const std::wstring& str) {
AutoSavePythonState pystate( &m_state );
python::object sys = python::import("sys"); python::object sys = python::import("sys");
sys.attr("stdout").attr("write")( str ); sys.attr("stdout").attr("write")( str );
} }
virtual void writedml( const std::wstring& str) { virtual void writedml( const std::wstring& str) {
AutoSavePythonState pystate( &m_state );
write(str); write(str);
} }
private:
PyThreadState* m_state;
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -58,16 +78,26 @@ class SysDbgIn : public DbgIn
{ {
public: public:
SysDbgIn() {
m_state = PyThreadState_Get();
}
virtual std::wstring readline() { virtual std::wstring readline() {
AutoSavePythonState pystate( &m_state );
python::object sys = python::import("sys"); python::object sys = python::import("sys");
return python::extract<std::wstring>( sys.attr("stdin").attr("readline") ); return python::extract<std::wstring>( sys.attr("stdin").attr("readline") );
} }
private:
PyThreadState* m_state;
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
inline void dprint( const std::wstring &str, bool dml = false ) inline void dprint( const std::wstring &str, bool dml = false )
{ {
AutoRestorePyState pystate;
kdlib::dprint(str,dml); kdlib::dprint(str,dml);
} }
@ -75,6 +105,7 @@ inline void dprint( const std::wstring &str, bool dml = false )
inline void dprintln( const std::wstring &str, bool dml = false ) inline void dprintln( const std::wstring &str, bool dml = false )
{ {
AutoRestorePyState pystate;
kdlib::dprintln(str,dml); kdlib::dprintln(str,dml);
} }
@ -82,6 +113,7 @@ inline void dprintln( const std::wstring &str, bool dml = false )
inline void eprint( const std::wstring &str ) inline void eprint( const std::wstring &str )
{ {
AutoRestorePyState pystate;
kdlib::eprint(str); kdlib::eprint(str);
} }
@ -89,6 +121,7 @@ inline void eprint( const std::wstring &str )
inline void eprintln( const std::wstring &str ) inline void eprintln( const std::wstring &str )
{ {
AutoRestorePyState pystate;
kdlib::eprintln(str); kdlib::eprintln(str);
} }

View File

@ -286,6 +286,28 @@ void EventHandler::onChangeLocalScope()
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
void EventHandler::onDebugOutput(const std::wstring& text)
{
PyEval_RestoreThread( m_pystate );
try {
python::override pythonHandler = get_override("onDebugOutput");
if ( pythonHandler )
{
pythonHandler(text);
}
}
catch (const python::error_already_set &)
{
printException();
}
m_pystate = PyEval_SaveThread();
}
/////////////////////////////////////////////////////////////////////////////////
Breakpoint::Breakpoint(kdlib::BreakpointPtr bp) Breakpoint::Breakpoint(kdlib::BreakpointPtr bp)
{ {
m_pystate = PyThreadState_Get(); m_pystate = PyThreadState_Get();

View File

@ -35,6 +35,7 @@ public:
virtual kdlib::DebugCallbackResult onModuleUnload( kdlib::MEMOFFSET_64 offset, const std::wstring &name ); virtual kdlib::DebugCallbackResult onModuleUnload( kdlib::MEMOFFSET_64 offset, const std::wstring &name );
virtual void onCurrentThreadChange(kdlib::THREAD_DEBUG_ID threadid); virtual void onCurrentThreadChange(kdlib::THREAD_DEBUG_ID threadid);
virtual void onChangeLocalScope(); virtual void onChangeLocalScope();
virtual void onDebugOutput(const std::wstring& text);
private: private:

View File

@ -2,7 +2,7 @@
#define PYKD_VERSION_MAJOR 0 #define PYKD_VERSION_MAJOR 0
#define PYKD_VERSION_MINOR 3 #define PYKD_VERSION_MINOR 3
#define PYKD_VERSION_SUBVERSION 0 #define PYKD_VERSION_SUBVERSION 0
#define PYKD_VERSION_BUILDNO 14 #define PYKD_VERSION_BUILDNO 15
#define __VER_STR2__(x) #x #define __VER_STR2__(x) #x
#define __VER_STR1__(x) __VER_STR2__(x) #define __VER_STR1__(x) __VER_STR2__(x)

View File

@ -39,6 +39,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( detachProcess_, pykd::detachProcess, 0, 1 );
BOOST_PYTHON_FUNCTION_OVERLOADS( terminateProcess_, pykd::terminateProcess, 0, 1 ); BOOST_PYTHON_FUNCTION_OVERLOADS( terminateProcess_, pykd::terminateProcess, 0, 1 );
BOOST_PYTHON_FUNCTION_OVERLOADS( attachKernel_, pykd::attachKernel, 0, 1 ); BOOST_PYTHON_FUNCTION_OVERLOADS( attachKernel_, pykd::attachKernel, 0, 1 );
BOOST_PYTHON_FUNCTION_OVERLOADS( evaluate_, pykd::evaluate, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( evaluate_, pykd::evaluate, 1, 2 );
BOOST_PYTHON_FUNCTION_OVERLOADS( debugCommand_, pykd::debugCommand, 1, 2 );
BOOST_PYTHON_FUNCTION_OVERLOADS( dprint_, pykd::dprint, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( dprint_, pykd::dprint, 1, 2 );
BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln_, pykd::dprintln, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln_, pykd::dprintln, 1, 2 );
@ -83,16 +84,22 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( Module_findSymbol, ModuleAdapter::findSymbol, 2
BOOST_PYTHON_FUNCTION_OVERLOADS( TypeInfo_ptrTo, TypeInfoAdapter::ptrTo, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( TypeInfo_ptrTo, TypeInfoAdapter::ptrTo, 1, 2 );
pykd::SysDbgOut sysPykdOut;
pykd::SysDbgOut sysPykdErr;
pykd::SysDbgIn sysPykdIn;
namespace pykd { namespace pykd {
void initialize() void initialize()
{ {
pykd::SysDbgOut *sysPykdOut = new pykd::SysDbgOut();
pykd::SysDbgOut *sysPykdErr = new pykd::SysDbgOut();
pykd::SysDbgIn *sysPykdIn = new pykd::SysDbgIn();
AutoRestorePyState pystate; AutoRestorePyState pystate;
kdlib::initialize(); kdlib::initialize();
// èñïîëüçîâàòü âìåñòî êîíñîëè ïîòîêè èç sys
kdlib::dbgout = sysPykdOut;
kdlib::dbgerr = sysPykdErr;
kdlib::dbgin = sysPykdIn;
} }
void remote_initialize( const std::wstring& remoteOptions ) void remote_initialize( const std::wstring& remoteOptions )
@ -110,11 +117,6 @@ void uninitialize()
BOOST_PYTHON_MODULE( pykd ) BOOST_PYTHON_MODULE( pykd )
{ {
// èñïîëüçîâàòü âìåñòî êîíñîëè ïîòîêè èç sys
kdlib::dbgout =&sysPykdOut;
kdlib::dbgerr = &sysPykdErr;
kdlib::dbgin = &sysPykdIn;
python::scope().attr("__version__") = pykdVersion; python::scope().attr("__version__") = pykdVersion;
python::scope().attr("version") = pykdVersion; python::scope().attr("version") = pykdVersion;
@ -173,10 +175,10 @@ BOOST_PYTHON_MODULE( pykd )
python::def( "breakin", pykd::targetBreak, python::def( "breakin", pykd::targetBreak,
"Break into debugger" ); "Break into debugger" );
python::def( "expr", pykd::evaluate, evaluate_( boost::python::args( "expression", "cplusplus" ), python::def( "expr", pykd::evaluate, evaluate_( python::args( "expression", "cplusplus" ),
"Evaluate windbg expression" ) ); "Evaluate windbg expression" ) );
python::def( "dbgCommand", pykd::debugCommand, python::def( "dbgCommand", &pykd::debugCommand,
"Run a debugger's command and return it's result as a string" ); debugCommand_( python::args( "command", "suppressOutput"), "Run a debugger's command and return it's result as a string" ) );
python::def( "go", pykd::targetGo, python::def( "go", pykd::targetGo,
"Go debugging" ); "Go debugging" );
python::def( "step", pykd::targetStep, python::def( "step", pykd::targetStep,
@ -899,6 +901,8 @@ BOOST_PYTHON_MODULE( pykd )
.def( "onChangeLocalScope", &EventHandler::onChangeLocalScope, .def( "onChangeLocalScope", &EventHandler::onChangeLocalScope,
"The current local scope has been changed.\n" "The current local scope has been changed.\n"
"There is no return value" ) "There is no return value" )
.def( "onDebugOutput", &EventHandler::onDebugOutput,
"Request debug output" );
// .def( "onSymbolsLoaded", &EventHandlerWrap::onSymbolsLoaded, // .def( "onSymbolsLoaded", &EventHandlerWrap::onSymbolsLoaded,
// "Triggered debug symbols loaded. Parameter - module base or 0\n" // "Triggered debug symbols loaded. Parameter - module base or 0\n"
@ -908,7 +912,6 @@ BOOST_PYTHON_MODULE( pykd )
// "There is no return value"); // "There is no return value");
; ;
python::class_<Breakpoint, boost::noncopyable>( "breakpoint", python::class_<Breakpoint, boost::noncopyable>( "breakpoint",
"class for CPU context representation", python::init<kdlib::MEMOFFSET_64>()) "class for CPU context representation", python::init<kdlib::MEMOFFSET_64>())
.def( python::init<kdlib::MEMOFFSET_64, size_t, kdlib::ACCESS_TYPE>() ) .def( python::init<kdlib::MEMOFFSET_64, size_t, kdlib::ACCESS_TYPE>() )

View File

@ -30,4 +30,25 @@ private:
PyThreadState* m_state; PyThreadState* m_state;
}; };
class AutoSavePythonState
{
public:
explicit AutoSavePythonState(PyThreadState **state) {
PyEval_RestoreThread(*state);
m_state = state;
}
~AutoSavePythonState() {
*m_state = PyEval_SaveThread();
}
private:
PyThreadState** m_state;
};
} }

View File

@ -25,9 +25,9 @@ bool PykdExt::isInit() {
extern "C" void initpykd(); extern "C" void initpykd();
pykd::DbgOut pykdOut; //pykd::DbgOut pykdOut;
pykd::DbgOut pykdErr; //pykd::DbgOut pykdErr;
pykd::DbgIn pykdIn; //pykd::DbgIn pykdIn;
void PykdExt::setUp() void PykdExt::setUp()
@ -58,16 +58,16 @@ void PykdExt::setUp()
main_namespace[ key ] = pykd_namespace[ key ]; main_namespace[ key ] = pykd_namespace[ key ];
} }
// ïåðåíàïðàâëåíèå ñòàíäàðòíûõ ïîòîêîâ ÂÂ //// ïåðåíàïðàâëåíèå ñòàíäàðòíûõ ïîòîêîâ ÂÂ
kdlib::dbgout =&pykdOut; //kdlib::dbgout =&pykdOut;
kdlib::dbgerr = &pykdErr; //kdlib::dbgerr = &pykdErr;
kdlib::dbgin = &pykdIn; //kdlib::dbgin = &pykdIn;
python::object sys = python::import("sys"); python::object sys = python::import("sys");
sys.attr("stdout") = python::object( &pykdOut ); sys.attr("stdout") = python::object( pykd::DbgOut() );
sys.attr("stderr") = python::object( &pykdErr ); sys.attr("stderr") = python::object( pykd::DbgOut() );
sys.attr("stdin") = python::object( &pykdIn ); sys.attr("stdin") = python::object( pykd::DbgIn() );
python::list pathList(sys.attr("path")); python::list pathList(sys.attr("path"));