mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[0.3.x] added : !py command commandline arguments ( -g -l -h )
git-svn-id: https://pykd.svn.codeplex.com/svn@86005 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
f98b8c60bc
commit
2115053907
@ -5,27 +5,10 @@
|
|||||||
|
|
||||||
#include "dbgengine.h"
|
#include "dbgengine.h"
|
||||||
#include "variant.h"
|
#include "variant.h"
|
||||||
|
#include "pystate.h"
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
class AutoRestorePyState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
AutoRestorePyState()
|
|
||||||
{
|
|
||||||
m_state = PyEval_SaveThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
~AutoRestorePyState()
|
|
||||||
{
|
|
||||||
PyEval_RestoreThread( m_state );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
PyThreadState* m_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -239,6 +239,8 @@
|
|||||||
<ClInclude Include="eventhandler.h" />
|
<ClInclude Include="eventhandler.h" />
|
||||||
<ClInclude Include="memaccess.h" />
|
<ClInclude Include="memaccess.h" />
|
||||||
<ClInclude Include="module.h" />
|
<ClInclude Include="module.h" />
|
||||||
|
<ClInclude Include="pydbgio.h" />
|
||||||
|
<ClInclude Include="pystate.h" />
|
||||||
<ClInclude Include="stdafx.h" />
|
<ClInclude Include="stdafx.h" />
|
||||||
<ClInclude Include="stladaptor.h" />
|
<ClInclude Include="stladaptor.h" />
|
||||||
<ClInclude Include="targetver.h" />
|
<ClInclude Include="targetver.h" />
|
||||||
|
@ -54,6 +54,12 @@
|
|||||||
<ClInclude Include="cpucontext.h">
|
<ClInclude Include="cpucontext.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="pydbgio.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="pystate.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "windbgext.h"
|
#include "windbgext.h"
|
||||||
#include "eventhandler.h"
|
#include "eventhandler.h"
|
||||||
#include "cpucontext.h"
|
#include "cpucontext.h"
|
||||||
|
#include "pydbgio.h"
|
||||||
|
|
||||||
using namespace pykd;
|
using namespace pykd;
|
||||||
|
|
||||||
@ -132,10 +133,14 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
|
"Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
|
||||||
|
|
||||||
// Python debug output console helper classes
|
// Python debug output console helper classes
|
||||||
python::class_<kdlib::DbgOut, boost::noncopyable >( "dout", "dout", python::no_init )
|
python::class_<DbgOut>( "dout", "dout", python::no_init )
|
||||||
.def( "write", &kdlib::DbgOut::write );
|
.def( "write", &DbgOut::write )
|
||||||
python::class_<kdlib::DbgIn, boost::noncopyable>( "din", "din", python::no_init )
|
.def( "flush", &DbgOut::flush )
|
||||||
.def( "readline", &kdlib::DbgIn::readline );
|
.add_property( "encoding", &DbgOut::encoding );
|
||||||
|
|
||||||
|
python::class_<DbgIn>( "din", "din", python::no_init )
|
||||||
|
.def( "readline", &DbgIn::readline )
|
||||||
|
.add_property( "encoding", &DbgIn::encoding );
|
||||||
|
|
||||||
// system properties
|
// system properties
|
||||||
python::def( "ptrSize", &kdlib::ptrSize,
|
python::def( "ptrSize", &kdlib::ptrSize,
|
||||||
|
@ -9,6 +9,7 @@ namespace python = boost::python;
|
|||||||
|
|
||||||
#include "windbgext.h"
|
#include "windbgext.h"
|
||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
|
#include "pydbgio.h"
|
||||||
|
|
||||||
using namespace kdlib;
|
using namespace kdlib;
|
||||||
using namespace kdlib::windbg;
|
using namespace kdlib::windbg;
|
||||||
@ -32,19 +33,34 @@ void PykdExt::setUp()
|
|||||||
|
|
||||||
PyImport_AppendInittab("pykd", initpykd );
|
PyImport_AppendInittab("pykd", initpykd );
|
||||||
|
|
||||||
Py_Initialize();
|
|
||||||
|
|
||||||
PyEval_InitThreads();
|
PyEval_InitThreads();
|
||||||
|
|
||||||
python::import( "pykd" );
|
Py_Initialize();
|
||||||
|
|
||||||
|
python::object main = boost::python::import("__main__");
|
||||||
|
|
||||||
|
python::object main_namespace = main.attr("__dict__");
|
||||||
|
|
||||||
|
python::object pykd = python::import( "pykd" );
|
||||||
|
|
||||||
|
// äåëàåì àíàëîã from pykd import *
|
||||||
|
python::dict pykd_namespace( pykd.attr("__dict__") );
|
||||||
|
|
||||||
|
python::list iterkeys( pykd_namespace.iterkeys() );
|
||||||
|
|
||||||
|
for (int i = 0; i < boost::python::len(iterkeys); i++)
|
||||||
|
{
|
||||||
|
std::string key = boost::python::extract<std::string>(iterkeys[i]);
|
||||||
|
|
||||||
|
main_namespace[ key ] = pykd_namespace[ key ];
|
||||||
|
}
|
||||||
|
|
||||||
// ïåðåíàïðàâëåíèå ñòàíäàðòíûõ ïîòîêîâ ÂÂ
|
// ïåðåíàïðàâëåíèå ñòàíäàðòíûõ ïîòîêîâ ÂÂ
|
||||||
python::object sys = python::import("sys");
|
python::object sys = python::import("sys");
|
||||||
|
|
||||||
sys.attr("stdout") = python::ptr( dbgout );
|
sys.attr("stdout") = python::object( pykd::DbgOut() );
|
||||||
sys.attr("stderr") = python::ptr( dbgout );
|
sys.attr("stderr") = python::object( pykd::DbgOut() );
|
||||||
sys.attr("stdin") = python::ptr( dbgin );
|
sys.attr("stdin") = python::object( pykd::DbgIn() );
|
||||||
|
|
||||||
|
|
||||||
python::list pathList(sys.attr("path"));
|
python::list pathList(sys.attr("path"));
|
||||||
|
|
||||||
@ -52,12 +68,16 @@ void PykdExt::setUp()
|
|||||||
|
|
||||||
for (python::ssize_t i = 0; i < n ; i++)
|
for (python::ssize_t i = 0; i < n ; i++)
|
||||||
m_paths.push_back(boost::python::extract<std::string>(pathList[i]));
|
m_paths.push_back(boost::python::extract<std::string>(pathList[i]));
|
||||||
|
|
||||||
|
m_pyState = PyEval_SaveThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void PykdExt::tearDown()
|
void PykdExt::tearDown()
|
||||||
{
|
{
|
||||||
|
PyEval_RestoreThread( m_pyState );
|
||||||
|
|
||||||
Py_Finalize();
|
Py_Finalize();
|
||||||
|
|
||||||
WindbgExtension::tearDown();
|
WindbgExtension::tearDown();
|
||||||
@ -67,45 +87,157 @@ void PykdExt::tearDown()
|
|||||||
|
|
||||||
KDLIB_EXT_COMMAND_METHOD_IMPL(PykdExt, py)
|
KDLIB_EXT_COMMAND_METHOD_IMPL(PykdExt, py)
|
||||||
{
|
{
|
||||||
const ArgsList& args = getArgs();
|
ArgsList args = getArgs();
|
||||||
|
|
||||||
|
bool global = false;
|
||||||
|
bool local = false;
|
||||||
|
bool clean = false;
|
||||||
|
|
||||||
|
ArgsList::iterator foundArg;
|
||||||
|
|
||||||
|
foundArg = std::find( args.begin(), args.end(), "-h" );
|
||||||
|
if ( foundArg != args.end() )
|
||||||
|
{
|
||||||
|
printUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foundArg = std::find( args.begin(), args.end(), "--help" );
|
||||||
|
if ( foundArg != args.end() )
|
||||||
|
{
|
||||||
|
printUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foundArg = std::find( args.begin(), args.end(), "-g" );
|
||||||
|
if ( foundArg != args.end() )
|
||||||
|
{
|
||||||
|
global = true;
|
||||||
|
args.erase( foundArg );
|
||||||
|
}
|
||||||
|
|
||||||
|
foundArg = std::find( args.begin(), args.end(), "--global" );
|
||||||
|
if ( foundArg != args.end() )
|
||||||
|
{
|
||||||
|
global = true;
|
||||||
|
args.erase( foundArg );
|
||||||
|
}
|
||||||
|
|
||||||
|
foundArg = std::find( args.begin(), args.end(), "-l" );
|
||||||
|
if ( foundArg != args.end() )
|
||||||
|
{
|
||||||
|
local = true;
|
||||||
|
args.erase( foundArg );
|
||||||
|
}
|
||||||
|
|
||||||
|
foundArg = std::find( args.begin(), args.end(), "--local" );
|
||||||
|
if ( foundArg != args.end() )
|
||||||
|
{
|
||||||
|
local = true;
|
||||||
|
args.erase( foundArg );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( global & local )
|
||||||
|
{
|
||||||
|
eprintln( L"-g(--global) and -l(--local) cannot be set together" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string scriptFileName;
|
||||||
|
if ( args.size() > 0 )
|
||||||
|
{
|
||||||
|
scriptFileName = getScriptFileName( args[0] );
|
||||||
|
|
||||||
|
if ( scriptFileName.empty() )
|
||||||
|
{
|
||||||
|
eprintln( L"script file not found" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
global = !(global | local ) ? false : global ; //set local by default
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
global = !(global | local ) ? true : global ; //set global by default
|
||||||
|
}
|
||||||
|
|
||||||
|
PyThreadState *localState = NULL;
|
||||||
|
PyThreadState *globalState = NULL;
|
||||||
|
|
||||||
|
PyEval_RestoreThread( m_pyState );
|
||||||
|
|
||||||
|
if ( !global )
|
||||||
|
{
|
||||||
|
globalState = PyThreadState_Swap( NULL );
|
||||||
|
|
||||||
|
localState = Py_NewInterpreter();
|
||||||
|
|
||||||
|
python::object sys = python::import("sys");
|
||||||
|
|
||||||
|
sys.attr("stdout") = python::object( pykd::DbgOut() );
|
||||||
|
sys.attr("stderr") = python::object( pykd::DbgOut() );
|
||||||
|
sys.attr("stdin") = python::object( pykd::DbgIn() );
|
||||||
|
}
|
||||||
|
|
||||||
if ( args.size() == 0 )
|
if ( args.size() == 0 )
|
||||||
{
|
{
|
||||||
startConsole();
|
startConsole();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
std::string scriptFileName = getScriptFileName( args[0] );
|
|
||||||
|
|
||||||
if ( scriptFileName.empty() )
|
|
||||||
{
|
{
|
||||||
eprintln( L"script file not found" );
|
std::string scriptFileName = getScriptFileName( args[0] );
|
||||||
return;
|
|
||||||
|
// óñòàíàâèëèâàåì ïèòîíîâñêèå àðãóìåíòû
|
||||||
|
char **pythonArgs = new char* [ args.size() ];
|
||||||
|
|
||||||
|
pythonArgs[0] = const_cast<char*>(scriptFileName.c_str());
|
||||||
|
|
||||||
|
for ( size_t i = 1; i < args.size(); ++i )
|
||||||
|
pythonArgs[i] = const_cast<char*>( args[i].c_str() );
|
||||||
|
|
||||||
|
PySys_SetArgv( (int)args.size(), pythonArgs );
|
||||||
|
|
||||||
|
delete[] pythonArgs;
|
||||||
|
|
||||||
|
// ïîëó÷àåì äîñòïó ê ãëîáàëüíîìó ìàïó ( íóæåí äëÿ âûçîâà exec_file )
|
||||||
|
python::object main = python::import("__main__");
|
||||||
|
|
||||||
|
python::object global(main.attr("__dict__"));
|
||||||
|
|
||||||
|
try {
|
||||||
|
PykdInterruptWatch interruptWatch;
|
||||||
|
python::exec_file( scriptFileName.c_str(), global );
|
||||||
|
}
|
||||||
|
catch( python::error_already_set const & )
|
||||||
|
{
|
||||||
|
printException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// óñòàíàâèëèâàåì ïèòîíîâñêèå àðãóìåíòû
|
if ( !global )
|
||||||
char **pythonArgs = new char* [ args.size() ];
|
|
||||||
|
|
||||||
for ( size_t i = 0; i < args.size(); ++i )
|
|
||||||
pythonArgs[i] = const_cast<char*>( args[i].c_str() );
|
|
||||||
|
|
||||||
PySys_SetArgv( (int)args.size(), pythonArgs );
|
|
||||||
|
|
||||||
delete[] pythonArgs;
|
|
||||||
|
|
||||||
// ïîëó÷àåì äîñòïó ê ãëîáàëüíîìó ìàïó ( íóæåí äëÿ âûçîâà exec_file )
|
|
||||||
python::object main = python::import("__main__");
|
|
||||||
|
|
||||||
python::object global(main.attr("__dict__"));
|
|
||||||
|
|
||||||
try {
|
|
||||||
PykdInterruptWatch interruptWatch;
|
|
||||||
python::exec_file( scriptFileName.c_str(), global );
|
|
||||||
}
|
|
||||||
catch( python::error_already_set const & )
|
|
||||||
{
|
{
|
||||||
printException();
|
PyInterpreterState *interpreter = localState->interp;
|
||||||
|
|
||||||
|
while( interpreter->tstate_head != NULL )
|
||||||
|
{
|
||||||
|
PyThreadState *threadState = (PyThreadState*)(interpreter->tstate_head);
|
||||||
|
|
||||||
|
PyThreadState_Clear(threadState);
|
||||||
|
|
||||||
|
PyThreadState_Swap( NULL );
|
||||||
|
|
||||||
|
PyThreadState_Delete(threadState);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyInterpreterState_Clear(interpreter);
|
||||||
|
|
||||||
|
PyInterpreterState_Delete(interpreter);
|
||||||
|
|
||||||
|
PyThreadState_Swap( globalState );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_pyState = PyEval_SaveThread();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -130,6 +262,16 @@ void PykdExt::startConsole()
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void PykdExt::printUsage()
|
||||||
|
{
|
||||||
|
dprintln( L"usage: !py [options] [file]" );
|
||||||
|
dprintln( L"Options:" );
|
||||||
|
dprintln( L"-g --global : run code in the common namespace" );
|
||||||
|
dprintln( L"-l --local : run code in the isolate namespace" );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string PykdExt::getScriptFileName( const std::string &scriptName )
|
std::string PykdExt::getScriptFileName( const std::string &scriptName )
|
||||||
{
|
{
|
||||||
bool fileHasPyExt = false;
|
bool fileHasPyExt = false;
|
||||||
|
@ -18,6 +18,8 @@ private:
|
|||||||
|
|
||||||
void startConsole();
|
void startConsole();
|
||||||
|
|
||||||
|
void printUsage();
|
||||||
|
|
||||||
virtual void setUp();
|
virtual void setUp();
|
||||||
|
|
||||||
virtual void tearDown();
|
virtual void tearDown();
|
||||||
@ -25,6 +27,8 @@ private:
|
|||||||
std::string getScriptFileName( const std::string &scriptName );
|
std::string getScriptFileName( const std::string &scriptName );
|
||||||
|
|
||||||
std::vector<std::string> m_paths;
|
std::vector<std::string> m_paths;
|
||||||
|
|
||||||
|
PyThreadState *m_pyState;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
22
snippets/ipython.py
Normal file
22
snippets/ipython.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from IPython.config.loader import Config
|
||||||
|
from IPython.terminal.embed import InteractiveShellEmbed
|
||||||
|
|
||||||
|
from IPython.terminal.interactiveshell import TerminalInteractiveShell
|
||||||
|
|
||||||
|
import pykd
|
||||||
|
|
||||||
|
cfg = Config()
|
||||||
|
|
||||||
|
cfg.InteractiveShell.colors = 'NoColor'
|
||||||
|
cfg.InteractiveShell.readline_use = False
|
||||||
|
cfg.InteractiveShell.autoindent = True
|
||||||
|
|
||||||
|
cfg.PromptManager.in_template = 'In <\\#>: '
|
||||||
|
cfg.PromptManager.in2_template = ' .\\D.: '
|
||||||
|
cfg.PromptManager.out_template = 'Out<\\#>: '
|
||||||
|
|
||||||
|
cfg.InteractiveShellApp.extensions = [ 'pykdmagic' ]
|
||||||
|
|
||||||
|
ipshell = InteractiveShellEmbed(config=cfg)
|
||||||
|
|
||||||
|
ipshell()
|
Loading…
Reference in New Issue
Block a user