blob: 6e608a75263dcc6c3cd27ce52cf16dd150f6f971 [file] [log] [blame]
Jean-Paul Calderonefd593122013-03-03 10:21:53 -08001import sys
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -08002
3import traceback
4
5from cffi import api as _api
Alex Gaynorc3fac9d2016-01-16 12:15:09 -05006
7
Alex Gaynorc3fac9d2016-01-16 12:15:09 -05008sys.modules['ssl'] = None
9sys.modules['_hashlib'] = None
10
11
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080012_ffi = _api.FFI()
13_ffi.cdef(
14 """
15 void *malloc(size_t size);
16 void free(void *ptr);
17 void *realloc(void *ptr, size_t size);
18
19 int CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *));
20
21 int backtrace(void **buffer, int size);
22 char **backtrace_symbols(void *const *buffer, int size);
23 void backtrace_symbols_fd(void *const *buffer, int size, int fd);
Hynek Schlawack7b3aa902015-10-16 21:06:20 +020024 """) # noqa
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080025_api = _ffi.verify(
26 """
27 #include <openssl/crypto.h>
28 #include <stdlib.h>
29 #include <execinfo.h>
30 """, libraries=["crypto"])
31C = _ffi.dlopen(None)
32
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080033verbose = False
34
Hynek Schlawack7b3aa902015-10-16 21:06:20 +020035
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080036def log(s):
37 if verbose:
Jean-Paul Calderone558b78a2014-01-10 14:08:50 -050038 print(s)
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080039
Hynek Schlawack7b3aa902015-10-16 21:06:20 +020040
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080041def _backtrace():
42 buf = _ffi.new("void*[]", 64)
43 result = _api.backtrace(buf, len(buf))
44 strings = _api.backtrace_symbols(buf, result)
45 stack = [_ffi.string(strings[i]) for i in range(result)]
46 C.free(strings)
47 return stack
48
49
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080050@_ffi.callback("void*(*)(size_t)")
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050051def malloc(n):
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080052 memory = C.malloc(n)
53 python_stack = traceback.extract_stack(limit=3)
54 c_stack = _backtrace()
Jean-Paul Calderonec2e8b412013-03-02 16:27:55 -080055 heap[memory] = [(n, python_stack, c_stack)]
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080056 log("malloc(%d) -> %s" % (n, memory))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080057 return memory
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080058
59
60@_ffi.callback("void*(*)(void*, size_t)")
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050061def realloc(p, n):
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080062 memory = C.realloc(p, n)
63 old = heap.pop(p)
64
65 python_stack = traceback.extract_stack(limit=3)
66 c_stack = _backtrace()
67
Jean-Paul Calderonec2e8b412013-03-02 16:27:55 -080068 old.append((n, python_stack, c_stack))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080069 heap[memory] = old
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080070 log("realloc(0x%x, %d) -> %s" % (int(_ffi.cast("int", p)), n, memory))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080071 return memory
72
73
74@_ffi.callback("void(*)(void*)")
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050075def free(p):
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080076 if p != _ffi.NULL:
77 C.free(p)
78 del heap[p]
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080079 log("free(0x%x)" % (int(_ffi.cast("int", p)),))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080080
81
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050082if _api.CRYPTO_set_mem_functions(malloc, realloc, free):
Jean-Paul Calderone558b78a2014-01-10 14:08:50 -050083 log('Enabled memory debugging')
Jean-Paul Calderone8e4a6632013-03-03 17:30:27 -080084 heap = {}
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080085else:
Jean-Paul Calderone558b78a2014-01-10 14:08:50 -050086 log('Failed to enable memory debugging')
Jean-Paul Calderone8e4a6632013-03-03 17:30:27 -080087 heap = None