Skip to content
This repository was archived by the owner on Jan 15, 2021. It is now read-only.

Commit 9021555

Browse files
committed
Merge pull request #22 from ARMmbed/tracing
Enable memory tracing
2 parents 5bfe6c8 + abcb0fe commit 9021555

File tree

1 file changed

+80
-17
lines changed

1 file changed

+80
-17
lines changed

source/ualloc.c

Lines changed: 80 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,44 @@ extern int printf(const char *, ...);
2727

2828
extern void * volatile mbed_sbrk_ptr;
2929

30-
// Set debug level to 0 until non-allocating printf is available
31-
const UAllocDebug_t ualloc_debug_level = UALLOC_DEBUG_NONE;//(DEBUG?UALLOC_DEBUG_MAX:UALLOC_DEBUG_NONE);
30+
/*****************************************************************************************
31+
UALLOC_DEBUG_LOG is effectively reserved for tracing memory allocations
32+
Tracing must be enabled via "yotta config":
33+
{
34+
"debug": {
35+
"options": {
36+
"memory-trace": true
37+
}
38+
}
39+
}
40+
[TODO]: ualloc_debug_level probably needs better control with "yotta config"
41+
*****************************************************************************************/
42+
#ifdef YOTTA_CFG_DEBUG_OPTIONS_MEMORY_TRACE
43+
const UAllocDebug_t ualloc_debug_level = UALLOC_DEBUG_LOG;
44+
#else
45+
const UAllocDebug_t ualloc_debug_level = UALLOC_DEBUG_NONE;
46+
#endif
3247

3348
// Debug characters
3449
const char ua_chars[] = "NFEWIL";
3550

