@@ -193,75 +193,33 @@ typedef struct trampoline_api_st trampoline_api_t;
193
193
#define trampoline_api _PyRuntime.ceval.perf.trampoline_api
194
194
#define perf_map_file _PyRuntime.ceval.perf.map_file
195
195
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
- }
237
196
238
197
static void
239
198
perf_map_write_entry (void * state , const void * code_addr ,
240
199
unsigned int code_size , PyCodeObject * co )
241
200
{
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 );
249
204
}
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 ) {
254
212
return ;
255
213
}
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 );
259
217
}
260
218
261
219
_PyPerf_Callbacks _Py_perfmap_callbacks = {
262
- & perf_map_get_file ,
220
+ NULL ,
263
221
& perf_map_write_entry ,
264
- & perf_map_close
222
+ NULL ,
265
223
};
266
224
267
225
static int
@@ -465,13 +423,6 @@ _PyPerfTrampoline_Init(int activate)
465
423
if (new_code_arena () < 0 ) {
466
424
return -1 ;
467
425
}
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
- }
475
426
extra_code_index = _PyEval_RequestCodeExtraIndex (NULL );
476
427
if (extra_code_index == -1 ) {
477
428
return -1 ;
@@ -491,10 +442,6 @@ _PyPerfTrampoline_Fini(void)
491
442
tstate -> interp -> eval_frame = NULL ;
492
443
}
493
444
free_code_arenas ();
494
- if (trampoline_api .state != NULL ) {
495
- trampoline_api .free_state (trampoline_api .state );
496
- trampoline_api .state = NULL ;
497
- }
498
445
extra_code_index = -1 ;
499
446
#endif
500
447
return 0 ;
@@ -507,6 +454,7 @@ _PyPerfTrampoline_AfterFork_Child(void)
507
454
// Restart trampoline in file in child.
508
455
int was_active = _PyIsPerfTrampolineActive ();
509
456
_PyPerfTrampoline_Fini ();
457
+ PyUnstable_PerfMapState_Fini ();
510
458
if (was_active ) {
511
459
_PyPerfTrampoline_Init (1 );
512
460
}
0 commit comments