deploy-stub: Fix crash when running in Python 3.11

Fixes #1423
This commit is contained in:
rdb 2023-01-09 13:19:09 +01:00
parent 470e352ab8
commit 2e42400700

View File

@ -90,6 +90,16 @@ static struct _inittab extensions[] = {
static wchar_t *log_pathw = NULL; static wchar_t *log_pathw = NULL;
#endif #endif
#if PY_VERSION_HEX >= 0x030b0000
typedef struct {
const char *name;
const unsigned char *code;
int size;
} ModuleDef;
#else
typedef struct _frozen ModuleDef;
#endif
#if defined(_WIN32) && PY_VERSION_HEX < 0x03060000 #if defined(_WIN32) && PY_VERSION_HEX < 0x03060000
static int supports_code_page(UINT cp) { static int supports_code_page(UINT cp) {
if (cp == 0) { if (cp == 0) {
@ -742,7 +752,7 @@ int wmain(int argc, wchar_t *argv[]) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
#endif #endif
int retval; int retval;
struct _frozen *moddef; ModuleDef *moddef;
const char *log_filename; const char *log_filename;
void *blob = NULL; void *blob = NULL;
log_filename = NULL; log_filename = NULL;
@ -792,6 +802,9 @@ int main(int argc, char *argv[]) {
// Offset the pointers in the module table using the base mmap address. // Offset the pointers in the module table using the base mmap address.
moddef = blobinfo.pointers[0]; moddef = blobinfo.pointers[0];
#if PY_VERSION_HEX < 0x030b0000
PyImport_FrozenModules = moddef;
#endif
while (moddef->name) { while (moddef->name) {
moddef->name = (char *)((uintptr_t)moddef->name + (uintptr_t)blob); moddef->name = (char *)((uintptr_t)moddef->name + (uintptr_t)blob);
if (moddef->code != 0) { if (moddef->code != 0) {
@ -800,6 +813,24 @@ int main(int argc, char *argv[]) {
//printf("MOD: %s %p %d\n", moddef->name, (void*)moddef->code, moddef->size); //printf("MOD: %s %p %d\n", moddef->name, (void*)moddef->code, moddef->size);
moddef++; moddef++;
} }
// In Python 3.11, we need to convert this to the new structure format.
#if PY_VERSION_HEX >= 0x030b0000
ModuleDef *moddef_end = moddef;
ptrdiff_t num_modules = moddef - (ModuleDef *)blobinfo.pointers[0];
struct _frozen *new_moddef = (struct _frozen *)calloc(num_modules + 1, sizeof(struct _frozen));
PyImport_FrozenModules = new_moddef;
for (moddef = blobinfo.pointers[0]; moddef < moddef_end; ++moddef) {
new_moddef->name = moddef->name;
new_moddef->code = moddef->code;
new_moddef->size = moddef->size < 0 ? -(moddef->size) : moddef->size;
new_moddef->is_package = moddef->size < 0;
new_moddef->get_code = NULL;
new_moddef++;
}
#endif
} else {
PyImport_FrozenModules = blobinfo.pointers[0];
} }
if (log_filename != NULL) { if (log_filename != NULL) {
@ -822,12 +853,16 @@ int main(int argc, char *argv[]) {
#endif #endif
// Run frozen application // Run frozen application
PyImport_FrozenModules = blobinfo.pointers[0];
retval = Py_FrozenMain(argc, argv); retval = Py_FrozenMain(argc, argv);
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
#if PY_VERSION_HEX >= 0x030b0000
free((void *)PyImport_FrozenModules);
PyImport_FrozenModules = NULL;
#endif
unmap_blob(blob); unmap_blob(blob);
return retval; return retval;
} }