@@ -269,9 +269,38 @@ impl Tracer for RuntimeTracer {
269269 let mut args: Vec < runtime_tracing:: FullValueRecord > = Vec :: new ( ) ;
270270 let frame_and_args = ( || -> PyResult < ( ) > {
271271 // Current Python frame where the function just started executing
272- let sys = py. import ( "sys" ) ?;
273- let frame = sys. getattr ( "_getframe" ) ?. call1 ( ( 0 , ) ) ?;
274- let locals = frame. getattr ( "f_locals" ) ?;
272+
273+ // Acquire current frame without importing sys
274+ let mut frame_ptr = unsafe { ffi:: PyEval_GetFrame ( ) } ;
275+ if frame_ptr. is_null ( ) {
276+ return Err ( pyo3:: exceptions:: PyRuntimeError :: new_err (
277+ "on_py_start: null frame" ,
278+ ) ) ;
279+ }
280+ unsafe {
281+ ffi:: Py_XINCREF ( frame_ptr. cast ( ) ) ;
282+ }
283+
284+ // Synchronize fast locals into f_locals
285+ unsafe {
286+ if ffi:: PyFrame_FastToLocalsWithError ( frame_ptr) < 0 {
287+ ffi:: Py_DECREF ( frame_ptr. cast ( ) ) ;
288+ let err = PyErr :: fetch ( py) ;
289+ return Err ( err) ;
290+ }
291+ }
292+
293+ // Obtain concrete locals dict for lookup
294+ let locals_raw = unsafe { PyFrame_GetLocals ( frame_ptr) } ;
295+ if locals_raw. is_null ( ) {
296+ unsafe {
297+ ffi:: Py_DECREF ( frame_ptr. cast ( ) ) ;
298+ }
299+ return Err ( pyo3:: exceptions:: PyRuntimeError :: new_err (
300+ "on_py_start: PyFrame_GetLocals returned null" ,
301+ ) ) ;
302+ }
303+ let locals = unsafe { Bound :: < PyAny > :: from_owned_ptr ( py, locals_raw) } ;
275304
276305 // Argument names come from co_varnames in the order defined by CPython:
277306 // [positional (pos-only + pos-or-kw)] [+ varargs] [+ kw-only] [+ kwargs]
@@ -280,9 +309,10 @@ impl Tracer for RuntimeTracer {
280309 // for the positional slice; `co_posonlyargcount` is only needed if we want to
281310 // distinguish the two groups, which we do not here.
282311 let argcount = code. arg_count ( py) ? as usize ; // total positional (pos-only + pos-or-kw)
312+
283313 let _posonly: usize = code. as_bound ( py) . getattr ( "co_posonlyargcount" ) ?. extract ( ) ?;
284- let kwonly: usize = code. as_bound ( py) . getattr ( "co_kwonlyargcount" ) ?. extract ( ) ?;
285314
315+ let kwonly: usize = code. as_bound ( py) . getattr ( "co_kwonlyargcount" ) ?. extract ( ) ?;
286316 let flags = code. flags ( py) ?;
287317 const CO_VARARGS : u32 = 0x04 ;
288318 const CO_VARKEYWORDS : u32 = 0x08 ;
@@ -300,7 +330,7 @@ impl Tracer for RuntimeTracer {
300330 let vrec = self . encode_value ( py, & val) ;
301331 args. push ( TraceWriter :: arg ( & mut self . writer , name, vrec) ) ;
302332 }
303- Err ( _ ) => { }
333+ Err ( e ) => { panic ! ( "Error {:?}" , e ) }
304334 }
305335 idx += 1 ;
306336 }
@@ -323,7 +353,7 @@ impl Tracer for RuntimeTracer {
323353 let vrec = self . encode_value ( py, & val) ;
324354 args. push ( TraceWriter :: arg ( & mut self . writer , name, vrec) ) ;
325355 }
326- Err ( _ ) => { }
356+ Err ( e ) => { panic ! ( "Error {:?}" , e ) }
327357 }
328358 }
329359 idx = idx. saturating_add ( kwonly_take) ;
@@ -336,6 +366,7 @@ impl Tracer for RuntimeTracer {
336366 args. push ( TraceWriter :: arg ( & mut self . writer , name, vrec) ) ;
337367 }
338368 }
369+ unsafe { ffi:: Py_DECREF ( frame_ptr. cast ( ) ) ; }
339370 Ok ( ( ) )
340371 } ) ( ) ;
341372 if let Err ( e) = frame_and_args {
@@ -344,7 +375,8 @@ impl Tracer for RuntimeTracer {
344375 "on_py_start: failed to capture args: {}" ,
345376 e
346377 ) ) ) ;
347- log:: debug!( "error {:?}" , rete) ;
378+ //panic!("error {:?}", rete);
379+ log:: error!( "AAA error {:?}" , rete) ;
348380 return rete;
349381 }
350382
0 commit comments