Skip to content

Commit 1cf5c45

Browse files
committed
platform: make C++ allocation wrappers log the correct caller address
The C++ "operator new" and "operator delete" (and their array variants) were logging the the caller address wrong. In practice if one used "operator new", the logged caller address pointed to mbed_retarget.cpp, not to the client. Fix this by exposing the alloc wrappers to the the retarget. Note: this fixes only the ARMCC variants, as the GCC ones have different different API and implementation.
1 parent c832515 commit 1cf5c45

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

platform/mbed_alloc_wrappers.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,16 @@ extern "C" {
245245
void *SUPER_REALLOC(void *ptr, size_t size);
246246
void *SUPER_CALLOC(size_t nmemb, size_t size);
247247
void SUPER_FREE(void *ptr);
248+
void *malloc_wrapper(size_t size, void* caller);
249+
void free_wrapper(void *ptr, void* caller);
248250
}
249251

252+
250253
extern "C" void* SUB_MALLOC(size_t size) {
254+
return malloc_wrapper(size, MBED_CALLER_ADDR());
255+
}
256+
257+
extern "C" void* malloc_wrapper(size_t size, void* caller) {
251258
void *ptr = NULL;
252259
#ifdef MBED_MEM_TRACING_ENABLED
253260
mbed_mem_trace_lock();
@@ -272,12 +279,13 @@ extern "C" void* SUB_MALLOC(size_t size) {
272279
ptr = SUPER_MALLOC(size);
273280
#endif // #ifdef MBED_HEAP_STATS_ENABLED
274281
#ifdef MBED_MEM_TRACING_ENABLED
275-
mbed_mem_trace_malloc(ptr, size, MBED_CALLER_ADDR());
282+
mbed_mem_trace_malloc(ptr, size, caller);
276283
mbed_mem_trace_unlock();
277284
#endif // #ifdef MBED_MEM_TRACING_ENABLED
278285
return ptr;
279286
}
280287

288+
281289
extern "C" void* SUB_REALLOC(void *ptr, size_t size) {
282290
void *new_ptr = NULL;
283291
#ifdef MBED_MEM_TRACING_ENABLED
@@ -337,6 +345,10 @@ extern "C" void *SUB_CALLOC(size_t nmemb, size_t size) {
337345
}
338346

339347
extern "C" void SUB_FREE(void *ptr) {
348+
free_wrapper(ptr, MBED_CALLER_ADDR());
349+
}
350+
351+
extern "C" void free_wrapper(void *ptr, void* caller) {
340352
#ifdef MBED_MEM_TRACING_ENABLED
341353
mbed_mem_trace_lock();
342354
#endif
@@ -354,7 +366,7 @@ extern "C" void SUB_FREE(void *ptr) {
354366
SUPER_FREE(ptr);
355367
#endif // #ifdef MBED_HEAP_STATS_ENABLED
356368
#ifdef MBED_MEM_TRACING_ENABLED
357-
mbed_mem_trace_free(ptr, MBED_CALLER_ADDR());
369+
mbed_mem_trace_free(ptr, caller);
358370
mbed_mem_trace_unlock();
359371
#endif // #ifdef MBED_MEM_TRACING_ENABLED
360372
}

platform/mbed_retarget.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,53 @@ extern "C" void __cxa_guard_abort(int *guard_object_p)
10221022

10231023
#endif
10241024

1025+
#if defined(MBED_MEM_TRACING_ENABLED) && (defined(__CC_ARM) || defined(__ICCARM__))
1026+
1027+
// If the memory tracing is enabled, the wrappers in mbed_alloc_wrappers.cpp
1028+
// provide the implementation for these. Note: this needs to use the wrappers
1029+
// instead of malloc()/free() as the caller address would point to wrappers,
1030+
// not the caller of "new" or "delete".
1031+
extern "C" void* malloc_wrapper(size_t size, const void* caller);
1032+
extern "C" void free_wrapper(void *ptr, const void* caller);
1033+
1034+
void *operator new(std::size_t count)
1035+
{
1036+
void *buffer = malloc_wrapper(count, MBED_CALLER_ADDR());
1037+
if (NULL == buffer) {
1038+
error("Operator new out of memory\r\n");
1039+
}
1040+
return buffer;
1041+
}
1042+
1043+
void *operator new[](std::size_t count)
1044+
{
1045+
void *buffer = malloc_wrapper(count, MBED_CALLER_ADDR());
1046+
if (NULL == buffer) {
1047+
error("Operator new[] out of memory\r\n");
1048+
}
1049+
return buffer;
1050+
}
1051+
1052+
void *operator new(std::size_t count, const std::nothrow_t& tag)
1053+
{
1054+
return malloc_wrapper(count, MBED_CALLER_ADDR());
1055+
}
1056+
1057+
void *operator new[](std::size_t count, const std::nothrow_t& tag)
1058+
{
1059+
return malloc_wrapper(count, MBED_CALLER_ADDR());
1060+
}
1061+
1062+
void operator delete(void *ptr)
1063+
{
1064+
free_wrapper(ptr, MBED_CALLER_ADDR());
1065+
}
1066+
void operator delete[](void *ptr)
1067+
{
1068+
free_wrapper(ptr, MBED_CALLER_ADDR());
1069+
}
1070+
1071+
#else
10251072
void *operator new(std::size_t count)
10261073
{
10271074
void *buffer = malloc(count);
@@ -1059,6 +1106,8 @@ void operator delete[](void *ptr)
10591106
free(ptr);
10601107
}
10611108

1109+
#endif
1110+
10621111
/* @brief standard c library clock() function.
10631112
*
10641113
* This function returns the number of clock ticks elapsed since the start of the program.

0 commit comments

Comments
 (0)