[pykd_ext_2.0] fixed : many bugs

git-svn-id: https://pykd.svn.codeplex.com/svn@90992 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\ussrhero_cp 2016-06-22 23:20:06 +00:00 committed by Mikhail I. Izmestev
parent 27db13b5de
commit cf9aa94082
4 changed files with 172 additions and 93 deletions

View File

@ -28,7 +28,7 @@ ArgsList getArgsList(const char* args)
static const std::regex versionRe("^-([2,3])(?:\\.(\\d+))?$"); static const std::regex versionRe("^-([2,3])(?:\\.(\\d+))?$");
Options::Options(const ArgsList& argList) : Options::Options(const ArgsList& argList) :
pyMajorVersion(2), pyMajorVersion(-1),
pyMinorVersion(-1), pyMinorVersion(-1),
global(true), global(true),
showHelp(false) showHelp(false)

View File

@ -4,6 +4,8 @@
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include <map> #include <map>
#include <set>
#include <algorithm>
#include "pymodule.h" #include "pymodule.h"
#include "pyclass.h" #include "pyclass.h"
@ -60,67 +62,67 @@ public:
PyObject* Py_None; PyObject* Py_None;
PyObject* PyExc_SystemExit; PyObject* PyExc_SystemExit;
void(__stdcall *Py_Initialize)(); void( *Py_Initialize)();
void(__stdcall *Py_Finalize)(); void( *Py_Finalize)();
PyThreadState* (__stdcall *Py_NewInterpreter)(); PyThreadState* ( *Py_NewInterpreter)();
void(__stdcall *Py_EndInterpreter)(PyThreadState *tstate); void( *Py_EndInterpreter)(PyThreadState *tstate);
PyObject* (__stdcall *PyEval_GetGlobals)(); PyObject* ( *PyEval_GetGlobals)();
PyObject* (__stdcall *PyImport_Import)(PyObject *name); PyObject* ( *PyImport_Import)(PyObject *name);
PyObject* (__stdcall *PyImport_ImportModule)(const char *name); PyObject* ( *PyImport_ImportModule)(const char *name);
void(__stdcall *PyEval_InitThreads)(); void( *PyEval_InitThreads)();
PyThreadState* (__stdcall *PyEval_SaveThread)(); PyThreadState* ( *PyEval_SaveThread)();
void(__stdcall *PyEval_RestoreThread)(PyThreadState *tstate); void( *PyEval_RestoreThread)(PyThreadState *tstate);
PyThreadState* (__stdcall *PyThreadState_Swap)(PyThreadState *tstate); PyThreadState* ( *PyThreadState_Swap)(PyThreadState *tstate);
PyObject* (__stdcall *PyRun_String)(const char *str, int start, PyObject *globals, PyObject *locals); PyObject* ( *PyRun_String)(const char *str, int start, PyObject *globals, PyObject *locals);
int(__stdcall *PyRun_SimpleString)(const char* str); int( *PyRun_SimpleString)(const char* str);
PyObject* (__stdcall *PyRun_File)(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals); PyObject* ( *PyRun_File)(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals);
PyObject* (__stdcall *PyDict_New)(); PyObject* ( *PyDict_New)();
int(__stdcall *PyDict_SetItemString)(PyObject *p, const char *key, PyObject *val); int( *PyDict_SetItemString)(PyObject *p, const char *key, PyObject *val);
PyObject*(__stdcall *PyDict_GetItemString)(PyObject *p, const char* key); PyObject*( *PyDict_GetItemString)(PyObject *p, const char* key);
void(__stdcall *Py_IncRef)(PyObject* object); void( *Py_IncRef)(PyObject* object);
void(__stdcall *Py_DecRef)(PyObject* object); void( *Py_DecRef)(PyObject* object);
PyObject* (__stdcall *PyObject_Call)(PyObject *callable_object, PyObject *args, PyObject *kw); PyObject* ( *PyObject_Call)(PyObject *callable_object, PyObject *args, PyObject *kw);
PyObject* (__stdcall *PyObject_GetAttr)(PyObject *object, PyObject *attr_name); PyObject* ( *PyObject_GetAttr)(PyObject *object, PyObject *attr_name);
PyObject* (__stdcall *PyObject_GetAttrString)(PyObject *object, const char *attr_name); PyObject* ( *PyObject_GetAttrString)(PyObject *object, const char *attr_name);
int(__stdcall *PyObject_SetAttr)(PyObject *object, PyObject *attr_name, PyObject *value); int( *PyObject_SetAttr)(PyObject *object, PyObject *attr_name, PyObject *value);
PyObject* (__stdcall *PyObject_CallObject)(PyObject *callable_object, PyObject *args); PyObject* ( *PyObject_CallObject)(PyObject *callable_object, PyObject *args);
PyObject* (__stdcall *PyTuple_New)(size_t len); PyObject* ( *PyTuple_New)(size_t len);
int(__stdcall *PyTuple_SetItem)(PyObject *p, size_t pos, PyObject *o); int( *PyTuple_SetItem)(PyObject *p, size_t pos, PyObject *o);
PyObject* (__stdcall *PyTuple_GetItem)(PyObject *p, size_t pos); PyObject* ( *PyTuple_GetItem)(PyObject *p, size_t pos);
size_t(__stdcall *PyTuple_Size)(PyObject *p); size_t( *PyTuple_Size)(PyObject *p);
PyObject* (__stdcall *PyCFunction_NewEx)(PyMethodDef *, PyObject *, PyObject *); PyObject* ( *PyCFunction_NewEx)(PyMethodDef *, PyObject *, PyObject *);
PyObject* (__stdcall *PySys_GetObject)(char *name); PyObject* ( *PySys_GetObject)(char *name);
int(__stdcall *PySys_SetObject)(char *name, PyObject *v); int( *PySys_SetObject)(char *name, PyObject *v);
void(__stdcall *PySys_SetArgv)(int argc, char **argv); void( *PySys_SetArgv)(int argc, char **argv);
void(__stdcall *PySys_SetArgv_Py3)(int argc, wchar_t **argv); void( *PySys_SetArgv_Py3)(int argc, wchar_t **argv);
PyObject* (__stdcall *PyString_FromString)(const char *v); PyObject* ( *PyString_FromString)(const char *v);
char* (__stdcall *PyString_AsString)(PyObject *string); char* ( *PyString_AsString)(PyObject *string);
void(__stdcall *PyErr_Fetch)(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback); void( *PyErr_Fetch)(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback);
void(__stdcall *PyErr_NormalizeException)(PyObject**exc, PyObject**val, PyObject**tb); void( *PyErr_NormalizeException)(PyObject**exc, PyObject**val, PyObject**tb);
void(__stdcall *PyErr_SetString)(PyObject *type, const char *message); void( *PyErr_SetString)(PyObject *type, const char *message);
void(__stdcall *PyErr_Clear)(); void( *PyErr_Clear)();
PyObject* (__stdcall *PyImport_AddModule)(const char *name); PyObject* ( *PyImport_AddModule)(const char *name);
PyObject* (__stdcall *PyClass_New)(PyObject* className, PyObject* classBases, PyObject* classDict); PyObject* ( *PyClass_New)(PyObject* className, PyObject* classBases, PyObject* classDict);
PyObject* (__stdcall *PyInstance_New)(PyObject *classobj, PyObject *arg, PyObject *kw); PyObject* ( *PyInstance_New)(PyObject *classobj, PyObject *arg, PyObject *kw);
PyObject* (__stdcall *PyMethod_New)(PyObject *func, PyObject *self, PyObject *classobj); PyObject* ( *PyMethod_New)(PyObject *func, PyObject *self, PyObject *classobj);
PyObject* (__stdcall *PyCapsule_New)(void *pointer, const char *name, PyCapsule_Destructor destructor); PyObject* ( *PyCapsule_New)(void *pointer, const char *name, PyCapsule_Destructor destructor);
void* (__stdcall *PyCapsule_GetPointer)(PyObject *capsule, const char *name); void* ( *PyCapsule_GetPointer)(PyObject *capsule, const char *name);
int(__stdcall *PyObject_SetAttrString)(PyObject *o, const char *attr_name, PyObject *v); int( *PyObject_SetAttrString)(PyObject *o, const char *attr_name, PyObject *v);
PyObject* (__stdcall *PyUnicode_FromWideChar)(const wchar_t *w, size_t size); PyObject* ( *PyUnicode_FromWideChar)(const wchar_t *w, size_t size);
PyObject* (__stdcall *PyBool_FromLong)(long v); PyObject* ( *PyBool_FromLong)(long v);
size_t(__stdcall *PyList_Size)(PyObject* list); size_t( *PyList_Size)(PyObject* list);
PyObject* (__stdcall *PyList_GetItem)(PyObject *list, size_t index); PyObject* ( *PyList_GetItem)(PyObject *list, size_t index);
PyObject* (__stdcall *PyFile_FromString)(char *filename, char *mode); PyObject* ( *PyFile_FromString)(char *filename, char *mode);
FILE* (__stdcall *PyFile_AsFile)(PyObject *pyfile); FILE* ( *PyFile_AsFile)(PyObject *pyfile);
PyObject* (__stdcall *PyUnicode_FromString)(const char *u); PyObject* ( *PyUnicode_FromString)(const char *u);
PyObject* (__stdcall *PyInstanceMethod_New)(PyObject *func); PyObject* ( *PyInstanceMethod_New)(PyObject *func);
size_t(__stdcall *PyUnicode_AsWideChar)(PyObject *unicode, wchar_t *w, size_t size); size_t( *PyUnicode_AsWideChar)(PyObject *unicode, wchar_t *w, size_t size);
FILE* ( __stdcall *_Py_fopen)(const char* filename, const char* mode); FILE* ( *_Py_fopen)(const char* filename, const char* mode);
int(__stdcall *Py_AddPendingCall)(int(*func)(void *), void *arg); int( *Py_AddPendingCall)(int(*func)(void *), void *arg);
PyGILState_STATE(__stdcall *PyGILState_Ensure)(); PyGILState_STATE( *PyGILState_Ensure)();
void(__stdcall *PyGILState_Release)(PyGILState_STATE state); void( *PyGILState_Release)(PyGILState_STATE state);
PyObject* (__stdcall *PyDescr_NewMethod)(PyObject* type, struct PyMethodDef *meth); PyObject* ( *PyDescr_NewMethod)(PyObject* type, struct PyMethodDef *meth);
HMODULE m_handlePython; HMODULE m_handlePython;
PyThreadState* m_globalState; PyThreadState* m_globalState;
@ -261,8 +263,37 @@ private:
std::auto_ptr<PythonSingleton> PythonSingleton::m_singleton; std::auto_ptr<PythonSingleton> PythonSingleton::m_singleton;
HMODULE LoadPythonForKey(HKEY installPathKey, int majorVersion, int minorVersion)
{
HMODULE LoadPythonLibrary(int majorVesion, int minorVersion) HMODULE hmodule = NULL;
char installPath[1000];
DWORD installPathSize = sizeof(installPath);
if (ERROR_SUCCESS == RegQueryValueExA(installPathKey, NULL, NULL, NULL, (LPBYTE)installPath, &installPathSize))
{
std::stringstream dllName;
dllName << "python" << majorVersion << minorVersion << ".dll";
std::stringstream imagePath;
imagePath << installPath << dllName.str();
hmodule = LoadLibraryExA(imagePath.str().c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (hmodule)
return hmodule;
hmodule = LoadLibraryA(dllName.str().c_str());
if (hmodule)
return hmodule;
}
return NULL;
}
HMODULE LoadPythonLibrary(int majorVersion, int minorVersion)
{ {
HKey pythonCoreKey; HKey pythonCoreKey;
@ -274,29 +305,26 @@ HMODULE LoadPythonLibrary(int majorVesion, int minorVersion)
HKey installPathKey; HKey installPathKey;
std::stringstream installPathStr; std::stringstream installPathStr;
installPathStr << majorVesion << '.' << minorVersion << "\\InstallPath";
if (majorVersion == 2 || (majorVersion == 3 && minorVersion <= 4))
{
installPathStr << majorVersion << '.' << minorVersion << "\\InstallPath";
}
else
if (majorVersion == 3 && minorVersion >= 5)
{
#ifdef _M_X64
installPathStr << majorVersion << '.' << minorVersion << "\\InstallPath";
#else
installPathStr << majorVersion << '.' << minorVersion << "-32" << "\\InstallPath";
#endif
}
if (ERROR_SUCCESS == RegOpenKeyA(pythonCoreKey, installPathStr.str().c_str(), installPathKey)) if (ERROR_SUCCESS == RegOpenKeyA(pythonCoreKey, installPathStr.str().c_str(), installPathKey))
{ {
char installPath[1000]; HMODULE hmodule = LoadPythonForKey(installPathKey, majorVersion, minorVersion);
DWORD installPathSize = sizeof(installPath);
if (ERROR_SUCCESS == RegQueryValueExA(installPathKey, NULL, NULL, NULL, (LPBYTE)installPath, &installPathSize))
{
std::stringstream dllName;
dllName << "python" << majorVesion << minorVersion << ".dll";
HMODULE hmodule = LoadLibraryA(dllName.str().c_str());
if (hmodule) if (hmodule)
return hmodule; return hmodule;
std::stringstream imagePath;
imagePath << installPath << dllName.str();
hmodule = LoadLibraryExA(imagePath.str().c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (hmodule)
return hmodule;
}
} }
} }
} }
@ -304,11 +332,14 @@ HMODULE LoadPythonLibrary(int majorVesion, int minorVersion)
return NULL; return NULL;
} }
std::list<InterpreterDesc> getInstalledInterpreter() std::list<InterpreterDesc> getInstalledInterpreter()
{ {
std::list<InterpreterDesc> lst; std::set<InterpreterDesc> interpretSet;
for (auto rootKey : std::list<HKEY>({ HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER })) for (auto rootKey : const std::list<HKEY>({ HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }))
{ {
HKey pythonCoreKey; HKey pythonCoreKey;
@ -321,25 +352,39 @@ std::list<InterpreterDesc> getInstalledInterpreter()
if (ERROR_SUCCESS != RegEnumKeyA(pythonCoreKey, i, versionStr, sizeof(versionStr))) if (ERROR_SUCCESS != RegEnumKeyA(pythonCoreKey, i, versionStr, sizeof(versionStr)))
break; break;
int majorVersion, minorVersion; int majorVersion = -1, minorVersion = -1;
sscanf_s(versionStr, "%d.%d", &majorVersion, &minorVersion); sscanf_s(versionStr, "%d.%d", &majorVersion, &minorVersion);
HMODULE hmodule = LoadPythonLibrary(majorVersion, minorVersion); HKey installPathKey;
std::string installPathStr(versionStr);
installPathStr += "\\InstallPath";
if (ERROR_SUCCESS != RegOpenKeyA(pythonCoreKey, installPathStr.c_str(), installPathKey))
continue;
HMODULE hmodule = LoadPythonForKey(installPathKey, majorVersion, minorVersion);
if (hmodule) if (hmodule)
{ {
char fullPath[1000]; char fullPath[1000];
if (GetModuleFileNameA(hmodule, fullPath, sizeof(fullPath))) if (GetModuleFileNameA(hmodule, fullPath, sizeof(fullPath)))
lst.push_back({ majorVersion, minorVersion, fullPath }); {
interpretSet.insert({ majorVersion, minorVersion, fullPath });
}
FreeLibrary(hmodule); FreeLibrary(hmodule);
} }
} }
} }
return lst; std::list<InterpreterDesc> interpretLst;
std::copy(interpretSet.begin(), interpretSet.end(), std::inserter(interpretLst, interpretLst.begin()));
interpretLst.sort();
return interpretLst;
} }
PyModule::PyModule(int majorVesion, int minorVersion) PyModule::PyModule(int majorVesion, int minorVersion)

