From 516095649c4767effa3e45f20898f11c75f6a328 Mon Sep 17 00:00:00 2001 From: "SND\\ussrhero_cp" Date: Wed, 22 Apr 2015 22:30:39 +0000 Subject: [PATCH] [0.3.x] fixed : process restart raises exception git-svn-id: https://pykd.svn.codeplex.com/svn@90463 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/pykdver.h | 2 +- pykd_bootstrapper/dllmain.cpp | 11 ++ pykd_bootstrapper/windbgext.cpp | 201 +++++++++++++++++++------------- 3 files changed, 132 insertions(+), 82 deletions(-) diff --git a/pykd/pykdver.h b/pykd/pykdver.h index 75a2745..7c60e11 100644 --- a/pykd/pykdver.h +++ b/pykd/pykdver.h @@ -2,7 +2,7 @@ #define PYKD_VERSION_MAJOR 0 #define PYKD_VERSION_MINOR 3 #define PYKD_VERSION_SUBVERSION 0 -#define PYKD_VERSION_BUILDNO 23 +#define PYKD_VERSION_BUILDNO 24 #define __VER_STR2__(x) #x #define __VER_STR1__(x) __VER_STR2__(x) diff --git a/pykd_bootstrapper/dllmain.cpp b/pykd_bootstrapper/dllmain.cpp index 8a4edd3..6284baf 100644 --- a/pykd_bootstrapper/dllmain.cpp +++ b/pykd_bootstrapper/dllmain.cpp @@ -1,11 +1,22 @@ // dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.h" + +static HMODULE pinHandle = NULL; + BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, 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) { case DLL_PROCESS_ATTACH: diff --git a/pykd_bootstrapper/windbgext.cpp b/pykd_bootstrapper/windbgext.cpp index dd601c9..00b42dd 100644 --- a/pykd_bootstrapper/windbgext.cpp +++ b/pykd_bootstrapper/windbgext.cpp @@ -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 { public: @@ -65,6 +35,7 @@ private: PyThreadState* m_state; }; + /////////////////////////////////////////////////////////////////////////////// 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 @@ -168,12 +235,11 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, py) PyThreadState *localState = NULL; PyThreadState *globalState = NULL; - PyEval_RestoreThread(m_pyState); - try { InterruptWatch interruptWatch; + PythonSingleton::get()->beginPythonCode(); std::string scriptFileName; if (args.size() > 0) @@ -182,11 +248,9 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, py) if (scriptFileName.empty()) { - m_pyState = PyEval_SaveThread(); - kdlib::eprintln(L"script file not found"); - return; + python::throw_error_already_set(); } global = !(global || local) ? false : global; //set local by default @@ -279,15 +343,14 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, py) PyThreadState_Swap(globalState); } - m_pyState = PyEval_SaveThread(); - + PythonSingleton::get()->endPythonCode(); } /////////////////////////////////////////////////////////////////////////////// KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, install) { - PyEval_RestoreThread(m_pyState); + PythonSingleton::get()->beginPythonCode(); try { @@ -308,24 +371,21 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, install) printException(); } - m_pyState = PyEval_SaveThread(); + PythonSingleton::get()->endPythonCode(); } /////////////////////////////////////////////////////////////////////////////// KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, upgrade) { - PyEval_RestoreThread(m_pyState); + PythonSingleton::get()->beginPythonCode(); try { InterruptWatch interruptWatch; - // получаем доступ к глобальному мапу ( нужен для вызова exec_file ) python::object main = python::import("__main__"); - python::object global(main.attr("__dict__")); - python::exec("import pip\n", global); python::exec("pip.logger.consumers = []\n", global); python::exec("pip.main(['install', '--upgrade', 'pykd'])\n", global); @@ -335,58 +395,37 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdBootsTrapper, upgrade) printException(); } - m_pyState = PyEval_SaveThread(); + PythonSingleton::get()->endPythonCode(); } -/////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// void PykdBootsTrapper::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() { - PyEval_RestoreThread(m_pyState); - if (m_pykdInitialized) { - python::object main = python::import("__main__"); - python::object globalScope(main.attr("__dict__")); - python::exec("__import__('pykd').deinitialize()", globalScope); - m_pykdInitialized = false; - } + PythonSingleton::get()->beginPythonCode(); - // 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(); }