@@ -27,12 +27,44 @@ extern int printf(const char *, ...);
2727
2828extern 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
3449const 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,8 @@ const char ua_chars[] = "NFEWIL";
5284 #define caller_addr () (NULL)
5385#endif
5486
55- void * mbed_ualloc (size_t bytes , UAllocTraits_t traits )
56- {
87+ static void * mbed_ualloc_internal (size_t bytes , UAllocTraits_t traits , void * caller ) {
5788 void * ptr = NULL ;
58- void * caller = (void * ) caller_addr ();
5989 if (UALLOC_TEST_TRAITS (traits .flags , UALLOC_TRAITS_NEVER_FREE )) {
6090 ptr = mbed_krbs (bytes );
6191 // krbs uses the same semantics as sbrk, so translate a -1 to NULL.
@@ -76,47 +106,75 @@ void * mbed_ualloc(size_t bytes, UAllocTraits_t traits)
76106
77107 if (ptr == NULL ) {
78108 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 );
81109 }
110+
82111 return ptr ;
83112}
84- void * mbed_urealloc (void * ptr , size_t bytes , UAllocTraits_t traits )
85- {
86- void * caller = (void * ) caller_addr ();
113+
114+ void * mbed_ualloc (size_t bytes , UAllocTraits_t traits ) {
115+ void * caller = (void * )caller_addr ();
116+ void * p = mbed_ualloc_internal (bytes , traits , caller );
117+ if (!prevent_tracing ) {
118+ prevent_tracing = 1 ;
119+ ualloc_debug (UALLOC_DEBUG_LOG , "ua c:%p s:%u m:%p\n" , caller , (unsigned )bytes , p );
120+ prevent_tracing = 0 ;
121+ }
122+ return p ;
123+ }
124+
125+ static void * mbed_urealloc_internal (void * ptr , size_t bytes , UAllocTraits_t traits , void * caller ) {
87126 void * newptr = NULL ;
88127 if (ptr == NULL ) {
89128 return mbed_ualloc (bytes , traits );
90129 }
91130 if (traits .flags & ~UALLOC_TRAITS_BITMASK ) {
92131 // Traits not supported in urealloc yet
93- ualloc_debug (UALLOC_DEBUG_WARNING , "ua c:%p fail\n" , caller );
132+ ualloc_debug (UALLOC_DEBUG_ERROR , "ua c:%p fail\n" , caller );
94133 return NULL ;
95134 }
96135 uintptr_t ptr_tmp = (uintptr_t ) ptr ;
97136 if ((ptr_tmp < (uintptr_t ) mbed_sbrk_ptr ) &&
98137 (ptr_tmp >= (uintptr_t )& __mbed_sbrk_start )) {
99138 newptr = dlrealloc (ptr , bytes );
100139 } else {
101- ualloc_debug (UALLOC_DEBUG_LOG , "uf c:%p m:%p non-heap realloc\n" , caller , ptr );
140+ ualloc_debug (UALLOC_DEBUG_ERROR , "uf c:%p m:%p non-heap realloc\n" , caller , ptr );
102141 }
103142
104143 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 );
144+ ualloc_debug (UALLOC_DEBUG_WARNING , "ur c:%p p:%p fail\n" , caller , ptr );
108145 }
109146 return newptr ;
110147}
111- void mbed_ufree (void * ptr )
148+
149+ void * mbed_urealloc (void * ptr , size_t bytes , UAllocTraits_t traits ) {
150+ void * caller = (void * )caller_addr ();
151+ void * p = mbed_urealloc_internal (ptr , bytes , traits , caller );
152+ if (!prevent_tracing ) {
153+ prevent_tracing = 1 ;
154+ ualloc_debug (UALLOC_DEBUG_LOG , "ua c:%p s:%u p:%p m:%p\n" , caller , (unsigned )bytes , ptr , p );
155+ prevent_tracing = 0 ;
156+ }
157+ return p ;
158+ }
159+
160+ static void mbed_ufree_internal (void * ptr , void * caller )
112161{
113- void * caller = (void * ) caller_addr ();
114- ualloc_debug (UALLOC_DEBUG_LOG , "uf c:%p m:%p\n" , caller , ptr );
115162 uintptr_t ptr_tmp = (uintptr_t ) ptr ;
116163 if ((ptr_tmp < (uintptr_t ) mbed_sbrk_ptr ) &&
117164 (ptr_tmp >= (uintptr_t )& __mbed_sbrk_start )) {
118165 dlfree (ptr );
119166 } else {
120- ualloc_debug (UALLOC_DEBUG_LOG , "uf c:%p m:%p non-heap free\n" , caller , ptr );
167+ ualloc_debug (UALLOC_DEBUG_WARNING , "uf c:%p m:%p non-heap free\n" , caller , ptr );
168+ }
169+ }
170+
171+ void mbed_ufree (void * ptr ) {
172+ void * caller = (void * )caller_addr ();
173+ mbed_ufree_internal (ptr , caller );
174+ if (!prevent_tracing ) {
175+ prevent_tracing = 1 ;
176+ ualloc_debug (UALLOC_DEBUG_LOG , "uf c:%p m:%p\n" , caller , ptr );
177+ prevent_tracing = 0 ;
121178 }
122179}
180+
0 commit comments