Skip to content

Commit a18cb96

Browse files
committed
Address Pablo's feedback
1 parent 67ae6cb commit a18cb96

3 files changed

Lines changed: 66 additions & 15 deletions

File tree

Include/internal/pycore_jit_unwind.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ void _PyJitUnwind_GdbRegisterCode(const void *code_addr,
2323
const char *entry,
2424
const char *filename);
2525

26+
void _PyJitUnwind_GdbUnregisterCode(const void *code_addr);
27+
2628
#endif // PY_HAVE_PERF_TRAMPOLINE
2729

2830
#endif // Py_CORE_JIT_UNWIND_H

Python/jit.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,9 @@ _PyJIT_Free(_PyExecutorObject *executor)
843843
if (memory) {
844844
executor->jit_code = NULL;
845845
executor->jit_size = 0;
846+
#ifdef PY_HAVE_PERF_TRAMPOLINE
847+
_PyJitUnwind_GdbUnregisterCode(memory);
848+
#endif
846849
if (jit_free(memory, size)) {
847850
PyErr_FormatUnraisable("Exception ignored while "
848851
"freeing JIT memory");
@@ -860,6 +863,9 @@ _PyJIT_Fini(void)
860863
if (size) {
861864
_Py_jit_entry = _Py_LazyJitShim;
862865
_Py_jit_shim_size = 0;
866+
#ifdef PY_HAVE_PERF_TRAMPOLINE
867+
_PyJitUnwind_GdbUnregisterCode(memory);
868+
#endif
863869
if (jit_free(memory, size)) {
864870
PyErr_FormatUnraisable("Exception ignored while "
865871
"freeing JIT entry code");

Python/jit_unwind.c

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "Python.h"
99
#include "pycore_jit_unwind.h"
10+
#include "pycore_lock.h"
1011

1112
#ifdef PY_HAVE_PERF_TRAMPOLINE
1213

@@ -579,20 +580,14 @@ static void elf_init_ehframe(ELFObjectContext* ctx, int absolute_addr) {
579580
DWRF_U8(DWRF_CFA_offset | DWRF_REG_RA); // x30 (link register) saved
580581
DWRF_UV(1); // At CFA-8 (1 * 8 = 8 bytes from CFA)
581582
DWRF_U8(DWRF_CFA_advance_loc | 3); // Advance by 3 instructions (12 bytes)
582-
DWRF_U8(DWRF_CFA_restore | DWRF_REG_RA); // Restore x30 - NO DWRF_UV() after this!
583-
DWRF_U8(DWRF_CFA_restore | DWRF_REG_FP); // Restore x29 - NO DWRF_UV() after this!
584-
DWRF_U8(DWRF_CFA_def_cfa_offset); // CFA = SP + 0 (stack restored)
585-
DWRF_UV(0); // Back to original stack position
586-
587-
if (absolute_addr) {
588-
DWRF_U8(DWRF_CFA_def_cfa_register); // CFA = FP (x29)
589-
DWRF_UV(DWRF_REG_FP);
590-
DWRF_U8(DWRF_CFA_def_cfa_offset); // CFA = FP + 16
591-
DWRF_UV(16);
592-
DWRF_U8(DWRF_CFA_offset | DWRF_REG_FP); // x29 saved
593-
DWRF_UV(2);
594-
DWRF_U8(DWRF_CFA_offset | DWRF_REG_RA); // x30 saved
595-
DWRF_UV(1);
583+
DWRF_U8(DWRF_CFA_def_cfa_register); // CFA = FP (x29) + 16
584+
DWRF_UV(DWRF_REG_FP);
585+
if (!absolute_addr) {
586+
DWRF_U8(DWRF_CFA_restore | DWRF_REG_RA); // Restore x30 - NO DWRF_UV() after this!
587+
DWRF_U8(DWRF_CFA_restore | DWRF_REG_FP); // Restore x29 - NO DWRF_UV() after this!
588+
DWRF_U8(DWRF_CFA_def_cfa); // CFA = SP + 0 (stack restored)
589+
DWRF_UV(DWRF_REG_SP);
590+
DWRF_UV(0);
596591
}
597592

598593
#else
@@ -666,6 +661,7 @@ struct jit_code_entry {
666661
struct jit_code_entry *prev;
667662
const char *symfile_addr;
668663
uint64_t symfile_size;
664+
const void *code_addr;
669665
};
670666

671667
struct jit_descriptor {
@@ -678,6 +674,7 @@ struct jit_descriptor {
678674
Py_EXPORTED_SYMBOL volatile struct jit_descriptor __jit_debug_descriptor = {
679675
1, JIT_NOACTION, NULL, NULL
680676
};
677+
static PyMutex gdb_jit_mutex = {0};
681678

682679
Py_EXPORTED_SYMBOL void __attribute__((noinline))
683680
__jit_debug_register_code(void)
@@ -863,6 +860,9 @@ gdb_jit_register_code(
863860
}
864861
entry->symfile_addr = (const char *)buf;
865862
entry->symfile_size = total_size;
863+
entry->code_addr = code_addr;
864+
865+
PyMutex_Lock(&gdb_jit_mutex);
866866
entry->prev = NULL;
867867
entry->next = __jit_debug_descriptor.first_entry;
868868
if (entry->next != NULL) {
@@ -873,7 +873,8 @@ gdb_jit_register_code(
873873
__jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
874874
__jit_debug_register_code();
875875
__jit_debug_descriptor.action_flag = JIT_NOACTION;
876-
876+
__jit_debug_descriptor.relevant_entry = NULL;
877+
PyMutex_Unlock(&gdb_jit_mutex);
877878
}
878879
#endif // __linux__ && __ELF__
879880

@@ -917,4 +918,46 @@ _PyJitUnwind_GdbRegisterCode(const void *code_addr,
917918
#endif
918919
}
919920

921+
void
922+
_PyJitUnwind_GdbUnregisterCode(const void *code_addr)
923+
{
924+
#if defined(__linux__) && defined(__ELF__)
925+
if (code_addr == NULL) {
926+
return;
927+
}
928+
929+
PyMutex_Lock(&gdb_jit_mutex);
930+
struct jit_code_entry *entry = __jit_debug_descriptor.first_entry;
931+
while (entry != NULL && entry->code_addr != code_addr) {
932+
entry = entry->next;
933+
}
934+
if (entry == NULL) {
935+
PyMutex_Unlock(&gdb_jit_mutex);
936+
return;
937+
}
938+
939+
if (entry->prev != NULL) {
940+
entry->prev->next = entry->next;
941+
}
942+
else {
943+
__jit_debug_descriptor.first_entry = entry->next;
944+
}
945+
if (entry->next != NULL) {
946+
entry->next->prev = entry->prev;
947+
}
948+
949+
__jit_debug_descriptor.relevant_entry = entry;
950+
__jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;
951+
__jit_debug_register_code();
952+
__jit_debug_descriptor.action_flag = JIT_NOACTION;
953+
__jit_debug_descriptor.relevant_entry = NULL;
954+
PyMutex_Unlock(&gdb_jit_mutex);
955+
956+
PyMem_RawFree((void *)entry->symfile_addr);
957+
PyMem_RawFree(entry);
958+
#else
959+
(void)code_addr;
960+
#endif
961+
}
962+
920963
#endif // PY_HAVE_PERF_TRAMPOLINE

0 commit comments

Comments
 (0)