diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2013-12-01 10:03:26 +0100 |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2013-12-01 10:03:26 +0100 |
commit | 7049e92e939bfdb1d9e34a8d3a5d1611d8fd1a4a (patch) | |
tree | 616d8d2a4ca7e0f8742d4cf8f17150bce9eb816e /Modules/_tracemalloc.c | |
parent | e90b63bb003a4339ac5243d7728fbd2792d4fe8f (diff) | |
download | cpython-7049e92e939bfdb1d9e34a8d3a5d1611d8fd1a4a.tar.gz |
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 2b2222ea87..7b88a74594 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(); +} + |