51+
/*****************************************************************************************
52+
The purpose of "prevent_tracing" below is twofold:
53+
54+
1. prevent infinite loops (mbed_ualloc_internal -> ualloc_debug -> printf ->
55+
mbed_ualloc_internal -> ualloc_debug -> printf...)
56+
2. prevent a possible scenario when an interrupt occurs while ualloc_debug
57+
is printing debug information and the interrupt also calls 'mbed_ualloc' or
58+
another memory operation that would result in ualloc_debug being called,
59+
which would in turn result in garbled output. By using "prevent_tracing",
60+
the output is kept consistent, but the memory operation invoked in the
61+
interrupt handler is not logged.
62+
63+
1 above can be prevented by using a logging function that doesn't allocate memory.
64+
2 above can be prevented by queueing log messages instead of logging them immediately.
65+
*****************************************************************************************/
66+
static volatile int prevent_tracing = 0;
67+
3668
#define ualloc_debug(ADBG_LEVEL, fmt, ...) do { \
3769
if (ADBG_LEVEL <= ualloc_debug_level && ADBG_LEVEL < UALLOC_DEBUG_MAX) { \
3870
printf("UAL:%c " fmt, ua_chars[ADBG_LEVEL], __VA_ARGS__); \
@@ -52,10 +84,9 @@ const char ua_chars[] = "NFEWIL";
5284
#define caller_addr() (NULL)
5385
#endif
5486

55-
void * mbed_ualloc(size_t bytes, UAllocTraits_t traits)
87+
static void * mbed_ualloc_internal(size_t bytes, UAllocTraits_t traits, void *caller)
5688
{
5789
void * ptr = NULL;
58-
void * caller = (void*) caller_addr();
5990
if (UALLOC_TEST_TRAITS(traits.flags, UALLOC_TRAITS_NEVER_FREE)) {
6091
ptr = mbed_krbs(bytes);
6192
// krbs uses the same semantics as sbrk, so translate a -1 to NULL.
@@ -76,47 +107,79 @@ void * mbed_ualloc(size_t bytes, UAllocTraits_t traits)
76107

77108
if(ptr == NULL) {
78109
ualloc_debug(UALLOC_DEBUG_WARNING, "ua c:%p fail\n", caller);
79-
} else {
80-
ualloc_debug(UALLOC_DEBUG_LOG, "ua c:%p m:%p\n", caller, ptr);
81110
}
111+
82112
return ptr;
83113
}
84-
void * mbed_urealloc(void * ptr, size_t bytes, UAllocTraits_t traits)
114+
115+
void *mbed_ualloc(size_t bytes, UAllocTraits_t traits)
116+
{
117+
void *caller = (void*)caller_addr();
118+
void *p = mbed_ualloc_internal(bytes, traits, caller);
119+
if (!prevent_tracing) {
120+
prevent_tracing = 1;
121+
ualloc_debug(UALLOC_DEBUG_LOG, "ua c:%p s:%u m:%p\n", caller, (unsigned)bytes, p);
122+
prevent_tracing = 0;
123+
}
124+
return p;
125+
}
126+
127+
static void * mbed_urealloc_internal(void * ptr, size_t bytes, UAllocTraits_t traits, void *caller)
85128
{
86-
void * caller = (void*) caller_addr();
87129
void *newptr = NULL;
88130
if (ptr == NULL) {
89131
return mbed_ualloc(bytes, traits);
90132
}
91133
if(traits.flags & ~UALLOC_TRAITS_BITMASK) {
92134
// Traits not supported in urealloc yet
93-
ualloc_debug(UALLOC_DEBUG_WARNING, "ua c:%p fail\n", caller);
135+
ualloc_debug(UALLOC_DEBUG_ERROR, "ur c:%p fail\n", caller);
94136
return NULL;
95137
}
96138
uintptr_t ptr_tmp = (uintptr_t) ptr;
97139
if ((ptr_tmp < (uintptr_t) mbed_sbrk_ptr) &&
98140
(ptr_tmp >= (uintptr_t)&__mbed_sbrk_start)) {
99141
newptr = dlrealloc(ptr, bytes);
100142
} else {
101-
ualloc_debug(UALLOC_DEBUG_LOG, "uf c:%p m:%p non-heap realloc\n", caller, ptr);
143+
ualloc_debug(UALLOC_DEBUG_ERROR, "ur c:%p m:%p non-heap realloc\n", caller, ptr);
102144
}
103145

104146
if(newptr == NULL) {
105-
ualloc_debug(UALLOC_DEBUG_WARNING, "ur c:%p m0:%p fail\n", caller, ptr);
106-
} else {
107-
ualloc_debug(UALLOC_DEBUG_LOG, "ur c:%p m0:%p m1:%p\n", caller, ptr, newptr);
147+
ualloc_debug(UALLOC_DEBUG_WARNING, "ur c:%p p:%p fail\n", caller, ptr);
108148
}
109149
return newptr;
110150
}
111-
void mbed_ufree(void * ptr)
151+
152+
void * mbed_urealloc(void * ptr, size_t bytes, UAllocTraits_t traits)
153+
{
154+
void *caller = (void*)caller_addr();
155+
void *p = mbed_urealloc_internal(ptr, bytes, traits, caller);
156+
if (!prevent_tracing) {
157+
prevent_tracing = 1;
158+
ualloc_debug(UALLOC_DEBUG_LOG, "ur c:%p s:%u p:%p m:%p\n", caller, (unsigned)bytes, ptr, p);
159+
prevent_tracing = 0;
160+
}
161+
return p;
162+
}
163+
164+
static void mbed_ufree_internal(void * ptr, void *caller)
112165
{
113-
void * caller = (void*) caller_addr();
114-
ualloc_debug(UALLOC_DEBUG_LOG, "uf c:%p m:%p\n", caller, ptr);
115166
uintptr_t ptr_tmp = (uintptr_t) ptr;
116167
if ((ptr_tmp < (uintptr_t) mbed_sbrk_ptr) &&
117168
(ptr_tmp >= (uintptr_t)&__mbed_sbrk_start)) {
118169
dlfree(ptr);
119170
} else {
120-
ualloc_debug(UALLOC_DEBUG_LOG, "uf c:%p m:%p non-heap free\n", caller, ptr);
171+
ualloc_debug(UALLOC_DEBUG_WARNING, "uf c:%p m:%p non-heap free\n", caller, ptr);
121172
}
122173
}
174+
175+
void mbed_ufree(void *ptr)
176+
{
177+
void *caller = (void*)caller_addr();
178+
mbed_ufree_internal(ptr, caller);
179+
if (!prevent_tracing) {
180+
prevent_tracing = 1;
181+
ualloc_debug(UALLOC_DEBUG_LOG, "uf c:%p m:%p\n", caller, ptr);
182+
prevent_tracing = 0;
183+
}
184+
}
185+

0 commit comments

Comments
 (0)