1#if !defined (__EMSCRIPTEN__) && !defined (__MACH__)
8#define MIN_SIZE_TRACED 64
11extern void *stacktrace[MAX_STRACE];
13void call_unwind(
void);
29struct trace *all_traces =
nullptr;
31unsigned hash_trace(
unsigned len,
unsigned *buf)
34 for (
unsigned i = 0; i <
len; ++i)
39 return ret & 0xFFFFFF;
42struct trace *find_current_trace(
unsigned hash)
44 for (
struct trace *t = all_traces; t; t = t->
next)
46 if (t->hash != (
hash & 0xFFFFFF))
48 if (t->len != strace_len)
50 unsigned *payload = (
unsigned *)(t + 1);
51 if (memcmp(payload, stacktrace, strace_len *
sizeof(stacktrace[0])) !=
60extern void *__wrap_malloc(
size_t size);
61extern void *__real_malloc(
size_t size);
67 unsigned total_size =
sizeof(
struct trace) + strace_len *
sizeof(stacktrace[0]);
68#if defined(TARGET_LPC2368) || defined(TARGET_LPC1768)
73 memcpy(t + 1, stacktrace, strace_len *
sizeof(stacktrace[0]));
86void *stacktrace[MAX_STRACE];
89_Unwind_Reason_Code trace_func(
struct _Unwind_Context *context,
void *arg)
91 void *ip = (
void *)_Unwind_GetIP(context);
92 if (strace_len > 0 && stacktrace[strace_len - 1] == ip)
94 return _URC_END_OF_STACK;
96 if (strace_len >= MAX_STRACE)
98 return _URC_END_OF_STACK;
100 stacktrace[strace_len++] = ip;
101 return _URC_NO_REASON;
104void *__wrap_malloc(
size_t size)
106 if (size < MIN_SIZE_TRACED) {
107 return __real_malloc(size);
109 uintptr_t saved_lr = 0;
110#if defined(TARGET_LPC2368) || defined(TARGET_LPC1768) || defined(GCC_ARMCM3)
111 asm volatile (
"mov %0, lr \n" :
"=r" (saved_lr));
116 _Unwind_Backtrace(&trace_func, 0);
117 if (strace_len == 1) {
118 stacktrace[strace_len++] = (
void*)saved_lr;
120 unsigned h = hash_trace(strace_len, (
unsigned *)stacktrace);
121 struct trace *t = find_current_trace(h);
124 t = add_new_trace(h);
128 return __real_malloc(size);
See OSMutexLock in os/OS.hxx.
Lightweight locking class for protecting small critical sections.
void * usb_malloc(unsigned long length)
Custom malloc function for USB space.
Linked list entry type for a call-stack backtrace.
unsigned hash
For quick comparison of traces.
unsigned total_size
total memory (bytes) allocated via this trace.
unsigned len
Number of entries in the trace.
struct trace * next
Link to the next trace entry.