Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix an intermittent crash after :func:`os.fork` when perf trampoline
profiling is enabled and the child returns through trampoline frames
inherited from the parent process.
17 changes: 12 additions & 5 deletions Python/perf_trampoline.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,16 +211,22 @@ enum perf_trampoline_type {
static void free_code_arenas(void);

static void
perf_trampoline_reset_state(void)
perf_trampoline_clear_code_watcher(void)
{
free_code_arenas();
if (code_watcher_id >= 0) {
PyCode_ClearWatcher(code_watcher_id);
code_watcher_id = -1;
}
extra_code_index = -1;
}

static void
perf_trampoline_reset_state(void)
{
free_code_arenas();
perf_trampoline_clear_code_watcher();
}

static int
perf_trampoline_code_watcher(PyCodeEvent event, PyCodeObject *co)
{
Expand Down Expand Up @@ -623,9 +629,10 @@ _PyPerfTrampoline_AfterFork_Child(void)
// After fork, Fini may leave the old code watcher registered
// if trampolined code objects from the parent still exist
// (trampoline_refcount > 0). Clear it unconditionally before
// Init registers a new one, to prevent two watchers sharing
// the same globals and double-decrementing trampoline_refcount.
perf_trampoline_reset_state();
// Init registers a new one, but keep the old arenas mapped: the
// child may still need to return through trampoline frames that
// were on the C stack at fork().
perf_trampoline_clear_code_watcher();
_PyPerfTrampoline_Init(1);
}
}
Expand Down
Loading