From a4a47f2df066e3c2ee1dd92e08a1b702eaa037f4 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 3 Dec 2018 12:38:40 +0100 Subject: [PATCH] bpo-35368: Add assertions in pymalloc to check GIL Add "assert(PyGILState_Check());" assertion to pymalloc functions like pymalloc_alloc() to ensure that the GIL is held. Remove also _PyGILState_check_enabled define: use directly _PyRuntime.gilstate.check_enabled. Note: The debug hook already uses _PyMem_DebugCheckGIL() to check that the GIL is held. --- Include/internal/pycore_pystate.h | 6 ++---- Objects/obmalloc.c | 12 +++++++++++- Python/pylifecycle.c | 2 +- Python/pystate.c | 3 ++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 4f5545aaa45fab..72f6ae74d9543c 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -20,6 +20,8 @@ extern "C" { /* GIL state */ struct _gilstate_runtime_state { + /* Issue #26558: Flag to disable PyGILState_Check(). + If set to non-zero, PyGILState_Check() always return 1. */ int check_enabled; /* Assuming the current thread holds the GIL, this is the PyThreadState for the current thread. */ @@ -36,10 +38,6 @@ struct _gilstate_runtime_state { /* hook for PyEval_GetFrame(), requested for Psyco */ #define _PyThreadState_GetFrame _PyRuntime.gilstate.getframe -/* Issue #26558: Flag to disable PyGILState_Check(). - If set to non-zero, PyGILState_Check() always return 1. */ -#define _PyGILState_check_enabled _PyRuntime.gilstate.check_enabled - /* interpreter state */ diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 1c2a32050f9381..b9322354c9e37d 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1358,6 +1358,9 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) poolp next; uint size; + /* pymalloc is protected by the GIL */ + assert(PyGILState_Check()); + #ifdef WITH_VALGRIND if (UNLIKELY(running_on_valgrind == -1)) { running_on_valgrind = RUNNING_ON_VALGRIND; @@ -1590,6 +1593,9 @@ pymalloc_free(void *ctx, void *p) assert(p != NULL); + /* pymalloc is protected by the GIL */ + assert(PyGILState_Check()); + #ifdef WITH_VALGRIND if (UNLIKELY(running_on_valgrind > 0)) { return 0; @@ -1824,6 +1830,9 @@ pymalloc_realloc(void *ctx, void **newptr_p, void *p, size_t nbytes) assert(p != NULL); + /* pymalloc is protected by the GIL */ + assert(PyGILState_Check()); + #ifdef WITH_VALGRIND /* Treat running_on_valgrind == -1 the same as 0 */ if (UNLIKELY(running_on_valgrind > 0)) { @@ -2193,9 +2202,10 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) static void _PyMem_DebugCheckGIL(void) { - if (!PyGILState_Check()) + if (!PyGILState_Check()) { Py_FatalError("Python memory allocator called " "without holding the GIL"); + } } static void * diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 6de32decc5aed3..7b18e2b0607dae 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1232,7 +1232,7 @@ new_interpreter(PyThreadState **tstate_p) /* Issue #10915, #15751: The GIL API doesn't work with multiple interpreters: disable PyGILState_Check(). */ - _PyGILState_check_enabled = 0; + _PyRuntime.gilstate.check_enabled = 0; interp = PyInterpreterState_New(); if (interp == NULL) { diff --git a/Python/pystate.c b/Python/pystate.c index f86f5a96f07450..646d4d8de706e3 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1078,8 +1078,9 @@ PyGILState_Check(void) { PyThreadState *tstate; - if (!_PyGILState_check_enabled) + if (!_PyRuntime.gilstate.check_enabled) { return 1; + } if (!PyThread_tss_is_created(&_PyRuntime.gilstate.autoTSSkey)) { return 1;