blob: e9273324e182fa0950c8471716f342c9da3035ae [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
8assert sys.modules.get('ssl') is None
9assert sys.modules.get('_hashlib') is None
10sys.modules['ssl'] = None
11sys.modules['_hashlib'] = None
12
13
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080014_ffi = _api.FFI()
15_ffi.cdef(
16 """
17 void *malloc(size_t size);
18 void free(void *ptr);
19 void *realloc(void *ptr, size_t size);
20
21 int CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *));
22
23 int backtrace(void **buffer, int size);
24 char **backtrace_symbols(void *const *buffer, int size);
25 void backtrace_symbols_fd(void *const *buffer, int size, int fd);
Hynek Schlawack7b3aa902015-10-16 21:06:20 +020026 """) # noqa
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080027_api = _ffi.verify(
28 """
29 #include <openssl/crypto.h>
30 #include <stdlib.h>
31 #include <execinfo.h>
32 """, libraries=["crypto"])
33C = _ffi.dlopen(None)
34
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080035verbose = False
36
Hynek Schlawack7b3aa902015-10-16 21:06:20 +020037
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080038def log(s):
39 if verbose:
Jean-Paul Calderone558b78a2014-01-10 14:08:50 -050040 print(s)
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080041
Hynek Schlawack7b3aa902015-10-16 21:06:20 +020042
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080043def _backtrace():
44 buf = _ffi.new("void*[]", 64)
45 result = _api.backtrace(buf, len(buf))
46 strings = _api.backtrace_symbols(buf, result)
47 stack = [_ffi.string(strings[i]) for i in range(result)]
48 C.free(strings)
49 return stack
50
51
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080052@_ffi.callback("void*(*)(size_t)")
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050053def malloc(n):
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080054 memory = C.malloc(n)
55 python_stack = traceback.extract_stack(limit=3)
56 c_stack = _backtrace()
Jean-Paul Calderonec2e8b412013-03-02 16:27:55 -080057 heap[memory] = [(n, python_stack, c_stack)]
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080058 log("malloc(%d) -> %s" % (n, memory))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080059 return memory
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080060
61
62@_ffi.callback("void*(*)(void*, size_t)")
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050063def realloc(p, n):
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080064 memory = C.realloc(p, n)
65 old = heap.pop(p)
66
67 python_stack = traceback.extract_stack(limit=3)
68 c_stack = _backtrace()
69
Jean-Paul Calderonec2e8b412013-03-02 16:27:55 -080070 old.append((n, python_stack, c_stack))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080071 heap[memory] = old
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080072 log("realloc(0x%x, %d) -> %s" % (int(_ffi.cast("int", p)), n, memory))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080073 return memory
74
75
76@_ffi.callback("void(*)(void*)")
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050077def free(p):
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080078 if p != _ffi.NULL:
79 C.free(p)
80 del heap[p]
Jean-Paul Calderonefd593122013-03-03 10:21:53 -080081 log("free(0x%x)" % (int(_ffi.cast("int", p)),))
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080082
83
Jean-Paul Calderoneede8b712014-01-01 12:36:46 -050084if _api.CRYPTO_set_mem_functions(malloc, realloc, free):
Jean-Paul Calderone558b78a2014-01-10 14:08:50 -050085 log('Enabled memory debugging')
Jean-Paul Calderone8e4a6632013-03-03 17:30:27 -080086 heap = {}
Jean-Paul Calderone68a6f8f2013-03-01 17:56:22 -080087else:
Jean-Paul Calderone558b78a2014-01-10 14:08:50 -050088 log('Failed to enable memory debugging')
Jean-Paul Calderone8e4a6632013-03-03 17:30:27 -080089 heap = None