diff --git a/Include/internal/pycore_jit_publish.h b/Include/internal/pycore_jit_publish.h index 1c9cd174d0a..7ee77f5c996 100644 --- a/Include/internal/pycore_jit_publish.h +++ b/Include/internal/pycore_jit_publish.h @@ -11,9 +11,13 @@ typedef struct _PyJitCodeRegistration _PyJitCodeRegistration; #ifdef _Py_JIT -/* Return a teardown handle when any backend stores registration state. - * A NULL result is valid when publication succeeded only through backends - * with no unregister step, such as perf map output. +/* Publish JIT code to optional tooling backends. + * + * The return value is a backend-specific deregistration handle, not a + * success/failure indicator. NULL means there is nothing to unregister later: + * perf does not need a handle, and GDB/GNU backtrace registration failures + * are intentionally non-fatal because tooling support must not make JIT + * compilation fail. */ _PyJitCodeRegistration *_PyJit_RegisterCode(const void *code_addr, size_t code_size, diff --git a/Python/jit_publish.c b/Python/jit_publish.c index 3b0b24fa1fd..bbe27056094 100644 --- a/Python/jit_publish.c +++ b/Python/jit_publish.c @@ -82,6 +82,8 @@ _PyJit_RegisterCode(const void *code_addr, size_t code_size, const char *entry, const char *filename) { jit_register_perf_code(code_addr, code_size, entry, filename); + // Perf publication has no teardown handle, so it is intentionally + // not counted below. #if !defined(PY_HAVE_JIT_GDB_UNWIND) \ && !defined(PY_HAVE_JIT_GNU_BACKTRACE_UNWIND) @@ -93,18 +95,20 @@ _PyJit_RegisterCode(const void *code_addr, size_t code_size, return NULL; } - int registered = 0; + // Partial failures are non-fatal: the JIT code can still execute, but + // unavailable tooling may not be able to unwind it. + int any_registered = 0; # if defined(PY_HAVE_JIT_GDB_UNWIND) jit_register_gdb_code( registration, code_addr, code_size, entry, filename); - registered |= registration->gdb_handle != NULL; + any_registered |= registration->gdb_handle != NULL; # endif # if defined(PY_HAVE_JIT_GNU_BACKTRACE_UNWIND) jit_register_gnu_backtrace_code( registration, code_addr, code_size); - registered |= registration->gnu_backtrace_handle != NULL; + any_registered |= registration->gnu_backtrace_handle != NULL; # endif - if (!registered) { + if (!any_registered) { PyMem_RawFree(registration); return NULL; }