[Python-checkins] cpython: Issue #19741: tracemalloc: report tracemalloc_log_alloc() failure to the caller

victor.stinner python-checkins at python.org
Sun Nov 24 12:02:49 CET 2013


http://hg.python.org/cpython/rev/d8de3f4c7662
changeset:   87495:d8de3f4c7662
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Sun Nov 24 11:37:15 2013 +0100
summary:
  Issue #19741: tracemalloc: report tracemalloc_log_alloc() failure to the caller
for new allocations, but not when a memory block was already resized

files:
  Modules/_tracemalloc.c |  47 ++++++++++++++++++-----------
  1 files changed, 29 insertions(+), 18 deletions(-)


diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c
--- a/Modules/_tracemalloc.c
+++ b/Modules/_tracemalloc.c
@@ -436,40 +436,35 @@
     return traceback;
 }
 
-static void
+static int
 tracemalloc_log_alloc(void *ptr, size_t size)
 {
     traceback_t *traceback;
     trace_t trace;
+    int res;
 
 #ifdef WITH_THREAD
     assert(PyGILState_Check());
 #endif
 
     traceback = traceback_new();
-    if (traceback == NULL) {
-        /* Memory allocation failed. The error cannot be reported to the
-           caller, because realloc() may already have shrink the memory block
-           and so removed bytes. */
-        return;
-    }
+    if (traceback == NULL)
+        return -1;
 
     trace.size = size;
     trace.traceback = traceback;
 
     TABLES_LOCK();
-    if (_Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace) == 0) {
+    res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace);
+    if (res == 0) {
         assert(tracemalloc_traced_memory <= PY_SIZE_MAX - size);
         tracemalloc_traced_memory += size;
         if (tracemalloc_traced_memory > tracemalloc_max_traced_memory)
             tracemalloc_max_traced_memory = tracemalloc_traced_memory;
     }
-    else {
-        /* Hashtabled failed to add a new entry because of a memory allocation
-           failure. Same than above, the error cannot be reported to the
-           caller. */
-    }
     TABLES_UNLOCK();
+
+    return res;
 }
 
 static void
@@ -512,11 +507,16 @@
 #endif
 #endif
     ptr = alloc->malloc(alloc->ctx, size);
+
+    if (ptr != NULL) {
+        if (tracemalloc_log_alloc(ptr, size) < 0) {
+            /* Memory allocation failed */
+            alloc->free(alloc->ctx, ptr);
+            ptr = NULL;
+        }
+    }
     set_reentrant(0);
 
-    if (ptr != NULL)
-        tracemalloc_log_alloc(ptr, size);
-
 #if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD)
     if (!gil_held)
         PyGILState_Release(gil_state);
@@ -561,14 +561,25 @@
 #endif
 #endif
     ptr2 = alloc->realloc(alloc->ctx, ptr, new_size);
-    set_reentrant(0);
 
     if (ptr2 != NULL) {
         if (ptr != NULL)
             tracemalloc_log_free(ptr);
 
-        tracemalloc_log_alloc(ptr2, new_size);
+        if (tracemalloc_log_alloc(ptr2, new_size) < 0) {
+            if (ptr == NULL) {
+                /* Memory allocation failed */
+                alloc->free(alloc->ctx, ptr2);
+                ptr2 = NULL;
+            }
+            else {
+                /* Memory allocation failed. The error cannot be reported to
+                   the caller, because realloc() may already have shrinked the
+                   memory block and so removed bytes. */
+            }
+        }
     }
+    set_reentrant(0);
 
 #if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD)
     if (!gil_held)

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list