View File

@ -18,6 +18,17 @@ struct InterpreterDesc {
std::string imagePath; std::string imagePath;
}; };
inline bool operator < (const InterpreterDesc& d1, const InterpreterDesc& d2)
{
if (d1.majorVersion != d2.majorVersion)
return d1.majorVersion < d2.majorVersion;
if (d1.minorVersion != d2.minorVersion)
return d1.minorVersion < d2.minorVersion;
return d1.imagePath < d2.imagePath;
}
std::list<InterpreterDesc> getInstalledInterpreter(); std::list<InterpreterDesc> getInstalledInterpreter();
bool isInterpreterLoaded(int majorVersion, int minorVersion); bool isInterpreterLoaded(int majorVersion, int minorVersion);

View File

@ -538,9 +538,14 @@ void getPythonVersion(int& majorVersion, int& minorVersion)
bool found = false; bool found = false;
bool anyMinorVersion = minorVersion == -1; bool anyMinorVersion = minorVersion == -1;
bool anyMajorVersion = majorVersion == -1;
if (anyMajorVersion)
{
for (auto interpret : interpreterList) for (auto interpret : interpreterList)
{ {
if (majorVersion == interpret.majorVersion &&
if (2 == interpret.majorVersion &&
anyMinorVersion ? (minorVersion <= interpret.minorVersion) : (minorVersion == interpret.minorVersion)) anyMinorVersion ? (minorVersion <= interpret.minorVersion) : (minorVersion == interpret.minorVersion))
{ {
found = true; found = true;
@ -548,6 +553,24 @@ void getPythonVersion(int& majorVersion, int& minorVersion)
} }
} }
if (found)
{
majorVersion = 2;
return;
}
}
for (auto interpret : interpreterList)
{
if (anyMajorVersion ? (majorVersion <= interpret.majorVersion) : (majorVersion==interpret.majorVersion) &&
anyMinorVersion ? (minorVersion <= interpret.minorVersion) : (minorVersion == interpret.minorVersion))
{
found = true;
minorVersion = interpret.minorVersion;
majorVersion = interpret.majorVersion;
}
}
if (!found) if (!found)
throw std::exception("failed to find python interpreter\n"); throw std::exception("failed to find python interpreter\n");
} }