Skip to content

Commit c4211e1

Browse files
authored
Merge pull request #5614 from maciejbocianski/mem_trace_fix
platform: fix mem_trace trace level guard
2 parents 43af0d7 + aa22ef1 commit c4211e1

File tree

3 files changed

+67
-29
lines changed

3 files changed

+67
-29
lines changed

platform/mbed_alloc_wrappers.cpp

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ typedef struct {
4646
uint32_t pad;
4747
} alloc_info_t;
4848

49-
#ifdef MBED_MEM_TRACING_ENABLED
50-
static SingletonPtr<PlatformMutex> mem_trace_mutex;
51-
#endif
5249
#ifdef MBED_HEAP_STATS_ENABLED
5350
static SingletonPtr<PlatformMutex> malloc_stats_mutex;
5451
static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0};
@@ -91,6 +88,9 @@ extern "C" {
9188

9289
extern "C" void * __wrap__malloc_r(struct _reent * r, size_t size) {
9390
void *ptr = NULL;
91+
#ifdef MBED_MEM_TRACING_ENABLED
92+
mbed_mem_trace_lock();
93+
#endif
9494
#ifdef MBED_HEAP_STATS_ENABLED
9595
malloc_stats_mutex->lock();
9696
alloc_info_t *alloc_info = (alloc_info_t*)__real__malloc_r(r, size + sizeof(alloc_info_t));
@@ -111,15 +111,17 @@ extern "C" void * __wrap__malloc_r(struct _reent * r, size_t size) {
111111
ptr = __real__malloc_r(r, size);
112112
#endif // #ifdef MBED_HEAP_STATS_ENABLED
113113
#ifdef MBED_MEM_TRACING_ENABLED
114-
mem_trace_mutex->lock();
115114
mbed_mem_trace_malloc(ptr, size, MBED_CALLER_ADDR());
116-
mem_trace_mutex->unlock();
115+
mbed_mem_trace_unlock();
117116
#endif // #ifdef MBED_MEM_TRACING_ENABLED
118117
return ptr;
119118
}
120119

121120
extern "C" void * __wrap__realloc_r(struct _reent * r, void * ptr, size_t size) {
122121
void *new_ptr = NULL;
122+
#ifdef MBED_MEM_TRACING_ENABLED
123+
mbed_mem_trace_lock();
124+
#endif
123125
#ifdef MBED_HEAP_STATS_ENABLED
124126
// Implement realloc_r with malloc and free.
125127
// The function realloc_r can't be used here directly since
@@ -151,14 +153,16 @@ extern "C" void * __wrap__realloc_r(struct _reent * r, void * ptr, size_t size)
151153
new_ptr = __real__realloc_r(r, ptr, size);
152154
#endif // #ifdef MBED_HEAP_STATS_ENABLED
153155
#ifdef MBED_MEM_TRACING_ENABLED
154-
mem_trace_mutex->lock();
155156
mbed_mem_trace_realloc(new_ptr, ptr, size, MBED_CALLER_ADDR());
156-
mem_trace_mutex->unlock();
157+
mbed_mem_trace_unlock();
157158
#endif // #ifdef MBED_MEM_TRACING_ENABLED
158159
return new_ptr;
159160
}
160161

161162
extern "C" void __wrap__free_r(struct _reent * r, void * ptr) {
163+
#ifdef MBED_MEM_TRACING_ENABLED
164+
mbed_mem_trace_lock();
165+
#endif
162166
#ifdef MBED_HEAP_STATS_ENABLED
163167
malloc_stats_mutex->lock();
164168
alloc_info_t *alloc_info = NULL;
@@ -173,14 +177,16 @@ extern "C" void __wrap__free_r(struct _reent * r, void * ptr) {
173177
__real__free_r(r, ptr);
174178
#endif // #ifdef MBED_HEAP_STATS_ENABLED
175179
#ifdef MBED_MEM_TRACING_ENABLED
176-
mem_trace_mutex->lock();
177180
mbed_mem_trace_free(ptr, MBED_CALLER_ADDR());
178-
mem_trace_mutex->unlock();
181+
mbed_mem_trace_unlock();
179182
#endif // #ifdef MBED_MEM_TRACING_ENABLED
180183
}
181184

182185
extern "C" void * __wrap__calloc_r(struct _reent * r, size_t nmemb, size_t size) {
183186
void *ptr = NULL;
187+
#ifdef MBED_MEM_TRACING_ENABLED
188+
mbed_mem_trace_lock();
189+
#endif
184190
#ifdef MBED_HEAP_STATS_ENABLED
185191
// Note - no lock needed since malloc is thread safe
186192

@@ -192,9 +198,8 @@ extern "C" void * __wrap__calloc_r(struct _reent * r, size_t nmemb, size_t size)
192198
ptr = __real__calloc_r(r, nmemb, size);
193199
#endif // #ifdef MBED_HEAP_STATS_ENABLED
194200
#ifdef MBED_MEM_TRACING_ENABLED
195-
mem_trace_mutex->lock();
196201
mbed_mem_trace_calloc(ptr, nmemb, size, MBED_CALLER_ADDR());
197-
mem_trace_mutex->unlock();
202+
mbed_mem_trace_unlock();
198203
#endif // #ifdef MBED_MEM_TRACING_ENABLED
199204
return ptr;
200205
}
@@ -244,6 +249,9 @@ extern "C" {
244249

245250
extern "C" void* SUB_MALLOC(size_t size) {
246251
void *ptr = NULL;
252+
#ifdef MBED_MEM_TRACING_ENABLED
253+
mbed_mem_trace_lock();
254+
#endif
247255
#ifdef MBED_HEAP_STATS_ENABLED
248256
malloc_stats_mutex->lock();
249257
alloc_info_t *alloc_info = (alloc_info_t*)SUPER_MALLOC(size + sizeof(alloc_info_t));
@@ -264,15 +272,17 @@ extern "C" void* SUB_MALLOC(size_t size) {
264272
ptr = SUPER_MALLOC(size);
265273
#endif // #ifdef MBED_HEAP_STATS_ENABLED
266274
#ifdef MBED_MEM_TRACING_ENABLED
267-
mem_trace_mutex->lock();
268275
mbed_mem_trace_malloc(ptr, size, MBED_CALLER_ADDR());
269-
mem_trace_mutex->unlock();
276+
mbed_mem_trace_unlock();
270277
#endif // #ifdef MBED_MEM_TRACING_ENABLED
271278
return ptr;
272279
}
273280

274281
extern "C" void* SUB_REALLOC(void *ptr, size_t size) {
275282
void *new_ptr = NULL;
283+
#ifdef MBED_MEM_TRACING_ENABLED
284+
mbed_mem_trace_lock();
285+
#endif
276286
#ifdef MBED_HEAP_STATS_ENABLED
277287
// Note - no lock needed since malloc and free are thread safe
278288

@@ -299,15 +309,17 @@ extern "C" void* SUB_REALLOC(void *ptr, size_t size) {
299309
new_ptr = SUPER_REALLOC(ptr, size);
300310
#endif // #ifdef MBED_HEAP_STATS_ENABLED
301311
#ifdef MBED_MEM_TRACING_ENABLED
302-
mem_trace_mutex->lock();
303312
mbed_mem_trace_realloc(new_ptr, ptr, size, MBED_CALLER_ADDR());
304-
mem_trace_mutex->unlock();
313+
mbed_mem_trace_unlock();
305314
#endif // #ifdef MBED_MEM_TRACING_ENABLED
306315
return new_ptr;
307316
}
308317

309318
extern "C" void *SUB_CALLOC(size_t nmemb, size_t size) {
310319
void *ptr = NULL;
320+
#ifdef MBED_MEM_TRACING_ENABLED
321+
mbed_mem_trace_lock();
322+
#endif
311323
#ifdef MBED_HEAP_STATS_ENABLED
312324
// Note - no lock needed since malloc is thread safe
313325
ptr = malloc(nmemb * size);
@@ -318,14 +330,16 @@ extern "C" void *SUB_CALLOC(size_t nmemb, size_t size) {
318330
ptr = SUPER_CALLOC(nmemb, size);
319331
#endif // #ifdef MBED_HEAP_STATS_ENABLED
320332
#ifdef MBED_MEM_TRACING_ENABLED
321-
mem_trace_mutex->lock();
322333
mbed_mem_trace_calloc(ptr, nmemb, size, MBED_CALLER_ADDR());
323-
mem_trace_mutex->unlock();
334+
mbed_mem_trace_unlock();
324335
#endif // #ifdef MBED_MEM_TRACING_ENABLED
325336
return ptr;
326337
}
327338

328339
extern "C" void SUB_FREE(void *ptr) {
340+
#ifdef MBED_MEM_TRACING_ENABLED
341+
mbed_mem_trace_lock();
342+
#endif
329343
#ifdef MBED_HEAP_STATS_ENABLED
330344
malloc_stats_mutex->lock();
331345
alloc_info_t *alloc_info = NULL;
@@ -340,9 +354,8 @@ extern "C" void SUB_FREE(void *ptr) {
340354
SUPER_FREE(ptr);
341355
#endif // #ifdef MBED_HEAP_STATS_ENABLED
342356
#ifdef MBED_MEM_TRACING_ENABLED
343-
mem_trace_mutex->lock();
344357
mbed_mem_trace_free(ptr, MBED_CALLER_ADDR());
345-
mem_trace_mutex->unlock();
358+
mbed_mem_trace_unlock();
346359
#endif // #ifdef MBED_MEM_TRACING_ENABLED
347360
}
348361

platform/mbed_mem_trace.c renamed to platform/mbed_mem_trace.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,23 @@
1919
#include <stdio.h>
2020
#include "platform/mbed_mem_trace.h"
2121
#include "platform/mbed_critical.h"
22+
#include "platform/SingletonPtr.h"
23+
#include "platform/PlatformMutex.h"
2224

2325
/******************************************************************************
2426
* Internal variables, functions and helpers
2527
*****************************************************************************/
2628

2729
/* The callback function that will be called after a traced memory operations finishes. */
2830
static mbed_mem_trace_cb_t mem_trace_cb;
29-
/* 'trave_level' guards "trace inside trace" situations (for example, the implementation
31+
/* 'trace_lock_count' guards "trace inside trace" situations (for example, the implementation
3032
* of realloc() might call malloc() internally, and since malloc() is also traced, this could
3133
* result in two calls to the callback function instead of one. */
32-
static uint8_t trace_level;
34+
static uint8_t trace_lock_count;
35+
static SingletonPtr<PlatformMutex> mem_trace_mutex;
36+
37+
#define TRACE_FIRST_LOCK() (trace_lock_count < 2)
38+
3339

3440
/******************************************************************************
3541
* Public interface
@@ -39,42 +45,50 @@ void mbed_mem_trace_set_callback(mbed_mem_trace_cb_t cb) {
3945
mem_trace_cb = cb;
4046
}
4147

48+
void mbed_mem_trace_lock()
49+
{
50+
mem_trace_mutex->lock();
51+
trace_lock_count++;
52+
}
53+
54+
void mbed_mem_trace_unlock()
55+
{
56+
trace_lock_count--;
57+
mem_trace_mutex->unlock();
58+
}
59+
4260
void *mbed_mem_trace_malloc(void *res, size_t size, void *caller) {
4361
if (mem_trace_cb) {
44-
if (core_util_atomic_incr_u8(&trace_level, 1) == 1) {
62+
if (TRACE_FIRST_LOCK()) {
4563
mem_trace_cb(MBED_MEM_TRACE_MALLOC, res, caller, size);
4664
}
47-
core_util_atomic_decr_u8(&trace_level, 1);
4865
}
4966
return res;
5067
}
5168

5269
void *mbed_mem_trace_realloc(void *res, void *ptr, size_t size, void *caller) {
5370
if (mem_trace_cb) {
54-
if (core_util_atomic_incr_u8(&trace_level, 1) == 1) {
71+
if (TRACE_FIRST_LOCK()) {
5572
mem_trace_cb(MBED_MEM_TRACE_REALLOC, res, caller, ptr, size);
5673
}
57-
core_util_atomic_decr_u8(&trace_level, 1);
5874
}
5975
return res;
6076
}
6177

6278
void *mbed_mem_trace_calloc(void *res, size_t num, size_t size, void *caller) {
6379
if (mem_trace_cb) {
64-
if (core_util_atomic_incr_u8(&trace_level, 1) == 1) {
80+
if (TRACE_FIRST_LOCK()) {
6581
mem_trace_cb(MBED_MEM_TRACE_CALLOC, res, caller, num, size);
6682
}
67-
core_util_atomic_decr_u8(&trace_level, 1);
6883
}
6984
return res;
7085
}
7186

7287
void mbed_mem_trace_free(void *ptr, void *caller) {
7388
if (mem_trace_cb) {
74-
if (core_util_atomic_incr_u8(&trace_level, 1) == 1) {
89+
if (TRACE_FIRST_LOCK()) {
7590
mem_trace_cb(MBED_MEM_TRACE_FREE, NULL, caller, ptr);
7691
}
77-
core_util_atomic_decr_u8(&trace_level, 1);
7892
}
7993
}
8094

platform/mbed_mem_trace.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ typedef void (*mbed_mem_trace_cb_t)(uint8_t op, void *res, void* caller, ...);
7272
*/
7373
void mbed_mem_trace_set_callback(mbed_mem_trace_cb_t cb);
7474

75+
/**
76+
* Trace lock.
77+
* @note Locking prevent recursive tracing of malloc/free inside relloc/calloc
78+
*/
79+
void mbed_mem_trace_lock();
80+
81+
/**
82+
* Trace unlock.
83+
*/
84+
void mbed_mem_trace_unlock();
85+
7586
/**
7687
* Trace a call to 'malloc'.
7788
* @param res the result of running 'malloc'.

0 commit comments

Comments
 (0)