From c9c53ea985565d7d78f23519b9c5db630ac76d3d Mon Sep 17 00:00:00 2001 From: Julian Taylor Date: Sat, 5 Jul 2014 23:09:12 +0200 Subject: [PATCH] BUG: disable garbage collector during memory allocation hook When a cython object contains numpy arrays the pure python allocation hook can trigger during cythons __dealloc__ method and trigger a second deletion of the object currently being deleted. To minimize the probabily that that happens disable the garbage collector during the hook. As this involves python calls it is still possible that a double delete occurs but chances are lowered, a proper solution would be C only hook like python 3.4 tracemalloc module. Closes gh-4834 --- tools/allocation_tracking/track_allocations.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/allocation_tracking/track_allocations.py b/tools/allocation_tracking/track_allocations.py index 2006217c2d61..dfc354eb5dbf 100644 --- a/tools/allocation_tracking/track_allocations.py +++ b/tools/allocation_tracking/track_allocations.py @@ -1,6 +1,7 @@ from __future__ import division, absolute_import, print_function import numpy as np +import gc import inspect from alloc_hook import NumpyAllocHook @@ -35,12 +36,21 @@ def __exit__(self, type, value, traceback): self.numpy_hook.__exit__() def hook(self, inptr, outptr, size): + # minimize the chances that the garbage collector kicks in during a + # cython __dealloc__ call and causes a double delete of the current + # object. To avoid this fully the hook would have to avoid all python + # api calls, e.g. by being implemented in C like python 3.4's + # tracemalloc module + gc_on = gc.isenabled() + gc.disable() if outptr == 0: # it's a free self.free_cb(inptr) elif inptr != 0: # realloc self.realloc_cb(inptr, outptr, size) else: # malloc self.alloc_cb(outptr, size) + if gc_on: + gc.enable() def alloc_cb(self, ptr, size): if size >= self.threshold: