mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +08:00
[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:
parent
f4473c8d89
commit
e4c8bd3ff9
@ -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 );
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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>() )
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -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"));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user