@@ -193,75 +193,33 @@ typedef struct trampoline_api_st trampoline_api_t;
193193#define trampoline_api _PyRuntime.ceval.perf.trampoline_api
194194#define perf_map_file _PyRuntime.ceval.perf.map_file
195195
196- static void *
197- perf_map_get_file (void )
198- {
199- if (perf_map_file ) {
200- return perf_map_file ;
201- }
202- char filename [100 ];
203- pid_t pid = getpid ();
204- // Location and file name of perf map is hard-coded in perf tool.
205- // Use exclusive create flag wit nofollow to prevent symlink attacks.
206- int flags = O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC ;
207- snprintf (filename , sizeof (filename ) - 1 , "/tmp/perf-%jd.map" ,
208- (intmax_t )pid );
209- int fd = open (filename , flags , 0600 );
210- if (fd == -1 ) {
211- perf_status = PERF_STATUS_FAILED ;
212- PyErr_SetFromErrnoWithFilename (PyExc_OSError , filename );
213- return NULL ;
214- }
215- perf_map_file = fdopen (fd , "w" );
216- if (!perf_map_file ) {
217- perf_status = PERF_STATUS_FAILED ;
218- PyErr_SetFromErrnoWithFilename (PyExc_OSError , filename );
219- close (fd );
220- return NULL ;
221- }
222- return perf_map_file ;
223- }
224-
225- static int
226- perf_map_close (void * state )
227- {
228- FILE * fp = (FILE * )state ;
229- int ret = 0 ;
230- if (fp ) {
231- ret = fclose (fp );
232- }
233- perf_map_file = NULL ;
234- perf_status = PERF_STATUS_NO_INIT ;
235- return ret ;
236- }
237196
238197static void
239198perf_map_write_entry (void * state , const void * code_addr ,
240199 unsigned int code_size , PyCodeObject * co )
241200{
242- assert (state != NULL );
243- FILE * method_file = (FILE * )state ;
244- const char * entry = PyUnicode_AsUTF8 (co -> co_qualname );
245- if (entry == NULL ) {
246- _PyErr_WriteUnraisableMsg ("Failed to get qualname from code object" ,
247- NULL );
248- return ;
201+ const char * entry = "" ;
202+ if (co -> co_qualname != NULL ) {
203+ entry = PyUnicode_AsUTF8 (co -> co_qualname );
249204 }
250- const char * filename = PyUnicode_AsUTF8 (co -> co_filename );
251- if (filename == NULL ) {
252- _PyErr_WriteUnraisableMsg ("Failed to get filename from code object" ,
253- NULL );
205+ const char * filename = "" ;
206+ if (co -> co_filename != NULL ) {
207+ filename = PyUnicode_AsUTF8 (co -> co_filename );
208+ }
209+ size_t perf_map_entry_size = snprintf (NULL , 0 , "py::%s:%s" , entry , filename ) + 1 ;
210+ char * perf_map_entry = (char * ) PyMem_RawMalloc (perf_map_entry_size );
211+ if (perf_map_entry == NULL ) {
254212 return ;
255213 }
256- fprintf ( method_file , "%" PRIxPTR " %x py::%s:%s\n " , ( uintptr_t ) code_addr , code_size , entry ,
257- filename );
258- fflush ( method_file );
214+ snprintf ( perf_map_entry , perf_map_entry_size , " py::%s:%s" , entry , filename );
215+ PyUnstable_WritePerfMapEntry ( code_addr , code_size , perf_map_entry );
216+ PyMem_RawFree ( perf_map_entry );
259217}
260218
261219_PyPerf_Callbacks _Py_perfmap_callbacks = {
262- & perf_map_get_file ,
220+ NULL ,
263221 & perf_map_write_entry ,
264- & perf_map_close
222+ NULL ,
265223};
266224
267225static int
@@ -465,13 +423,6 @@ _PyPerfTrampoline_Init(int activate)
465423 if (new_code_arena () < 0 ) {
466424 return -1 ;
467425 }
468- if (trampoline_api .state == NULL ) {
469- void * state = trampoline_api .init_state ();
470- if (state == NULL ) {
471- return -1 ;
472- }
473- trampoline_api .state = state ;
474- }
475426 extra_code_index = _PyEval_RequestCodeExtraIndex (NULL );
476427 if (extra_code_index == -1 ) {
477428 return -1 ;
@@ -491,10 +442,6 @@ _PyPerfTrampoline_Fini(void)
491442 tstate -> interp -> eval_frame = NULL ;
492443 }
493444 free_code_arenas ();
494- if (trampoline_api .state != NULL ) {
495- trampoline_api .free_state (trampoline_api .state );
496- trampoline_api .state = NULL ;
497- }
498445 extra_code_index = -1 ;
499446#endif
500447 return 0 ;
@@ -507,6 +454,7 @@ _PyPerfTrampoline_AfterFork_Child(void)
507454 // Restart trampoline in file in child.
508455 int was_active = _PyIsPerfTrampolineActive ();
509456 _PyPerfTrampoline_Fini ();
457+ PyUnstable_PerfMapState_Fini ();
510458 if (was_active ) {
511459 _PyPerfTrampoline_Init (1 );
512460 }
0 commit comments