@@ -47,33 +47,51 @@ _Py_stackref_get_object(_PyStackRef ref)
47
47
if (ref .index >= interp -> next_stackref ) {
48
48
_Py_FatalErrorFormat (__func__ , "Garbled stack ref with ID %" PRIu64 "\n" , ref .index );
49
49
}
50
- TableEntry * entry = _Py_hashtable_get (interp -> stackref_debug_table , (void * )ref .index );
50
+ TableEntry * entry = _Py_hashtable_get (interp -> open_stackrefs_table , (void * )ref .index );
51
51
if (entry == NULL ) {
52
52
_Py_FatalErrorFormat (__func__ , "Accessing closed stack ref with ID %" PRIu64 "\n" , ref .index );
53
53
}
54
54
return entry -> obj ;
55
55
}
56
56
57
57
PyObject *
58
- _Py_stackref_close (_PyStackRef ref )
58
+ _Py_stackref_close (_PyStackRef ref , const char * filename , int linenumber )
59
59
{
60
60
PyInterpreterState * interp = PyInterpreterState_Get ();
61
61
if (ref .index >= interp -> next_stackref ) {
62
- _Py_FatalErrorFormat (__func__ , "Garbled stack ref with ID %" PRIu64 "\n" , ref .index );
62
+ _Py_FatalErrorFormat (__func__ , "Invalid StackRef with ID %" PRIu64 " at %s:%d\n" , (void * )ref .index , filename , linenumber );
63
+
63
64
}
64
65
PyObject * obj ;
65
66
if (ref .index <= LAST_PREDEFINED_STACKREF_INDEX ) {
66
67
// Pre-allocated reference to None, False or True -- Do not clear
67
- TableEntry * entry = _Py_hashtable_get (interp -> stackref_debug_table , (void * )ref .index );
68
+ TableEntry * entry = _Py_hashtable_get (interp -> open_stackrefs_table , (void * )ref .index );
68
69
obj = entry -> obj ;
69
70
}
70
71
else {
71
- TableEntry * entry = _Py_hashtable_steal (interp -> stackref_debug_table , (void * )ref .index );
72
+ TableEntry * entry = _Py_hashtable_steal (interp -> open_stackrefs_table , (void * )ref .index );
72
73
if (entry == NULL ) {
74
+ #ifdef Py_STACKREF_CLOSE_DEBUG
75
+ entry = _Py_hashtable_get (interp -> closed_stackrefs_table , (void * )ref .index );
76
+ if (entry != NULL ) {
77
+ _Py_FatalErrorFormat (__func__ ,
78
+ "Double close of ref ID %" PRIu64 " at %s:%d. Referred to instance of %s at %p. Closed at %s:%d\n" ,
79
+ (void * )ref .index , filename , linenumber , entry -> classname , entry -> obj , entry -> filename , entry -> linenumber );
80
+ }
81
+ #endif
73
82
_Py_FatalErrorFormat (__func__ , "Invalid StackRef with ID %" PRIu64 "\n" , (void * )ref .index );
74
83
}
75
84
obj = entry -> obj ;
76
85
free (entry );
86
+ #ifdef Py_STACKREF_CLOSE_DEBUG
87
+ TableEntry * close_entry = make_table_entry (obj , filename , linenumber );
88
+ if (close_entry == NULL ) {
89
+ Py_FatalError ("No memory left for stackref debug table" );
90
+ }
91
+ if (_Py_hashtable_set (interp -> closed_stackrefs_table , (void * )ref .index , close_entry ) < 0 ) {
92
+ Py_FatalError ("No memory left for stackref debug table" );
93
+ }
94
+ #endif
77
95
}
78
96
return obj ;
79
97
}
@@ -90,7 +108,7 @@ _Py_stackref_create(PyObject *obj, const char *filename, int linenumber)
90
108
if (entry == NULL ) {
91
109
Py_FatalError ("No memory left for stackref debug table" );
92
110
}
93
- if (_Py_hashtable_set (interp -> stackref_debug_table , (void * )new_id , entry ) < 0 ) {
111
+ if (_Py_hashtable_set (interp -> open_stackrefs_table , (void * )new_id , entry ) < 0 ) {
94
112
Py_FatalError ("No memory left for stackref debug table" );
95
113
}
96
114
return (_PyStackRef ){ .index = new_id };
@@ -103,9 +121,17 @@ _Py_stackref_record_borrow(_PyStackRef ref, const char *filename, int linenumber
103
121
return ;
104
122
}
105
123
PyInterpreterState * interp = PyInterpreterState_Get ();
106
- TableEntry * entry = _Py_hashtable_get (interp -> stackref_debug_table , (void * )ref .index );
124
+ TableEntry * entry = _Py_hashtable_get (interp -> open_stackrefs_table , (void * )ref .index );
107
125
if (entry == NULL ) {
108
- _Py_FatalErrorFormat (__func__ , "Invalid StackRef with ID %" PRIu64 "\n" , (void * )ref .index );
126
+ #ifdef Py_STACKREF_CLOSE_DEBUG
127
+ entry = _Py_hashtable_get (interp -> closed_stackrefs_table , (void * )ref .index );
128
+ if (entry != NULL ) {
129
+ _Py_FatalErrorFormat (__func__ ,
130
+ "Borrow of closed ref ID %" PRIu64 " at %s:%d. Referred to instance of %s at %p. Closed at %s:%d\n" ,
131
+ (void * )ref .index , filename , linenumber , entry -> classname , entry -> obj , entry -> filename , entry -> linenumber );
132
+ }
133
+ #endif
134
+ _Py_FatalErrorFormat (__func__ , "Invalid StackRef with ID %" PRIu64 " at %s:%d\n" , (void * )ref .index , filename , linenumber );
109
135
}
110
136
entry -> filename_borrow = filename ;
111
137
entry -> linenumber_borrow = linenumber ;
@@ -121,7 +147,7 @@ _Py_stackref_associate(PyInterpreterState *interp, PyObject *obj, _PyStackRef re
121
147
if (entry == NULL ) {
122
148
Py_FatalError ("No memory left for stackref debug table" );
123
149
}
124
- if (_Py_hashtable_set (interp -> stackref_debug_table , (void * )ref .index , (void * )entry ) < 0 ) {
150
+ if (_Py_hashtable_set (interp -> open_stackrefs_table , (void * )ref .index , (void * )entry ) < 0 ) {
125
151
Py_FatalError ("No memory left for stackref debug table" );
126
152
}
127
153
}
147
173
_Py_stackref_report_leaks (PyInterpreterState * interp )
148
174
{
149
175
int leak = 0 ;
150
- _Py_hashtable_foreach (interp -> stackref_debug_table , report_leak , & leak );
176
+ _Py_hashtable_foreach (interp -> open_stackrefs_table , report_leak , & leak );
151
177
if (leak ) {
152
178
Py_FatalError ("Stackrefs leaked." );
153
179
}
0 commit comments