diff options
author | Julian Taylor <jtaylor.debian@googlemail.com> | 2014-07-05 23:09:12 +0200 |
---|---|---|
committer | Julian Taylor <jtaylor.debian@googlemail.com> | 2014-07-05 23:13:30 +0200 |
commit | c9c53ea985565d7d78f23519b9c5db630ac76d3d (patch) | |
tree | cd87185bf17c08fcae036c1a42ffda56be1842ff /tools | |
parent | 7a2b14ae0adb762a3eb8991595b14f74f004f435 (diff) | |
download | numpy-c9c53ea985565d7d78f23519b9c5db630ac76d3d.tar.gz |
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
Diffstat (limited to 'tools')
-rw-r--r-- | tools/allocation_tracking/track_allocations.py | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/tools/allocation_tracking/track_allocations.py b/tools/allocation_tracking/track_allocations.py index 2006217c2..dfc354eb5 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 @@ class AllocationTracker(object): 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: |