mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +08:00
[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:
parent
27db13b5de
commit
cf9aa94082
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user