From 2e42400700c64e9ebe00c0be7750ebf406d4a130 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 9 Jan 2023 13:19:09 +0100 Subject: [PATCH] deploy-stub: Fix crash when running in Python 3.11 Fixes #1423 --- pandatool/src/deploy-stub/deploy-stub.c | 39 +++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/pandatool/src/deploy-stub/deploy-stub.c b/pandatool/src/deploy-stub/deploy-stub.c index b0251be473..c9a9272b15 100644 --- a/pandatool/src/deploy-stub/deploy-stub.c +++ b/pandatool/src/deploy-stub/deploy-stub.c @@ -90,6 +90,16 @@ static struct _inittab extensions[] = { static wchar_t *log_pathw = NULL; #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 static int supports_code_page(UINT cp) { if (cp == 0) { @@ -742,7 +752,7 @@ int wmain(int argc, wchar_t *argv[]) { int main(int argc, char *argv[]) { #endif int retval; - struct _frozen *moddef; + ModuleDef *moddef; const char *log_filename; void *blob = 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. moddef = blobinfo.pointers[0]; +#if PY_VERSION_HEX < 0x030b0000 + PyImport_FrozenModules = moddef; +#endif while (moddef->name) { moddef->name = (char *)((uintptr_t)moddef->name + (uintptr_t)blob); 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); 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) { @@ -822,12 +853,16 @@ int main(int argc, char *argv[]) { #endif // Run frozen application - PyImport_FrozenModules = blobinfo.pointers[0]; retval = Py_FrozenMain(argc, argv); fflush(stdout); fflush(stderr); +#if PY_VERSION_HEX >= 0x030b0000 + free((void *)PyImport_FrozenModules); + PyImport_FrozenModules = NULL; +#endif + unmap_blob(blob); return retval; }