[0.3.x] fixed : process restart raises exception

git-svn-id: https://pykd.svn.codeplex.com/svn@90463 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\ussrhero_cp 2015-04-22 22:30:39 +00:00 committed by Mikhail I. Izmestev
parent 20a171ebda
commit 516095649c
3 changed files with 132 additions and 82 deletions

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 23 #define PYKD_VERSION_BUILDNO 24
#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

@ -1,11 +1,22 @@
// dllmain.cpp : Defines the entry point for the DLL application. // dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h" #include "stdafx.h"
static HMODULE pinHandle = NULL;
BOOL APIENTRY DllMain( HMODULE hModule, BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call, DWORD ul_reason_for_call,
LPVOID lpReserved LPVOID lpReserved
) )
{ {
if (!pinHandle)
{
GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
(LPCTSTR)hModule,
&pinHandle);
}
switch (ul_reason_for_call) switch (ul_reason_for_call)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:

View File

@ -10,36 +10,6 @@ using namespace kdlib;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class PykdBootsTrapper: public windbg::WindbgExtension
{
public:
KDLIB_EXT_COMMAND_METHOD(py);
KDLIB_EXT_COMMAND_METHOD(install);
KDLIB_EXT_COMMAND_METHOD(upgrade);
virtual void setUp();
virtual void tearDown();
private:
void printUsage();
void printException();
std::string getScriptFileName(const std::string &scriptName);
std::string findScript(const std::string &fullFileName);
PyThreadState *m_pyState;
bool m_pykdInitialized;
};
///////////////////////////////////////////////////////////////////////////////
class AutoRestorePyState class AutoRestorePyState
{ {
public: public:
@ -65,6 +35,7 @@ private:
PyThreadState* m_state; PyThreadState* m_state;
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class DbgOut : public windbg::WindbgOut class DbgOut : public windbg::WindbgOut
@ -105,6 +76,102 @@ public:
} }
}; };
///////////////////////////////////////////////////////////////////////////////
class PythonSingleton
{
public:
static PythonSingleton* get() {
if (!m_instance)
m_instance = new PythonSingleton();
return m_instance;
}
void beginPythonCode()
{
PyEval_RestoreThread(m_pyState);
}
void endPythonCode()
{
m_pyState = PyEval_SaveThread();
}
private:
PythonSingleton()
{
PyEval_InitThreads();
Py_Initialize();
python::object main = boost::python::import("__main__");
python::object main_namespace = main.attr("__dict__");
// Python debug output console helper classes
python::class_<::DbgOut>("dout", "dout", python::no_init)
.def("write", &::DbgOut::write)
.def("writedml", &::DbgOut::writedml)
.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);
python::object sys = python::import("sys");
sys.attr("stdout") = python::object(::DbgOut());
sys.attr("stderr") = python::object(::DbgOut());
sys.attr("stdin") = python::object(::DbgIn());
m_pyState = PyEval_SaveThread();
}
static PythonSingleton* m_instance;
PyThreadState *m_pyState;
};
PythonSingleton* PythonSingleton::m_instance = 0;
///////////////////////////////////////////////////////////////////////////////
class PykdBootsTrapper: public windbg::WindbgExtension
{
public:
KDLIB_EXT_COMMAND_METHOD(py);
KDLIB_EXT_COMMAND_METHOD(install);
KDLIB_EXT_COMMAND_METHOD(upgrade);
virtual void setUp();
virtual void tearDown();
private:
void printUsage();
void printException();
std::string getScriptFileName(const std::string &scriptName);
std::string findScript(const std::string &fullFileName);
bool m_pykdInitialized;
};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class InterruptWatch : public windbg::InterruptWatch class InterruptWatch : public windbg::InterruptWatch
@ -168,12 +235,11 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, py)
PyThreadState *localState = NULL; PyThreadState *localState = NULL;
PyThreadState *globalState = NULL; PyThreadState *globalState = NULL;
PyEval_RestoreThread(m_pyState);
try { try {
InterruptWatch interruptWatch; InterruptWatch interruptWatch;
PythonSingleton::get()->beginPythonCode();
std::string scriptFileName; std::string scriptFileName;
if (args.size() > 0) if (args.size() > 0)
@ -182,11 +248,9 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, py)
if (scriptFileName.empty()) if (scriptFileName.empty())
{ {
m_pyState = PyEval_SaveThread();
kdlib::eprintln(L"script file not found"); kdlib::eprintln(L"script file not found");
return; python::throw_error_already_set();
} }
global = !(global || local) ? false : global; //set local by default global = !(global || local) ? false : global; //set local by default
@ -279,15 +343,14 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, py)
PyThreadState_Swap(globalState); PyThreadState_Swap(globalState);
} }
m_pyState = PyEval_SaveThread(); PythonSingleton::get()->endPythonCode();
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, install) KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, install)
{ {
PyEval_RestoreThread(m_pyState); PythonSingleton::get()->beginPythonCode();
try { try {
@ -308,24 +371,21 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, install)
printException(); printException();
} }
m_pyState = PyEval_SaveThread(); PythonSingleton::get()->endPythonCode();
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, upgrade) KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, upgrade)
{ {
PyEval_RestoreThread(m_pyState); PythonSingleton::get()->beginPythonCode();
try { try {
InterruptWatch interruptWatch; InterruptWatch interruptWatch;
// ïîëó÷àåì äîñòóï ê ãëîáàëüíîìó ìàïó ( íóæåí äëÿ âûçîâà exec_file )
python::object main = python::import("__main__"); python::object main = python::import("__main__");
python::object global(main.attr("__dict__")); python::object global(main.attr("__dict__"));
python::exec("import pip\n", global); python::exec("import pip\n", global);
python::exec("pip.logger.consumers = []\n", global); python::exec("pip.logger.consumers = []\n", global);
python::exec("pip.main(['install', '--upgrade', 'pykd'])\n", global); python::exec("pip.main(['install', '--upgrade', 'pykd'])\n", global);
@ -335,58 +395,37 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, upgrade)
printException(); printException();
} }
m_pyState = PyEval_SaveThread(); PythonSingleton::get()->endPythonCode();
} }
/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
void PykdBootsTrapper::setUp() void PykdBootsTrapper::setUp()
{ {
WindbgExtension::setUp(); WindbgExtension::setUp();
PyEval_InitThreads();
Py_Initialize();
python::object main = boost::python::import("__main__");
python::object main_namespace = main.attr("__dict__");
// Python debug output console helper classes
python::class_<::DbgOut>("dout", "dout", python::no_init)
.def("write", &::DbgOut::write)
.def("writedml", &::DbgOut::writedml)
.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);
python::object sys = python::import("sys");
sys.attr("stdout") = python::object(::DbgOut());
sys.attr("stderr") = python::object(::DbgOut());
sys.attr("stdin") = python::object(::DbgIn());
m_pyState = PyEval_SaveThread();
} }
/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
void PykdBootsTrapper::tearDown() void PykdBootsTrapper::tearDown()
{ {
PyEval_RestoreThread(m_pyState);
if (m_pykdInitialized) if (m_pykdInitialized)
{ {
python::object main = python::import("__main__"); PythonSingleton::get()->beginPythonCode();
python::object globalScope(main.attr("__dict__"));
python::exec("__import__('pykd').deinitialize()", globalScope);
m_pykdInitialized = false;
}
// Py_Finalize(); try {
python::object main = python::import("__main__");
python::object global(main.attr("__dict__"));
python::exec("__import__('pykd').deinitialize()", global);
m_pykdInitialized = false;
}
catch (python::error_already_set const &)
{
printException();
}
PythonSingleton::get()->endPythonCode();
}
WindbgExtension::tearDown(); WindbgExtension::tearDown();
} }