blob: 324d0fde000f072258830cb79deed54123de32ce [file] [log] [blame]
Jean-Paul Calderonefd593122013-03-03 10:21:53 -08001import sys
2sys.modules['ssl'] = None
3sys.modules['_hashlib'] = None
4
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -08005
6import traceback
7
8from cffi import api as _api
9_ffi = _api.FFI()
10_ffi.cdef(
11 """
12 void *malloc(size_t size);
13 void free(void *ptr);
14 void *realloc(void *ptr, size_t size);
15
16 int CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *));
17
18 int backtrace(void **buffer, int size);
19 char **backtrace_symbols(void *const *buffer, int size);
20 void backtrace_symbols_fd(void *const *buffer, int size, int fd);
21 """)
22_api = _ffi.verify(
23 """
24 #include <openssl/crypto.h>
25 #include <stdlib.h>
26 #include <execinfo.h>
27 """, libraries=["crypto"])
28C = _ffi.dlopen(None)
29
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080030verbose = False
31
32def log(s):
33 if verbose:
Jean-Paul Calderone558b78a2014-01-10 14:08:50 -050034 print(s)
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080035
36def _backtrace():
37 buf = _ffi.new("void*[]", 64)
38 result = _api.backtrace(buf, len(buf))
39 strings = _api.backtrace_symbols(buf, result)
40 stack = [_ffi.string(strings[i]) for i in range(result)]
41 C.free(strings)
42 return stack
43
44
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080045@_ffi.callback("void*(*)(size_t)")
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050046def malloc(n):
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080047 memory = C.malloc(n)
48 python_stack = traceback.extract_stack(limit=3)
49 c_stack = _backtrace()
Jean-Paul Calderonec2e8b412013-03-02 16:27:55 -080050 heap[memory] = [(n, python_stack, c_stack)]
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080051 log("malloc(%d) -> %s" % (n, memory))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080052 return memory
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080053
54
55@_ffi.callback("void*(*)(void*, size_t)")
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050056def realloc(p, n):
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080057 memory = C.realloc(p, n)
58 old = heap.pop(p)
59
60 python_stack = traceback.extract_stack(limit=3)
61 c_stack = _backtrace()
62
Jean-Paul Calderonec2e8b412013-03-02 16:27:55 -080063 old.append((n, python_stack, c_stack))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080064 heap[memory] = old
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080065 log("realloc(0x%x, %d) -> %s" % (int(_ffi.cast("int", p)), n, memory))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080066 return memory
67
68
69@_ffi.callback("void(*)(void*)")
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050070def free(p):
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080071 if p != _ffi.NULL:
72 C.free(p)
73 del heap[p]
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080074 log("free(0x%x)" % (int(_ffi.cast("int", p)),))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080075
76
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050077if _api.CRYPTO_set_mem_functions(malloc, realloc, free):
Jean-Paul Calderone558b78a2014-01-10 14:08:50 -050078 log('Enabled memory debugging')
Jean-Paul Calderone8e4a6632013-03-03 17:30:27 -080079 heap = {}
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080080else:
Jean-Paul Calderone558b78a2014-01-10 14:08:50 -050081 log('Failed to enable memory debugging')
Jean-Paul Calderone8e4a6632013-03-03 17:30:27 -080082 heap = None