cpython: cef6a32d805f (original) (raw)

Mercurial > cpython

changeset 100551:cef6a32d805f

On memory error, dump the memory block traceback Issue #26564: _PyObject_DebugDumpAddress() now dumps the traceback where a memory block was allocated on memory block. Use the tracemalloc module to get the traceback. [#26564]

Victor Stinner victor.stinner@gmail.com
date Tue, 15 Mar 2016 22:22:13 +0100
parents 5eb223e1638c
children 8215dae7ec3c
files Doc/c-api/memory.rst Doc/whatsnew/3.6.rst Misc/NEWS Modules/_tracemalloc.c Modules/hashtable.c Objects/bytearrayobject.c Objects/obmalloc.c Parser/pgenmain.c
diffstat 8 files changed, 126 insertions(+), 19 deletions(-)[+] [-] Doc/c-api/memory.rst 7 Doc/whatsnew/3.6.rst 43 Misc/NEWS 4 Modules/_tracemalloc.c 67 Modules/hashtable.c 6 Objects/bytearrayobject.c 1 Objects/obmalloc.c 9 Parser/pgenmain.c 8

line wrap: on

line diff

--- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -349,12 +349,19 @@ Customize Memory Allocators allocator functions of the :c:data:PYMEM_DOMAIN_OBJ domain (ex: :c:func:PyObject_Malloc) are called

.. _pymalloc:

--- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -129,7 +129,48 @@ the C library for all Python memory allo It helps to use external memory debuggers like Valgrind on a Python compiled in release mode. -(Contributed by Victor Stinner in :issue:26516.) +On error, the debug hooks on Python memory allocators now use the +:mod:tracemalloc module to get the traceback where a memory block was +allocated. + +Example of fatal error on buffer overflow using +python3.6 -X tracemalloc=5 (store 5 frames in traces):: +

+

+

+

+ +(Contributed by Victor Stinner in :issue:26516 and :issue:26564.) Other Language Changes

--- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Release date: tba Core and Builtins ----------------- +- Issue #26564: On error, the debug hooks on Python memory allocators now use

--- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1161,6 +1161,25 @@ finally: return get_traces.list; } +static traceback_t* +tracemalloc_get_traceback(const void *ptr) +{

+

+

+

+

+} + PyDoc_STRVAR(tracemalloc_get_object_traceback_doc, "_get_object_traceback(obj)\n" "\n" @@ -1175,11 +1194,7 @@ py_tracemalloc_get_object_traceback(PyOb { PyTypeObject *type; void *ptr;

-

type = Py_TYPE(obj); if (PyType_IS_GC(type)) @@ -1187,16 +1202,46 @@ py_tracemalloc_get_object_traceback(PyOb else ptr = (void *)obj;

-

+} + +#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) + +static void +_PyMem_DumpFrame(int fd, frame_t * frame) +{

} +/* Dump the traceback where a memory block was allocated into file descriptor

+

+

+} + +#undef PUTS + PyDoc_STRVAR(tracemalloc_start_doc, "start(nframe: int=1)\n" "\n"

--- a/Modules/hashtable.c +++ b/Modules/hashtable.c @@ -486,9 +486,9 @@ void void *data, *new_data; dst = _Py_hashtable_new_full(src->data_size, src->num_buckets,

--- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2820,6 +2820,7 @@ bytearray_hex(PyBytesObject self) { char argbuf = PyByteArray_AS_STRING(self); Py_ssize_t arglen = PyByteArray_GET_SIZE(self);

--- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1,5 +1,10 @@ #include "Python.h" + +/* Defined in tracemalloc.c */ +extern void _PyMem_DumpTraceback(int fd, const void ptr); + + / Python's malloc wrappers (see pymem.h) / / @@ -2202,6 +2207,10 @@ static void } fputc('\n', stderr); }

+

}

--- a/Parser/pgenmain.c +++ b/Parser/pgenmain.c @@ -38,11 +38,11 @@ Py_Exit(int sts) } #ifdef WITH_THREAD -/* Needed by obmalloc.c / +/ Functions needed by obmalloc.c */ int PyGILState_Check(void) -{

-} +{ return 1; } +void _PyMem_DumpTraceback(int fd, const void *ptr) +{} #endif int