diff options
author | Hynek Schlawack <hs@ox.cx> | 2015-10-16 20:18:38 +0200 |
---|---|---|
committer | Hynek Schlawack <hs@ox.cx> | 2015-10-17 11:27:56 +0200 |
commit | f0e6685b0880bbc30099c998454925ee8d39b14e (patch) | |
tree | ef387dada69f8fe9830fa1c9d9d289760fbbe5c1 /tests/memdbg.py | |
parent | 510a04eb7cb97fda2062c0c8b51724db2edbd855 (diff) | |
download | pyopenssl-git-f0e6685b0880bbc30099c998454925ee8d39b14e.tar.gz |
Move package into src
Prevents accidental imports when running tests.
Diffstat (limited to 'tests/memdbg.py')
-rw-r--r-- | tests/memdbg.py | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/tests/memdbg.py b/tests/memdbg.py new file mode 100644 index 0000000..324d0fd --- /dev/null +++ b/tests/memdbg.py @@ -0,0 +1,82 @@ +import sys +sys.modules['ssl'] = None +sys.modules['_hashlib'] = None + + +import traceback + +from cffi import api as _api +_ffi = _api.FFI() +_ffi.cdef( + """ + void *malloc(size_t size); + void free(void *ptr); + void *realloc(void *ptr, size_t size); + + int CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *)); + + int backtrace(void **buffer, int size); + char **backtrace_symbols(void *const *buffer, int size); + void backtrace_symbols_fd(void *const *buffer, int size, int fd); + """) +_api = _ffi.verify( + """ + #include <openssl/crypto.h> + #include <stdlib.h> + #include <execinfo.h> + """, libraries=["crypto"]) +C = _ffi.dlopen(None) + +verbose = False + +def log(s): + if verbose: + print(s) + +def _backtrace(): + buf = _ffi.new("void*[]", 64) + result = _api.backtrace(buf, len(buf)) + strings = _api.backtrace_symbols(buf, result) + stack = [_ffi.string(strings[i]) for i in range(result)] + C.free(strings) + return stack + + +@_ffi.callback("void*(*)(size_t)") +def malloc(n): + memory = C.malloc(n) + python_stack = traceback.extract_stack(limit=3) + c_stack = _backtrace() + heap[memory] = [(n, python_stack, c_stack)] + log("malloc(%d) -> %s" % (n, memory)) + return memory + + +@_ffi.callback("void*(*)(void*, size_t)") +def realloc(p, n): + memory = C.realloc(p, n) + old = heap.pop(p) + + python_stack = traceback.extract_stack(limit=3) + c_stack = _backtrace() + + old.append((n, python_stack, c_stack)) + heap[memory] = old + log("realloc(0x%x, %d) -> %s" % (int(_ffi.cast("int", p)), n, memory)) + return memory + + +@_ffi.callback("void(*)(void*)") +def free(p): + if p != _ffi.NULL: + C.free(p) + del heap[p] + log("free(0x%x)" % (int(_ffi.cast("int", p)),)) + + +if _api.CRYPTO_set_mem_functions(malloc, realloc, free): + log('Enabled memory debugging') + heap = {} +else: + log('Failed to enable memory debugging') + heap = None |