diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2013-12-01 09:03:26 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2013-12-01 09:03:26 (GMT) |
commit | be0708f06634ae4426ca9032314be4b8902d6008 (patch) | |
tree | e9b48e4c87ed3b07bdf1237d3df57282bcbf5123 /Modules/_tracemalloc.c | |
parent | 54532c9742523814bbc43ccbd1a4560ec3d449d3 (diff) | |
download | cpython-be0708f06634ae4426ca9032314be4b8902d6008.zip cpython-be0708f06634ae4426ca9032314be4b8902d6008.tar.gz cpython-be0708f06634ae4426ca9032314be4b8902d6008.tar.bz2 |
Closes #19831: Stop tracemalloc later at Python shutdown to be able to use
tracemalloc in objects destructor
Replace atexit handler with an harcoded C function _PyTraceMalloc_Fini().
Diffstat (limited to 'Modules/_tracemalloc.c')
-rw-r--r-- | Modules/_tracemalloc.c | 77 |
1 files changed, 10 insertions, 67 deletions
diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 2b2222e..7b88a74 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -9,7 +9,6 @@ /* Forward declaration */ static void tracemalloc_stop(void); -static int tracemalloc_atexit_register(void); static void* raw_malloc(size_t size); static void raw_free(void *ptr); @@ -36,9 +35,6 @@ static struct { TRACEMALLOC_FINALIZED } initialized; - /* atexit handler registered? */ - int atexit_registered; - /* Is tracemalloc tracing memory allocations? Variable protected by the GIL */ int tracing; @@ -46,7 +42,7 @@ static struct { /* limit of the number of frames in a traceback, 1 by default. Variable protected by the GIL. */ int max_nframe; -} tracemalloc_config = {TRACEMALLOC_NOT_INITIALIZED, 0, 0, 1}; +} tracemalloc_config = {TRACEMALLOC_NOT_INITIALIZED, 0, 1}; #if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD) /* This lock is needed because tracemalloc_free() is called without @@ -802,9 +798,6 @@ tracemalloc_start(int max_nframe) return 0; } - if (tracemalloc_atexit_register() < 0) - return -1; - assert(1 <= max_nframe && max_nframe <= MAX_NFRAME); tracemalloc_config.max_nframe = max_nframe; @@ -1140,65 +1133,6 @@ py_tracemalloc_get_object_traceback(PyObject *self, PyObject *obj) return traceback_to_pyobject(trace.traceback, NULL); } -static PyObject* -tracemalloc_atexit(PyObject *self) -{ -#ifdef WITH_THREAD - assert(PyGILState_Check()); -#endif - tracemalloc_deinit(); - Py_RETURN_NONE; -} - -static PyMethodDef atexit_method = { - "_atexit", (PyCFunction)tracemalloc_atexit, METH_NOARGS, NULL}; - -static int -tracemalloc_atexit_register(void) -{ - PyObject *method = NULL, *atexit = NULL, *func = NULL; - PyObject *result; - int ret = -1; - - if (tracemalloc_config.atexit_registered) - return 0; - tracemalloc_config.atexit_registered = 1; - - /* private functions */ - method = PyCFunction_New(&atexit_method, NULL); - if (method == NULL) - goto done; - - atexit = PyImport_ImportModule("atexit"); - if (atexit == NULL) { - if (!PyErr_Warn(PyExc_ImportWarning, - "atexit module is missing: " - "cannot automatically disable tracemalloc at exit")) - { - PyErr_Clear(); - return 0; - } - goto done; - } - - func = PyObject_GetAttrString(atexit, "register"); - if (func == NULL) - goto done; - - result = PyObject_CallFunction(func, "O", method); - if (result == NULL) - goto done; - Py_DECREF(result); - - ret = 0; - -done: - Py_XDECREF(method); - Py_XDECREF(func); - Py_XDECREF(atexit); - return ret; -} - PyDoc_STRVAR(tracemalloc_start_doc, "start(nframe: int=1)\n" "\n" @@ -1439,3 +1373,12 @@ _PyTraceMalloc_Init(void) return tracemalloc_start(nframe); } +void +_PyTraceMalloc_Fini(void) +{ +#ifdef WITH_THREAD + assert(PyGILState_Check()); +#endif + tracemalloc_deinit(); +} + |