Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 71a3522

Browse files
authored
bpo-38644: Make tstate more explicit inside pystate.c (GH-19182)
Fix PyInterpreterState_New(): Don't call PyErr_SetString() when there is no current Python thread state (if tstate is NULL).
1 parent 7281898 commit 71a3522

File tree

3 files changed

+67
-47
lines changed

3 files changed

+67
-47
lines changed

Doc/c-api/init.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,8 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
11191119
Return the interpreter's unique ID. If there was any error in doing
11201120
so then ``-1`` is returned and an error is set.
11211121
1122+
The caller must hold the GIL.
1123+
11221124
.. versionadded:: 3.7
11231125
11241126

Doc/c-api/module.rst

+4
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,8 @@ since multiple such modules can be created from a single definition.
527527
mechanisms (either by calling it directly, or by referring to its
528528
implementation for details of the required state updates).
529529
530+
The caller must hold the GIL.
531+
530532
Return 0 on success or -1 on failure.
531533
532534
.. versionadded:: 3.3
@@ -536,4 +538,6 @@ since multiple such modules can be created from a single definition.
536538
Removes the module object created from *def* from the interpreter state.
537539
Return 0 on success or -1 on failure.
538540
541+
The caller must hold the GIL.
542+
539543
.. versionadded:: 3.3

Python/pystate.c

+61-47
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "pycore_pylifecycle.h"
99
#include "pycore_pymem.h"
1010
#include "pycore_pystate.h"
11+
#include "pycore_sysmodule.h"
1112

1213
/* --------------------------------------------------------------------------
1314
CAUTION
@@ -203,7 +204,10 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime)
203204
PyInterpreterState *
204205
PyInterpreterState_New(void)
205206
{
206-
if (PySys_Audit("cpython.PyInterpreterState_New", NULL) < 0) {
207+
PyThreadState *tstate = _PyThreadState_GET();
208+
/* tstate is NULL when Py_InitializeFromConfig() calls
209+
PyInterpreterState_New() to create the main interpreter. */
210+
if (_PySys_Audit(tstate, "cpython.PyInterpreterState_New", NULL) < 0) {
207211
return NULL;
208212
}
209213

@@ -214,6 +218,7 @@ PyInterpreterState_New(void)
214218

215219
interp->id_refcount = -1;
216220

221+
/* Don't get runtime from tstate since tstate can be NULL */
217222
_PyRuntimeState *runtime = &_PyRuntime;
218223
interp->runtime = runtime;
219224

