@@ -288,6 +288,17 @@ CTracer_set_pdata_stack(CTracer *self)
288288    return  ret ;
289289}
290290
291+ // Thanks for the idea, memray! 
292+ inline  PyCodeObject * 
293+ MyFrame_BorrowCode (PyFrameObject *  frame )
294+ {
295+     // Return a borrowed reference. 
296+     PyCodeObject *  pCode  =  PyFrame_GetCode (frame );
297+     assert (Py_REFCNT (pCode ) >= 2 );
298+     Py_DECREF (pCode );
299+     return  pCode ;
300+ }
301+ 
291302/* 
292303 * Parts of the trace function. 
293304 */ 
@@ -359,7 +370,7 @@ CTracer_handle_call(CTracer *self, PyFrameObject *frame)
359370    }
360371
361372    /* Check if we should trace this line. */ 
362-     filename  =  PyFrame_GetCode (frame )-> co_filename ;
373+     filename  =  MyFrame_BorrowCode (frame )-> co_filename ;
363374    disposition  =  PyDict_GetItem (self -> should_trace_cache , filename );
364375    if  (disposition  ==  NULL ) {
365376        if  (PyErr_Occurred ()) {
@@ -554,15 +565,15 @@ CTracer_handle_call(CTracer *self, PyFrameObject *frame)
554565     * The current opcode is guaranteed to be RESUME. The argument 
555566     * determines what kind of resume it is. 
556567     */ 
557-     pCode  =  MyCode_GetCode (PyFrame_GetCode (frame ));
568+     pCode  =  MyCode_GetCode (MyFrame_BorrowCode (frame ));
558569    real_call  =  (PyBytes_AS_STRING (pCode )[MyFrame_GetLasti (frame ) +  1 ] ==  0 );
559570#else 
560571    // f_lasti is -1 for a true call, and a real byte offset for a generator re-entry. 
561572    real_call  =  (MyFrame_GetLasti (frame ) <  0 );
562573#endif 
563574
564575    if  (real_call ) {
565-         self -> pcur_entry -> last_line  =  - PyFrame_GetCode (frame )-> co_firstlineno ;
576+         self -> pcur_entry -> last_line  =  - MyFrame_BorrowCode (frame )-> co_firstlineno ;
566577    }
567578    else  {
568579        self -> pcur_entry -> last_line  =  PyFrame_GetLineNumber (frame );
@@ -649,7 +660,7 @@ CTracer_handle_line(CTracer *self, PyFrameObject *frame)
649660
650661    STATS ( self -> stats .lines ++ ; )
651662    if  (self -> pdata_stack -> depth  >= 0 ) {
652-         SHOWLOG (PyFrame_GetLineNumber (frame ), PyFrame_GetCode (frame )-> co_filename , "line" );
663+         SHOWLOG (PyFrame_GetLineNumber (frame ), MyFrame_BorrowCode (frame )-> co_filename , "line" );
653664        if  (self -> pcur_entry -> file_data ) {
654665            int  lineno_from  =  -1 ;
655666            int  lineno_to  =  -1 ;
@@ -727,7 +738,7 @@ CTracer_handle_return(CTracer *self, PyFrameObject *frame)
727738        self -> pcur_entry  =  & self -> pdata_stack -> stack [self -> pdata_stack -> depth ];
728739        if  (self -> tracing_arcs  &&  self -> pcur_entry -> file_data ) {
729740            BOOL  real_return  =  FALSE;
730-             pCode  =  MyCode_GetCode (PyFrame_GetCode (frame ));
741+             pCode  =  MyCode_GetCode (MyFrame_BorrowCode (frame ));
731742            int  lasti  =  MyFrame_GetLasti (frame );
732743            Py_ssize_t  code_size  =  PyBytes_GET_SIZE (pCode );
733744            unsigned char   *  code_bytes  =  (unsigned char   * )PyBytes_AS_STRING (pCode );
@@ -759,7 +770,7 @@ CTracer_handle_return(CTracer *self, PyFrameObject *frame)
759770            real_return  =  !(is_yield  ||  is_yield_from );
760771#endif 
761772            if  (real_return ) {
762-                 int  first  =  PyFrame_GetCode (frame )-> co_firstlineno ;
773+                 int  first  =  MyFrame_BorrowCode (frame )-> co_firstlineno ;
763774                if  (CTracer_record_pair (self , self -> pcur_entry -> last_line , - first ) <  0 ) {
764775                    goto error ;
765776                }
@@ -782,7 +793,7 @@ CTracer_handle_return(CTracer *self, PyFrameObject *frame)
782793        }
783794
784795        /* Pop the stack. */ 
785-         SHOWLOG (PyFrame_GetLineNumber (frame ), PyFrame_GetCode (frame )-> co_filename , "return" );
796+         SHOWLOG (PyFrame_GetLineNumber (frame ), MyFrame_BorrowCode (frame )-> co_filename , "return" );
786797        self -> pdata_stack -> depth -- ;
787798        self -> pcur_entry  =  & self -> pdata_stack -> stack [self -> pdata_stack -> depth ];
788799    }
@@ -824,13 +835,13 @@ CTracer_trace(CTracer *self, PyFrameObject *frame, int what, PyObject *arg_unuse
824835    if  (what  <= (int )(sizeof (what_sym )/sizeof (const  char  * ))) {
825836        w  =  what_sym [what ];
826837    }
827-     ascii  =  PyUnicode_AsASCIIString (PyFrame_GetCode (frame )-> co_filename );
838+     ascii  =  PyUnicode_AsASCIIString (MyFrame_BorrowCode (frame )-> co_filename );
828839    printf ("%x trace: f:%x %s @ %s %d\n" , (int )self , (int )frame , what_sym [what ], PyBytes_AS_STRING (ascii ), PyFrame_GetLineNumber (frame ));
829840    Py_DECREF (ascii );
830841    #endif 
831842
832843    #if  TRACE_LOG 
833-     ascii  =  PyUnicode_AsASCIIString (PyFrame_GetCode (frame )-> co_filename );
844+     ascii  =  PyUnicode_AsASCIIString (MyFrame_BorrowCode (frame )-> co_filename );
834845    if  (strstr (PyBytes_AS_STRING (ascii ), start_file ) &&  PyFrame_GetLineNumber (frame ) ==  start_line ) {
835846        logging  =  TRUE;
836847    }
@@ -926,7 +937,7 @@ CTracer_call(CTracer *self, PyObject *args, PyObject *kwds)
926937    }
927938
928939    #if  WHAT_LOG 
929-     ascii  =  PyUnicode_AsASCIIString (PyFrame_GetCode (frame )-> co_filename );
940+     ascii  =  PyUnicode_AsASCIIString (MyFrame_BorrowCode (frame )-> co_filename );
930941    printf ("pytrace: %s @ %s %d\n" , what_sym [what ], PyBytes_AS_STRING (ascii ), PyFrame_GetLineNumber (frame ));
931942    Py_DECREF (ascii );
932943    #endif 
0 commit comments