summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Python/perf_trampoline.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tools/python3/Python/perf_trampoline.c')
-rw-r--r--contrib/tools/python3/Python/perf_trampoline.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/contrib/tools/python3/Python/perf_trampoline.c b/contrib/tools/python3/Python/perf_trampoline.c
index 7ef9eca11f5..e296605c16a 100644
--- a/contrib/tools/python3/Python/perf_trampoline.c
+++ b/contrib/tools/python3/Python/perf_trampoline.c
@@ -211,9 +211,8 @@ 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;
@@ -221,6 +220,13 @@ perf_trampoline_reset_state(void)
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)
{
@@ -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);
}
}