8000 [3.12] gh-107630: Revert "[3.12] gh-107080: Fix Py_TRACE_REFS Crashes… · python/cpython@6e4eec7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6e4eec7

Browse files
[3.12] gh-107630: Revert "[3.12] gh-107080: Fix Py_TRACE_REFS Crashes Under Isolated Subinterpreters (gh-107567) (#107599)" (#107648)
Revert "[3.12] gh-107080: Fix Py_TRACE_REFS Crashes Under Isolated Subinterpreters (gh-107567) (#107599)" This reverts commit 58af229.
1 parent 0e7a4f7 commit 6e4eec7

File tree

6 files changed

+29
-62
lines changed

6 files changed

+29
-62
lines changed

Include/internal/pycore_object.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,8 @@ extern void _PyDebug_PrintTotalRefs(void);
271271

272272
#ifdef Py_TRACE_REFS
273273
extern void _Py_AddToAllObjects(PyObject *op, int force);
274-
extern void _Py_PrintReferences(PyInterpreterState *, FILE *);
275-
extern void _Py_PrintReferenceAddresses(PyInterpreterState *, FILE *);
274+
extern void _Py_PrintReferences(FILE *);
275+
extern void _Py_PrintReferenceAddresses(FILE *);
276276
#endif
277277

278278

Include/internal/pycore_object_state.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,17 @@ extern "C" {
1111
struct _py_object_runtime_state {
1212
#ifdef Py_REF_DEBUG
1313
Py_ssize_t interpreter_leaks;
14-
#endif
14+
#else
1515
int _not_used;
16+
#endif
1617
};
1718

1819
struct _py_object_state {
1920
#ifdef Py_REF_DEBUG
2021
Py_ssize_t reftotal;
21-
#endif
22-
#ifdef Py_TRACE_REFS
23-
/* Head of circular doubly-linked list of all objects. These are linked
24-
* together via the _ob_prev and _ob_next members of a PyObject, which
25-
* exist only in a Py_TRACE_REFS build.
26-
*/
27-
PyObject refchain;
28-
#endif
22+
#else
2923
int _not_used;
24+
#endif
3025
};
3126

3227

Include/internal/pycore_runtime_init.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ extern PyTypeObject _PyExc_MemoryError;
101101
{ .threshold = 10, }, \
102102
}, \
103103
}, \
104-
.object_state = _py_object_state_INIT(INTERP), \
105104
.dtoa = _dtoa_state_INIT(&(INTERP)), \
106105
.dict_state = _dict_state_INIT, \
107106
.func_state = { \
@@ -131,16 +130,6 @@ extern PyTypeObject _PyExc_MemoryError;
131130
.context_ver = 1, \
132131
}
133132

134-
#ifdef Py_TRACE_REFS
135-
# define _py_object_state_INIT(INTERP) \
136-
{ \
137-
.refchain = {&INTERP.object_state.refchain, &INTERP.object_state.refchain}, \
138-
}
139-
#else
140-
# define _py_object_state_INIT(INTERP) \
141-
{ 0 }
142-
#endif
143-
144133

145134
// global objects
146135

Misc/NEWS.d/next/Core and Builtins/2023-08-02-12-24-51.gh-issue-107080.PNolFU.rst

Lines changed: 0 additions & 4 deletions
This file was deleted.

Objects/object.c

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,11 @@ _PyDebug_PrintTotalRefs(void) {
158158
Do not call them otherwise, they do not initialize the object! */
159159

160160
#ifdef Py_TRACE_REFS
161-
162-
#define REFCHAIN(interp) &interp->object_state.refchain
161+
/* Head of circular doubly-linked list of all objects. These are linked
162+
* together via the _ob_prev and _ob_next members of a PyObject, which
163+
* exist only in a Py_TRACE_REFS build.
164+
*/
165+
static PyObject refchain = {&refchain, &refchain};
163166

164167
/* Insert op at the front of the list of all objects. If force is true,
165168
* op is added even if _ob_prev and _ob_next are non-NULL already. If
@@ -184,11 +187,10 @@ _Py_AddToAllObjects(PyObject *op, int force)
184187
}
185188
#endif
186189
if (force || op->_ob_prev == NULL) {
187-
PyObject *refchain = REFCHAIN(_PyInterpreterState_GET());
188-
op->_ob_next = refchain->_ob_next;
189-
op->_ob_prev = refchain;
190-
refchain->_ob_next->_ob_prev = op;
191-
refchain->_ob_next = op;
190+
op->_ob_next = refchain._ob_next;
191+
op->_ob_prev = &refchain;
192+
refchain._ob_next->_ob_prev = op;
193+
refchain._ob_next = op;
192194
}
193195
}
194196
#endif /* Py_TRACE_REFS */
@@ -2204,21 +2206,20 @@ _Py_ForgetReference(PyObject *op)
22042206
_PyObject_ASSERT_FAILED_MSG(op, "negative refcnt");
22052207
}
22062208

