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 "variant.h"
|
||||
#include "pystate.h"
|
||||
|
||||
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="memaccess.h" />
|
||||
<ClInclude Include="module.h" />
|
||||
<ClInclude Include="pydbgio.h" />
|
||||
<ClInclude Include="pystate.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="stladaptor.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
|
@ -54,6 +54,12 @@
|
||||
<ClInclude Include="cpucontext.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pydbgio.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pystate.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "windbgext.h"
|
||||
#include "eventhandler.h"
|
||||
#include "cpucontext.h"
|
||||
#include "pydbgio.h"
|
||||
|
||||
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 )" ) );
|
||||
|
||||
// Python debug output console helper classes
|
||||
python::class_<kdlib::DbgOut, boost::noncopyable >( "dout", "dout", python::no_init )
|
||||
.def( "write", &kdlib::DbgOut::write );
|
||||
python::class_<kdlib::DbgIn, boost::noncopyable>( "din", "din", python::no_init )
|
||||
.def( "readline", &kdlib::DbgIn::readline );
|
||||
python::class_<DbgOut>( "dout", "dout", python::no_init )
|
||||
.def( "write", &DbgOut::write )
|
||||
.def( "flush", &DbgOut::flush )
|
||||
.add_property( "encoding", &DbgOut::encoding );
|
||||
|
||||
python::class_<DbgIn>( "din", "din", python::no_init )
|
||||
.def( "readline", &DbgIn::readline )
|
||||
.add_property( "encoding", &DbgIn::encoding );
|
||||
|
||||
// system properties
|
||||
python::def( "ptrSize", &kdlib::ptrSize,
|
||||
|
@ -9,6 +9,7 @@ namespace python = boost::python;
|
||||
|
||||
#include "windbgext.h"
|
||||
#include "dbgexcept.h"
|
||||
#include "pydbgio.h"
|
||||
|
||||
using namespace kdlib;
|
||||
using namespace kdlib::windbg;
|
||||
@ -32,19 +33,34 @@ void PykdExt::setUp()
|
||||
|
||||
PyImport_AppendInittab("pykd", initpykd );
|
||||
|
||||
Py_Initialize();
|
||||
|
||||
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");
|
||||
|
||||
sys.attr("stdout") = python::ptr( dbgout );
|
||||
sys.attr("stderr") = python::ptr( dbgout );
|
||||
sys.attr("stdin") = python::ptr( dbgin );
|
||||
|
||||
sys.attr("stdout") = python::object( pykd::DbgOut() );
|
||||
sys.attr("stderr") = python::object( pykd::DbgOut() );
|
||||
sys.attr("stdin") = python::object( pykd::DbgIn() );
|
||||
|
||||
python::list pathList(sys.attr("path"));
|
||||
|
||||
@ -52,12 +68,16 @@ void PykdExt::setUp()
|
||||
|
||||
for (python::ssize_t i = 0; i < n ; i++)
|
||||
m_paths.push_back(boost::python::extract<std::string>(pathList[i]));
|
||||
|
||||
m_pyState = PyEval_SaveThread();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PykdExt::tearDown()
|
||||
{
|
||||
PyEval_RestoreThread( m_pyState );
|
||||
|
||||
Py_Finalize();
|
||||
|
||||
WindbgExtension::tearDown();
|
||||
@ -67,45 +87,157 @@ void PykdExt::tearDown()
|
||||
|
||||
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 )
|
||||
{
|
||||
startConsole();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string scriptFileName = getScriptFileName( args[0] );
|
||||
|
||||
if ( scriptFileName.empty() )
|
||||
else
|
||||
{
|
||||
eprintln( L"script file not found" );
|
||||
return;
|
||||
std::string scriptFileName = getScriptFileName( args[0] );
|
||||
|
||||
// óñòàíàâèëèâàåì ïèòîíîâñêèå àðãóìåíòû
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
// óñòàíàâèëèâàåì ïèòîíîâñêèå àðãóìåíòû
|
||||
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 & )
|
||||
if ( !global )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
bool fileHasPyExt = false;
|
||||
|
@ -18,6 +18,8 @@ private:
|
||||
|
||||
void startConsole();
|
||||
|
||||
void printUsage();
|
||||
|
||||
virtual void setUp();
|
||||
|
||||
virtual void tearDown();
|
||||
@ -25,6 +27,8 @@ private:
|
||||
std::string getScriptFileName( const std::string &scriptName );
|
||||
|
||||
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