@@ -51,11 +51,13 @@ _Py_stackref_get_object(_PyStackRef ref)
5151 PyInterpreterState * interp = PyInterpreterState_Get ();
5252 assert (interp != NULL );
5353 if (ref .index >= interp -> next_stackref ) {
54- _Py_FatalErrorFormat (__func__ , "Garbled stack ref with ID %" PRIu64 "\n" , ref .index );
54+ _Py_FatalErrorFormat (__func__ ,
55+ "Garbled stack ref with ID %" PRIu64 "\n" , ref .index );
5556 }
5657 TableEntry * entry = _Py_hashtable_get (interp -> open_stackrefs_table , (void * )ref .index );
5758 if (entry == NULL ) {
58- _Py_FatalErrorFormat (__func__ , "Accessing closed stack ref with ID %" PRIu64 "\n" , ref .index );
59+ _Py_FatalErrorFormat (__func__ ,
60+ "Accessing closed stack ref with ID %" PRIu64 "\n" , ref .index );
5961 }
6062 return entry -> obj ;
6163}
@@ -72,12 +74,16 @@ _Py_stackref_close(_PyStackRef ref, const char *filename, int linenumber)
7274 assert (!PyStackRef_IsError (ref ));
7375 PyInterpreterState * interp = PyInterpreterState_Get ();
7476 if (ref .index >= interp -> next_stackref ) {
75- _Py_FatalErrorFormat (__func__ , "Invalid StackRef with ID %" PRIu64 " at %s:%d\n" , ref .index , filename , linenumber );
77+ _Py_FatalErrorFormat (__func__ ,
78+ "Invalid StackRef with ID %" PRIu64 " at %s:%d\n" ,
79+ ref .index , filename , linenumber );
7680 }
7781 PyObject * obj ;
7882 if (ref .index < INITIAL_STACKREF_INDEX ) {
7983 if (ref .index == 0 ) {
80- _Py_FatalErrorFormat (__func__ , "Passing NULL to _Py_stackref_close at %s:%d\n" , filename , linenumber );
84+ _Py_FatalErrorFormat (__func__ ,
85+ "Passing NULL to _Py_stackref_close at %s:%d\n" ,
86+ filename , linenumber );
8187 }
8288 // Pre-allocated reference to None, False or True -- Do not clear
8389 TableEntry * entry = _Py_hashtable_get (interp -> open_stackrefs_table , (void * )ref .index );
@@ -94,7 +100,25 @@ _Py_stackref_close(_PyStackRef ref, const char *filename, int linenumber)
94100 ref .index , filename , linenumber , entry -> classname , entry -> obj , entry -> filename , entry -> linenumber );
95101 }
96102#endif
97- _Py_FatalErrorFormat (__func__ , "Invalid StackRef with ID %" PRIu64 "\n" , ref .index );
103+ _Py_FatalErrorFormat (__func__ ,
104+ "Invalid StackRef with ID %" PRIu64 " at %s:%d\n" ,
105+ ref .index , filename , linenumber );
106+ }
107+ if (!PyStackRef_IsNull (entry -> borrowed_from )) {
108+ _PyStackRef borrowed_from = entry -> borrowed_from ;
109+ TableEntry * entry_borrowed = _Py_hashtable_get (interp -> open_stackrefs_table , (void * )borrowed_from .index );
110+ if (entry_borrowed == NULL ) {
111+ _Py_FatalErrorFormat (__func__ ,
112+ "Invalid borrowed StackRef with ID %" PRIu64 " at %s:%d\n" ,
113+ borrowed_from .index , filename , linenumber );
114+ } else {
115+ entry_borrowed -> borrows -- ;
116+ }
117+ }
118+ if (entry -> borrows > 0 ) {
119+ _Py_FatalErrorFormat (__func__ ,
120+ "StackRef with ID %" PRIu64 " closed while borrows %d refs at %s:%d. Opened at %s:%d\n" ,
121+ ref .index , entry -> borrows , filename , linenumber , entry -> filename , entry -> linenumber );
98122 }
99123 obj = entry -> obj ;
100124 free (entry );
@@ -149,7 +173,9 @@ _Py_stackref_record_borrow(_PyStackRef ref, const char *filename, int linenumber
149173 ref .index , filename , linenumber , entry -> classname , entry -> obj , entry -> filename , entry -> linenumber );
150174 }
151175#endif
152- _Py_FatalErrorFormat (__func__ , "Invalid StackRef with ID %" PRIu64 " at %s:%d\n" , ref .index , filename , linenumber );
176+ _Py_FatalErrorFormat (__func__ ,
177+ "Invalid StackRef with ID %" PRIu64 " at %s:%d\n" ,
178+ ref .index , filename , linenumber );
153179 }
154180 entry -> filename_borrow = filename ;
155181 entry -> linenumber_borrow = linenumber ;
0 commit comments