From 85a36df11e177bcadece2962e5fe0f5355db9ed1 Mon Sep 17 00:00:00 2001 From: "SND\\ussrhero_cp" Date: Sat, 1 Oct 2016 10:12:57 +0000 Subject: [PATCH] [pykd_ext_2.0] added : python version can be note in the first script line ( shebang line ) git-svn-id: https://pykd.svn.codeplex.com/svn@91049 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd_ext/arglist.cpp | 18 +++++++++++------- pykd_ext/arglist.h | 5 +---- pykd_ext/pyinterpret.cpp | 7 +++++-- pykd_ext/windbgext.cpp | 30 ++++++++++++++++++++++++++---- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/pykd_ext/arglist.cpp b/pykd_ext/arglist.cpp index a0b8b9b..69002c6 100644 --- a/pykd_ext/arglist.cpp +++ b/pykd_ext/arglist.cpp @@ -2,17 +2,18 @@ #include #include +#include #include "arglist.h" + +namespace { + typedef boost::escaped_list_separator char_separator_t; typedef boost::tokenizer< char_separator_t > char_tokenizer_t; - -ArgsList getArgsList(const char* args) +ArgsList getArgsList(const std::string& argsStr) { - std::string argsStr(args); - char_tokenizer_t token(argsStr, char_separator_t("", " \t", "\"")); ArgsList argsList; @@ -25,16 +26,19 @@ ArgsList getArgsList(const char* args) return argsList; } +} // anonymous namespace + + static const std::regex versionRe("^-([2,3])(?:\\.(\\d+))?$"); -Options::Options(const ArgsList& argList) : +Options::Options(const std::string& cmdline) : pyMajorVersion(-1), pyMinorVersion(-1), global(true), showHelp(false) { - args = argList; + args = getArgsList( cmdline ); for (auto it = args.begin(); it != args.end();) { @@ -72,7 +76,7 @@ Options::Options(const ArgsList& argList) : it = args.erase(it); continue; } - + break; } diff --git a/pykd_ext/arglist.h b/pykd_ext/arglist.h index e921f7f..bcd1768 100644 --- a/pykd_ext/arglist.h +++ b/pykd_ext/arglist.h @@ -5,8 +5,6 @@ typedef std::vector< std::string > ArgsList; -ArgsList getArgsList(const char* args); - struct Options { int pyMajorVersion; @@ -22,6 +20,5 @@ struct Options showHelp(false) {} - Options(const ArgsList& argList); - + Options(const std::string& cmdline); }; diff --git a/pykd_ext/pyinterpret.cpp b/pykd_ext/pyinterpret.cpp index 1e7e0e9..40d285d 100644 --- a/pykd_ext/pyinterpret.cpp +++ b/pykd_ext/pyinterpret.cpp @@ -197,7 +197,7 @@ public: { module->PyEval_RestoreThread(module->m_globalState); module->m_globalInterpreter = new PythonInterpreter(module); - } + } m_currentInterpter = module->m_globalInterpreter; m_currentIsGlobal = true; @@ -210,7 +210,8 @@ public: } m_currentInterpter->m_module->PyEval_RestoreThread(m_currentInterpter->m_state); - + m_currentInterpter->m_module->checkPykd(); + return m_currentInterpter; } @@ -544,6 +545,8 @@ void PyModule::checkPykd() } while( false); + PyErr_Clear(); + if (mainName) Py_DecRef(mainName); if (mainMod) Py_DecRef(mainMod); if (globals) Py_DecRef(globals); diff --git a/pykd_ext/windbgext.cpp b/pykd_ext/windbgext.cpp index d404778..9075fb5 100644 --- a/pykd_ext/windbgext.cpp +++ b/pykd_ext/windbgext.cpp @@ -2,7 +2,9 @@ #include #include +#include #include +#include #include @@ -265,6 +267,9 @@ help( ////////////////////////////////////////////////////////////////////////////// + +static const std::regex shebangRe("^#!\\s*python([2,3])(?:\\.(\\d))?$"); + extern "C" HRESULT CALLBACK @@ -279,7 +284,7 @@ py( try { - Options opts(getArgsList(args)); + Options opts(args); if (opts.showHelp) throw std::exception(printUsageMsg); @@ -287,6 +292,25 @@ py( int majorVersion = opts.pyMajorVersion; int minorVersion = opts.pyMinorVersion; + if ( opts.args.size() > 0 && majorVersion == -1 && minorVersion == -1 ) + { + std::ifstream scriptFile(opts.args[0]); + + std::string firstline; + std::getline(scriptFile, firstline); + + std::smatch mres; + if (std::regex_match(firstline, mres, shebangRe)) + { + majorVersion = atol(std::string(mres[1].first, mres[1].second).c_str()); + + if (mres[2].matched) + { + minorVersion = atol(std::string(mres[2].first, mres[2].second).c_str()); + } + } + } + getPythonVersion(majorVersion, minorVersion); AutoInterpreter autoInterpreter(opts.global, majorVersion, minorVersion); @@ -304,8 +328,6 @@ py( PyObjectRef mainMod = PyImport_Import(mainName); PyObjectRef globals = PyObject_GetAttrString(mainMod, "__dict__"); - checkPykd(); - InterruptWatch interruptWatch(client); if (opts.args.empty()) @@ -395,7 +417,7 @@ pip( try { - Options opts(getArgsList(args)); + Options opts(args); int majorVersion = opts.pyMajorVersion; int minorVersion = opts.pyMinorVersion;