Skip to content

Commit 280d491

Browse files
authored
Merge pull request #5456 from TeroJaasko/fix_cpp_alloc_wrappers
platform: make C++ allocation wrappers log the correct caller address
2 parents 663a6d8 + b81be1e commit 280d491

File tree

2 files changed

+121
-4
lines changed

2 files changed

+121
-4
lines changed

platform/mbed_alloc_wrappers.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,18 @@ extern "C" {
8181
void * __real__realloc_r(struct _reent * r, void * ptr, size_t size);
8282
void __real__free_r(struct _reent * r, void * ptr);
8383
void* __real__calloc_r(struct _reent * r, size_t nmemb, size_t size);
84+
void* malloc_wrapper(struct _reent * r, size_t size, void * caller);
85+
void free_wrapper(struct _reent * r, void * ptr, void* caller);
8486
}
8587

8688
// TODO: memory tracing doesn't work with uVisor enabled.
8789
#if !defined(FEATURE_UVISOR)
8890

8991
extern "C" void * __wrap__malloc_r(struct _reent * r, size_t size) {
92+
return malloc_wrapper(r, size, MBED_CALLER_ADDR());
93+
}
94+
95+
extern "C" void * malloc_wrapper(struct _reent * r, size_t size, void * caller) {
9096
void *ptr = NULL;
9197
#ifdef MBED_MEM_TRACING_ENABLED
9298
mbed_mem_trace_lock();
@@ -111,7 +117,7 @@ extern "C" void * __wrap__malloc_r(struct _reent * r, size_t size) {
111117
ptr = __real__malloc_r(r, size);
112118
#endif // #ifdef MBED_HEAP_STATS_ENABLED
113119
#ifdef MBED_MEM_TRACING_ENABLED
114-
mbed_mem_trace_malloc(ptr, size, MBED_CALLER_ADDR());
120+
mbed_mem_trace_malloc(ptr, size, caller);
115121
mbed_mem_trace_unlock();
116122
#endif // #ifdef MBED_MEM_TRACING_ENABLED
117123
return ptr;
@@ -160,6 +166,10 @@ extern "C" void * __wrap__realloc_r(struct _reent * r, void * ptr, size_t size)
160166
}
161167

162168
extern "C" void __wrap__free_r(struct _reent * r, void * ptr) {
169+
free_wrapper(r, ptr, MBED_CALLER_ADDR());
170+
}
171+
172+
extern "C" void free_wrapper(struct _reent * r, void * ptr, void * caller) {
163173
#ifdef MBED_MEM_TRACING_ENABLED
164174
mbed_mem_trace_lock();
165175
#endif
@@ -177,7 +187,7 @@ extern "C" void __wrap__free_r(struct _reent * r, void * ptr) {
177187
__real__free_r(r, ptr);
178188
#endif // #ifdef MBED_HEAP_STATS_ENABLED
179189
#ifdef MBED_MEM_TRACING_ENABLED
180-
mbed_mem_trace_free(ptr, MBED_CALLER_ADDR());
190+
mbed_mem_trace_free(ptr, caller);
181191
mbed_mem_trace_unlock();
182192
#endif // #ifdef MBED_MEM_TRACING_ENABLED
183193
}
@@ -245,9 +255,16 @@ extern "C" {
245255
void *SUPER_REALLOC(void *ptr, size_t size);
246256
void *SUPER_CALLOC(size_t nmemb, size_t size);
247257
void SUPER_FREE(void *ptr);
258+
void *malloc_wrapper(size_t size, void* caller);
259+
void free_wrapper(void *ptr, void* caller);
248260
}
249261

262+
250263
extern "C" void* SUB_MALLOC(size_t size) {
264+
return malloc_wrapper(size, MBED_CALLER_ADDR());
265+
}
266+
267+
extern "C" void* malloc_wrapper(size_t size, void* caller) {
251268
void *ptr = NULL;
252269
#ifdef MBED_MEM_TRACING_ENABLED
253270
mbed_mem_trace_lock();
@@ -272,12 +289,13 @@ extern "C" void* SUB_MALLOC(size_t size) {
272289
ptr = SUPER_MALLOC(size);
273290
#endif // #ifdef MBED_HEAP_STATS_ENABLED
274291
#ifdef MBED_MEM_TRACING_ENABLED
275-
mbed_mem_trace_malloc(ptr, size, MBED_CALLER_ADDR());
292+
mbed_mem_trace_malloc(ptr, size, caller);
276293
mbed_mem_trace_unlock();
277294
#endif // #ifdef MBED_MEM_TRACING_ENABLED
278295
return ptr;
279296
}
280297

298+
281299
extern "C" void* SUB_REALLOC(void *ptr, size_t size) {
282300
void *new_ptr = NULL;
283301
#ifdef MBED_MEM_TRACING_ENABLED
@@ -337,6 +355,10 @@ extern "C" void *SUB_CALLOC(size_t nmemb, size_t size) {
337355
}
338356

339357
extern "C" void SUB_FREE(void *ptr) {
358+
free_wrapper(ptr, MBED_CALLER_ADDR());
359+
}
360+
361+
extern "C" void free_wrapper(void *ptr, void* caller) {
340362
#ifdef MBED_MEM_TRACING_ENABLED
341363
mbed_mem_trace_lock();
342364
#endif
@@ -354,7 +376,7 @@ extern "C" void SUB_FREE(void *ptr) {
354376
SUPER_FREE(ptr);
355377
#endif // #ifdef MBED_HEAP_STATS_ENABLED
356378
#ifdef MBED_MEM_TRACING_ENABLED
357-
mbed_mem_trace_free(ptr, MBED_CALLER_ADDR());
379+
mbed_mem_trace_free(ptr, caller);
358380
mbed_mem_trace_unlock();
359381
#endif // #ifdef MBED_MEM_TRACING_ENABLED
360382
}

platform/mbed_retarget.cpp

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,99 @@ extern "C" void __cxa_guard_abort(int *guard_object_p)
10391039

10401040
#endif
10411041

1042+
#if defined(MBED_MEM_TRACING_ENABLED) && (defined(__CC_ARM) || defined(__ICCARM__))
1043+
1044+
// If the memory tracing is enabled, the wrappers in mbed_alloc_wrappers.cpp
1045+
// provide the implementation for these. Note: this needs to use the wrappers
1046+
// instead of malloc()/free() as the caller address would point to wrappers,
1047+
// not the caller of "new" or "delete".
1048+
extern "C" void* malloc_wrapper(size_t size, const void* caller);
1049+
extern "C" void free_wrapper(void *ptr, const void* caller);
1050+
1051+
void *operator new(std::size_t count)
1052+
{
1053+
void *buffer = malloc_wrapper(count, MBED_CALLER_ADDR());
1054+
if (NULL == buffer) {
1055+
error("Operator new out of memory\r\n");
1056+
}
1057+
return buffer;
1058+
}
1059+
1060+
void *operator new[](std::size_t count)
1061+
{
1062+
void *buffer = malloc_wrapper(count, MBED_CALLER_ADDR());
1063+
if (NULL == buffer) {
1064+
error("Operator new[] out of memory\r\n");
1065+
}
1066+
return buffer;
1067+
}
1068+
1069+
void *operator new(std::size_t count, const std::nothrow_t& tag)
1070+
{
1071+
return malloc_wrapper(count, MBED_CALLER_ADDR());
1072+
}
1073+
1074+
void *operator new[](std::size_t count, const std::nothrow_t& tag)
1075+
{
1076+
return malloc_wrapper(count, MBED_CALLER_ADDR());
1077+
}
1078+
1079+
void operator delete(void *ptr)
1080+
{
1081+
free_wrapper(ptr, MBED_CALLER_ADDR());
1082+
}
1083+
void operator delete[](void *ptr)
1084+
{
1085+
free_wrapper(ptr, MBED_CALLER_ADDR());
1086+
}
1087+
1088+
#elif defined(MBED_MEM_TRACING_ENABLED) && defined(__GNUC__)
1089+
1090+
#include <reent.h>
1091+
1092+
extern "C" void* malloc_wrapper(struct _reent * r, size_t size, void * caller);
1093+
extern "C" void free_wrapper(struct _reent * r, void * ptr, void * caller);
1094+
1095+
void *operator new(std::size_t count)
1096+
{
1097+
void *buffer = malloc_wrapper(_REENT, count, MBED_CALLER_ADDR());
1098+
if (NULL == buffer) {
1099+
error("Operator new out of memory\r\n");
1100+
}
1101+
return buffer;
1102+
}
1103+
1104+
void *operator new[](std::size_t count)
1105+
{
1106+
void *buffer = malloc_wrapper(_REENT, count, MBED_CALLER_ADDR());
1107+
if (NULL == buffer) {
1108+
error("Operator new[] out of memory\r\n");
1109+
}
1110+
return buffer;
1111+
}
1112+
1113+
void *operator new(std::size_t count, const std::nothrow_t& tag)
1114+
{
1115+
return malloc_wrapper(_REENT, count, MBED_CALLER_ADDR());
1116+
}
1117+
1118+
void *operator new[](std::size_t count, const std::nothrow_t& tag)
1119+
{
1120+
return malloc_wrapper(_REENT, count, MBED_CALLER_ADDR());
1121+
}
1122+
1123+
void operator delete(void *ptr)
1124+
{
1125+
free_wrapper(_REENT, ptr, MBED_CALLER_ADDR());
1126+
}
1127+
1128+
void operator delete[](void *ptr)
1129+
{
1130+
free_wrapper(_REENT, ptr, MBED_CALLER_ADDR());
1131+
}
1132+
1133+
#else
1134+
10421135
void *operator new(std::size_t count)
10431136
{
10441137
void *buffer = malloc(count);
@@ -1076,6 +1169,8 @@ void operator delete[](void *ptr)
10761169
free(ptr);
10771170
}
10781171

1172+
#endif
1173+
10791174
/* @brief standard c library clock() function.
10801175
*
10811176
* This function returns the number of clock ticks elapsed since the start of the program.

0 commit comments

Comments
 (0)