@@ -216,10 +216,24 @@ perf_map_write_entry(void *state, const void *code_addr,
216216 PyMem_RawFree (perf_map_entry );
217217}
218218
219+ static void *
220+ perf_map_init_state (void )
221+ {
222+ PyUnstable_PerfMapState_Init ();
223+ return NULL ;
224+ }
225+
226+ static int
227+ perf_map_free_state (void * state )
228+ {
229+ PyUnstable_PerfMapState_Fini ();
230+ return 0 ;
231+ }
232+
219233_PyPerf_Callbacks _Py_perfmap_callbacks = {
220- NULL ,
234+ & perf_map_init_state ,
221235 & perf_map_write_entry ,
222- NULL ,
236+ & perf_map_free_state ,
223237};
224238
225239static int
@@ -415,7 +429,6 @@ _PyPerfTrampoline_SetCallbacks(_PyPerf_Callbacks *callbacks)
415429 trampoline_api .write_state = callbacks -> write_state ;
416430 trampoline_api .free_state = callbacks -> free_state ;
417431 trampoline_api .state = NULL ;
418- perf_status = PERF_STATUS_OK ;
419432#endif
420433 return 0 ;
421434}
@@ -434,6 +447,7 @@ _PyPerfTrampoline_Init(int activate)
434447 }
435448 if (!activate ) {
436449 tstate -> interp -> eval_frame = NULL ;
450+ perf_status = PERF_STATUS_NO_INIT ;
437451 }
438452 else {
439453 tstate -> interp -> eval_frame = py_trampoline_evaluator ;
@@ -444,6 +458,9 @@ _PyPerfTrampoline_Init(int activate)
444458 if (extra_code_index == -1 ) {
445459 return -1 ;
446460 }
461+ if (trampoline_api .state == NULL && trampoline_api .init_state != NULL ) {
462+ trampoline_api .state = trampoline_api .init_state ();
463+ }
447464 perf_status = PERF_STATUS_OK ;
448465 }
449466#endif
@@ -454,16 +471,29 @@ int
454471_PyPerfTrampoline_Fini (void )
455472{
456473#ifdef PY_HAVE_PERF_TRAMPOLINE
474+ if (perf_status != PERF_STATUS_OK ) {
475+ return 0 ;
476+ }
457477 PyThreadState * tstate = _PyThreadState_GET ();
458478 if (tstate -> interp -> eval_frame == py_trampoline_evaluator ) {
459479 tstate -> interp -> eval_frame = NULL ;
460480 }
461- free_code_arenas ();
481+ if (perf_status == PERF_STATUS_OK ) {
482+ trampoline_api .free_state (trampoline_api .state );
483+ }
462484 extra_code_index = -1 ;
485+ perf_status = PERF_STATUS_NO_INIT ;
463486#endif
464487 return 0 ;
465488}
466489
490+ void _PyPerfTrampoline_FreeArenas (void ) {
491+ #ifdef PY_HAVE_PERF_TRAMPOLINE
492+ free_code_arenas ();
493+ #endif
494+ return ;
495+ }
496+
467497int
468498PyUnstable_PerfTrampoline_SetPersistAfterFork (int enable ){
469499#ifdef PY_HAVE_PERF_TRAMPOLINE
@@ -477,8 +507,8 @@ PyStatus
477507_PyPerfTrampoline_AfterFork_Child (void )
478508{
479509#ifdef PY_HAVE_PERF_TRAMPOLINE
480- PyUnstable_PerfMapState_Fini ();
481510 if (persist_after_fork ) {
511+ _PyPerfTrampoline_Fini ();
482512 char filename [256 ];
483513 pid_t parent_pid = getppid ();
484514 snprintf (filename , sizeof (filename ), "/tmp/perf-%d.map" , parent_pid );
0 commit comments