@@ -235,8 +240,10 @@ PyInterpreterState_New(void)
235240
HEAD_LOCK(runtime);
236241
if (interpreters->next_id < 0) {
237242
/* overflow or Py_Initialize() not called! */
238-
PyErr_SetString(PyExc_RuntimeError,
239-
"failed to get an interpreter ID");
243+
if (tstate != NULL) {
244+
_PyErr_SetString(tstate, PyExc_RuntimeError,
245+
"failed to get an interpreter ID");
246+
}
240247
PyMem_RawFree(interp);
241248
interp = NULL;
242249
}
@@ -268,8 +275,11 @@ PyInterpreterState_Clear(PyInterpreterState *interp)
268275
{
269276
_PyRuntimeState *runtime = interp->runtime;
270277

271-
if (PySys_Audit("cpython.PyInterpreterState_Clear", NULL) < 0) {
272-
PyErr_Clear();
278+
/* Use the current Python thread state to call audit hooks,
279+
not the current Python thread state of 'interp'. */
280+
PyThreadState *tstate = _PyThreadState_GET();
281+
if (_PySys_Audit(tstate, "cpython.PyInterpreterState_Clear", NULL) < 0) {
282+
_PyErr_Clear(tstate);
273283
}
274284

275285
HEAD_LOCK(runtime);
@@ -655,12 +665,13 @@ int
655665
_PyState_AddModule(PyThreadState *tstate, PyObject* module, struct PyModuleDef* def)
656666
{
657667
if (!def) {
658-
assert(PyErr_Occurred());
668+
assert(_PyErr_Occurred(tstate));
659669
return -1;
660670
}
661671
if (def->m_slots) {
662-
PyErr_SetString(PyExc_SystemError,
663-
"PyState_AddModule called on module with slots");
672+
_PyErr_SetString(tstate,
673+
PyExc_SystemError,
674+
"PyState_AddModule called on module with slots");
664675
return -1;
665676
}
666677

@@ -707,28 +718,29 @@ PyState_AddModule(PyObject* module, struct PyModuleDef* def)
707718
int
708719
PyState_RemoveModule(struct PyModuleDef* def)
709720
{
710-
PyInterpreterState *state;
711-
Py_ssize_t index = def->m_base.m_index;
721+
PyThreadState *tstate = _PyThreadState_GET();
722+
PyInterpreterState *interp = tstate->interp;
723+
712724
if (def->m_slots) {
713-
PyErr_SetString(PyExc_SystemError,
714-
"PyState_RemoveModule called on module with slots");
725+
_PyErr_SetString(tstate,
726+
PyExc_SystemError,
727+
"PyState_RemoveModule called on module with slots");
715728
return -1;
716729
}
717-
state = _PyInterpreterState_GET_UNSAFE();
730+
731+
Py_ssize_t index = def->m_base.m_index;
718732
if (index == 0) {
719733
Py_FatalError("invalid module index");
720-
return -1;
721734
}
722-
if (state->modules_by_index == NULL) {
735+
if (interp->modules_by_index == NULL) {
723736
Py_FatalError("Interpreters module-list not accessible.");
724-
return -1;
725737
}
726-
if (index > PyList_GET_SIZE(state->modules_by_index)) {
738+
if (index > PyList_GET_SIZE(interp->modules_by_index)) {
727739
Py_FatalError("Module index out of bounds.");
728-
return -1;
729740
}
741+
730742
Py_INCREF(Py_None);
731-
return PyList_SetItem(state->modules_by_index, index, Py_None);
743+
return PyList_SetItem(interp->modules_by_index, index, Py_None);
732744
}
733745

734746
/* Used by PyImport_Cleanup() */
@@ -1114,49 +1126,51 @@ PyThreadState_Next(PyThreadState *tstate) {
11141126
PyObject *
11151127
_PyThread_CurrentFrames(void)
11161128
{
1117-
PyObject *result;
1118-
PyInterpreterState *i;
1119-
1120-
if (PySys_Audit("sys._current_frames", NULL) < 0) {
1129+
PyThreadState *tstate = _PyThreadState_GET();
1130+
if (_PySys_Audit(tstate, "sys._current_frames", NULL) < 0) {
11211131
return NULL;
11221132
}
11231133

1124-
result = PyDict_New();
1125-
if (result == NULL)
1134+
PyObject *result = PyDict_New();
1135+
if (result == NULL) {
11261136
return NULL;
1137+
}
11271138

11281139
/* for i in all interpreters:
11291140
* for t in all of i's thread states:
11301141
* if t's frame isn't NULL, map t's id to its frame
11311142
* Because these lists can mutate even when the GIL is held, we
11321143
* need to grab head_mutex for the duration.
11331144
*/
1134-
_PyRuntimeState *runtime = &_PyRuntime;
1145+
_PyRuntimeState *runtime = tstate->interp->runtime;
11351146
HEAD_LOCK(runtime);
1147+
PyInterpreterState *i;
11361148
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
11371149
PyThreadState *t;
11381150
for (t = i->tstate_head; t != NULL; t = t->next) {
1139-
PyObject *id;
1140-
int stat;
11411151
struct _frame *frame = t->frame;
1142-
if (frame == NULL)
1152+
if (frame == NULL) {
11431153
continue;
1144-
id = PyLong_FromUnsignedLong(t->thread_id);
1145-
if (id == NULL)
1146-
goto Fail;
1147-
stat = PyDict_SetItem(result, id, (PyObject *)frame);
1154+
}
1155+
PyObject *id = PyLong_FromUnsignedLong(t->thread_id);
1156+
if (id == NULL) {
1157+
goto fail;
1158+
}
1159+
int stat = PyDict_SetItem(result, id, (PyObject *)frame);
11481160
Py_DECREF(id);
1149-
if (stat < 0)
1150-
goto Fail;
1161+
if (stat < 0) {
1162+
goto fail;
1163+
}
11511164
}
11521165
}
1153-
HEAD_UNLOCK(runtime);
1154-
return result;
1166+
goto done;
1167+
1168+
fail:
1169+
Py_CLEAR(result);
11551170

1156-
Fail:
1171+
done:
11571172
HEAD_UNLOCK(runtime);
1158-
Py_DECREF(result);
1159-
return NULL;
1173+
return result;
11601174
}
11611175

11621176
/* Python "auto thread state" API. */
@@ -1436,19 +1450,19 @@ _PyObject_CheckCrossInterpreterData(PyObject *obj)
14361450
}
14371451

14381452
static int
1439-
_check_xidata(_PyCrossInterpreterData *data)
1453+
_check_xidata(PyThreadState *tstate, _PyCrossInterpreterData *data)
14401454
{
14411455
// data->data can be anything, including NULL, so we don't check it.
14421456

14431457
// data->obj may be NULL, so we don't check it.
14441458

14451459
if (data->interp < 0) {
1446-
PyErr_SetString(PyExc_SystemError, "missing interp");
1460+
_PyErr_SetString(tstate, PyExc_SystemError, "missing interp");
14471461
return -1;
14481462
}
14491463

14501464
if (data->new_object == NULL) {
1451-
PyErr_SetString(PyExc_SystemError, "missing new_object func");
1465+
_PyErr_SetString(tstate, PyExc_SystemError, "missing new_object func");
14521466
return -1;
14531467
}
14541468

@@ -1460,9 +1474,9 @@ _check_xidata(_PyCrossInterpreterData *data)
14601474
int
14611475
_PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data)
14621476
{
1463-
// PyInterpreterState_Get() aborts if lookup fails, so we don't need
1464-
// to check the result for NULL.
1465-
PyInterpreterState *interp = PyInterpreterState_Get();
1477+
// PyThreadState_Get() aborts if tstate is NULL.
1478+
PyThreadState *tstate = PyThreadState_Get();
1479+
PyInterpreterState *interp = tstate->interp;
14661480

14671481
// Reset data before re-populating.
14681482
*data = (_PyCrossInterpreterData){0};
@@ -1483,7 +1497,7 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data)
14831497

14841498
// Fill in the blanks and validate the result.
14851499
data->interp = interp->id;
1486-
if (_check_xidata(data) != 0) {
1500+
if (_check_xidata(tstate, data) != 0) {
14871501
_PyCrossInterpreterData_Release(data);
14881502
return -1;
14891503
}

0 commit comments

Comments
 (0)