2207-
PyObject *refchain = REFCHAIN(_PyInterpreterState_GET());
2208-
if (op == refchain ||
2209+
if (op == &refchain ||
22092210
op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op)
22102211
{
22112212
_PyObject_ASSERT_FAILED_MSG(op, "invalid object chain");
22122213
}
22132214

22142215
#ifdef SLOW_UNREF_CHECK
22152216
PyObject *p;
2216-
for (p = refchain->_ob_next; p != refchain; p = p->_ob_next) {
2217+
for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
22172218
if (p == op) {
22182219
break;
22192220
}
22202221
}
2221-
if (p == refchain) {
2222+
if (p == &refchain) {
22222223
/* Not found */
22232224
_PyObject_ASSERT_FAILED_MSG(op,
22242225
"object not found in the objects list");
@@ -2234,15 +2235,11 @@ _Py_ForgetReference(PyObject *op)
22342235 10000
* interpreter must be in a healthy state.
22352236
*/
22362237
void
2237-
_Py_PrintReferences(PyInterpreterState *interp, FILE *fp)
2238+
_Py_PrintReferences(FILE *fp)
22382239
{
22392240
PyObject *op;
2240-
if (interp == NULL) {
2241-
interp = _PyInterpreterState_Main();
2242-
}
22432241
fprintf(fp, "Remaining objects:\n");
2244-
PyObject *refchain = REFCHAIN(interp);
2245-
for (op = refchain->_ob_next; op != refchain; op = op->_ob_next) {
2242+
for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
22462243
fprintf(fp, "%p [%zd] ", (void *)op, Py_REFCNT(op));
22472244
if (PyObject_Print(op, fp, 0) != 0) {
22482245
PyErr_Clear();
@@ -2254,42 +2251,34 @@ _Py_PrintReferences(PyInterpreterState *interp, FILE *fp)
22542251
/* Print the addresses of all live objects. Unlike _Py_PrintReferences, this
22552252
* doesn't make any calls to the Python C API, so is always safe to call.
22562253
*/
2257-
// XXX This function is not safe to use if the interpreter has been
2258-
// freed or is in an unhealthy state (e.g. late in finalization).
2259-
// The call in Py_FinalizeEx() is okay since the main interpreter
2260-
// is statically allocated.
22612254
void
2262-
_Py_PrintReferenceAddresses(PyInterpreterState *interp, FILE *fp)
2255+
_Py_PrintReferenceAddresses(FILE *fp)
22632256
{
22642257
PyObject *op;
2265-
PyObject *refchain = REFCHAIN(interp);
22662258
fprintf(fp, "Remaining object addresses:\n");
2267-
for (op = refchain->_ob_next; op != refchain; op = op->_ob_next)
2259+
for (op = refchain._ob_next; op != &refchain; op = op->_ob_next)
22682260
fprintf(fp, "%p [%zd] %s\n", (void *)op,
22692261
Py_REFCNT(op), Py_TYPE(op)->tp_name);
22702262
}
22712263

2272-
/* The implementation of sys.getobjects(). */
22732264
PyObject *
22742265
_Py_GetObjects(PyObject *self, PyObject *args)
22752266
{
22762267
int i, n;
22772268
PyObject *t = NULL;
22782269
PyObject *res, *op;
2279-
PyInterpreterState *interp = _PyInterpreterState_GET();
22802270

22812271
if (!PyArg_ParseTuple(args, "i|O", &n, &t))
22822272
return NULL;
2283-
PyObject *refchain = REFCHAIN(interp);
2284-
op = refchain->_ob_next;
2273+
op = refchain._ob_next;
22852274
res = PyList_New(0);
22862275
if (res == NULL)
22872276
return NULL;
2288-
for (i = 0; (n == 0 || i < n) && op != refchain; i++) {
2277+
for (i = 0; (n == 0 || i < n) && op != &refchain; i++) {
22892278
while (op == self || op == args || op == res || op == t ||
22902279
(t != NULL && !Py_IS_TYPE(op, (PyTypeObject *) t))) {
22912280
op = op->_ob_next;
2292-
if (op == refchain)
2281+
if (op == &refchain)
22932282
return res;
22942283
}
22952284
if (PyList_Append(res, op) < 0) {
@@ -2301,8 +2290,6 @@ _Py_GetObjects(PyObject *self, PyObject *args)
23012290
return res;
23022291
}
23032292

2304-
#undef REFCHAIN
2305-
23062293
#endif
23072294

23082295

Python/pylifecycle.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,11 +1920,11 @@ Py_FinalizeEx(void)
19201920
}
19211921

19221922
if (dump_refs) {
1923-
_Py_PrintReferences(tstate->interp, stderr);
1923+
_Py_PrintReferences(stderr);
19241924
}
19251925

19261926
if (dump_refs_fp != NULL) {
1927-
_Py_PrintReferences(tstate->interp, dump_refs_fp);
1927+
_Py_PrintReferences(dump_refs_fp);
19281928
}
19291929
#endif /* Py_TRACE_REFS */
19301930

@@ -1960,11 +1960,11 @@ Py_FinalizeEx(void)
19601960
*/
19611961

19621962
if (dump_refs) {
1963-
_Py_PrintReferenceAddresses(tstate->interp, stderr);
1963+
_Py_PrintReferenceAddresses(stderr);
19641964
}
19651965

19661966
if (dump_refs_fp != NULL) {
1967-
_Py_PrintReferenceAddresses(tstate->interp, dump_refs_fp);
1967+
_Py_PrintReferenceAddresses(dump_refs_fp);
19681968
fclose(dump_refs_fp);
19691969
}
19701970
#endif /* Py_TRACE_REFS */

0 commit comments

Comments
 (0)
0