[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:
SND\kernelnet_cp 2013-10-25 12:08:20 +00:00 committed by Mikhail I. Izmestev
parent f98b8c60bc
commit 2115053907
7 changed files with 222 additions and 58 deletions

View File

@ -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;
};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -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" />

View File

@ -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">

View File

@ -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,

View File

@ -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;

View File

@ -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
View 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()