45
45
* tested. This option is enabled when Tools->Debug: Serial is selected or
46
46
* Tools->Debug level: "CORE" is selected. While coverage is not 100%, a
47
47
* sketch is less likely to have strange behavior from heavy heap access with
48
- * interrupts disabled.
48
+ * interrupts disabled. If needed, continue reading "UMM_POISON_CHECK" for
49
+ * more details.
49
50
*
50
51
* * UMM_POISON_CHECK - Adds and presets 4 bytes of poison at the beginning and
51
52
* end of each allocation. For each Heap API call, a complete sweep through
@@ -101,6 +102,8 @@ extern "C" void z2EapFree(void *ptr, const char* file, int line) __attribute__((
101
102
#include < sys/reent.h>
102
103
#include < user_interface.h>
103
104
105
+ #include " heap_cb.h"
106
+
104
107
extern " C" {
105
108
106
109
// /////////////////////////////////////////////////////////////////////////////
@@ -133,7 +136,7 @@ extern "C" {
133
136
#undef realloc
134
137
#undef free
135
138
136
- #elif defined(DEBUG_ESP_OOM) || defined(UMM_INTEGRITY_CHECK)
139
+ #elif defined(DEBUG_ESP_OOM) || defined(UMM_INTEGRITY_CHECK) || defined(HEAP_DEBUG_PROBE_PSFLC_CB)
137
140
// All other debug wrappers that do not require handling poison
138
141
#define UMM_MALLOC_FL (s,f,l,c ) umm_malloc(s)
139
142
#define UMM_CALLOC_FL (n,s,f,l,c ) umm_calloc(n,s)
@@ -197,10 +200,11 @@ extern "C" {
197
200
198
201
199
202
// /////////////////////////////////////////////////////////////////////////////
200
- // OOM - this structure variable is always in use by abi.cpp
201
- //
202
- // Always track last failed caller and size requested
203
+ // OOM - this structure variable is always in use by abi.cpp - except for
204
+ // C++ Exceptions "enabled" builds.
203
205
//
206
+ // When building with C++ Exceptions "disabled" or debug build,
207
+ // always track last failed caller and size requested
204
208
#if defined(DEBUG_ESP_OOM)
205
209
struct umm_last_fail_alloc {
206
210
const void *addr;
@@ -210,6 +214,8 @@ struct umm_last_fail_alloc {
210
214
} _umm_last_fail_alloc = {NULL , 0 , NULL , 0 };
211
215
212
216
#else
217
+ // Note for the least used case "(defined(__cpp_exceptions) &&
218
+ // !defined(DEBUG_ESP_OOM))", we only capture details for LIBC calls.
213
219
struct umm_last_fail_alloc {
214
220
const void *addr;
215
221
size_t size;
@@ -268,6 +274,7 @@ static bool IRAM_ATTR oom_check__log_last_fail_atomic_psflc(void *ptr, size_t si
268
274
_umm_last_fail_alloc.line = line;
269
275
print_loc (size, file, line, caller);
270
276
xt_wsr_ps (saved_ps);
277
+ _HEAP_DEBUG_PROBE_PSFLC_CB (heap_oom_cb_id, ptr, size, file, line, caller);
271
278
return false ;
272
279
}
273
280
return true ;
@@ -276,18 +283,19 @@ static bool IRAM_ATTR oom_check__log_last_fail_atomic_psflc(void *ptr, size_t si
276
283
#define OOM_CHECK__LOG_LAST_FAIL_LITE_FL (p, s, f, l, c ) ({ (void )p, (void )s, (void )f; (void )l; (void )c; true ; })
277
284
278
285
#elif defined(ENABLE_THICK_DEBUG_WRAPPERS)
279
- static bool IRAM_ATTR oom_check__log_last_fail_psc (void *ptr, size_t size, const void * caller) {
286
+ static bool IRAM_ATTR oom_check__log_last_fail_atomic_psc (void *ptr, size_t size, const void * caller) {
280
287
if (0 != (size) && 0 == ptr) {
281
288
// Need to ensure changes to umm_last_fail_alloc are atomic.
282
289
uint32_t saved_ps = xt_rsil (DEFAULT_CRITICAL_SECTION_INTLEVEL);
283
290
_umm_last_fail_alloc.addr = caller;
284
291
_umm_last_fail_alloc.size = size;
285
292
xt_wsr_ps (saved_ps);
293
+ _HEAP_DEBUG_PROBE_PSFLC_CB (heap_oom_cb_id, ptr, size, NULL , 0 , caller);
286
294
return false ;
287
295
}
288
296
return true ;
289
297
}
290
- #define OOM_CHECK__LOG_LAST_FAIL_FL (p, s, f, l, c ) oom_check__log_last_fail_psc (p, s, c)
298
+ #define OOM_CHECK__LOG_LAST_FAIL_FL (p, s, f, l, c ) oom_check__log_last_fail_atomic_psc (p, s, c)
291
299
#define OOM_CHECK__LOG_LAST_FAIL_LITE_FL (p, s, f, l, c ) ({ (void )p, (void )s, (void )f; (void )l; (void )c; true ; })
292
300
293
301
#else
@@ -298,6 +306,7 @@ static bool oom_check__log_last_fail_psc(void *ptr, size_t size, const void* cal
298
306
if (0 != (size) && 0 == ptr) {
299
307
_umm_last_fail_alloc.addr = caller;
300
308
_umm_last_fail_alloc.size = size;
309
+ _HEAP_DEBUG_PROBE_PSFLC_CB (heap_oom_cb_id, ptr, size, NULL , 0 , caller);
301
310
return false ;
302
311
}
303
312
return true ;
@@ -356,6 +365,7 @@ void* IRAM_ATTR _heap_pvPortMalloc(size_t size, const char* file, int line, cons
356
365
INTEGRITY_CHECK__PANIC_FL (file, line, caller);
357
366
POISON_CHECK__PANIC_FL (file, line, caller);
358
367
void * ret = UMM_MALLOC_FL (size, file, line, caller);
368
+ ret = _HEAP_DEBUG_PROBE_PSFLC_CB (heap_malloc_cb_id, ret, size, file, line, caller);
359
369
OOM_CHECK__LOG_LAST_FAIL_FL (ret, size, file, line, caller);
360
370
return ret;
361
371
}
@@ -366,14 +376,17 @@ void* IRAM_ATTR _heap_pvPortCalloc(size_t count, size_t size, const char* file,
366
376
POISON_CHECK__PANIC_FL (file, line, caller);
367
377
size_t total_size = umm_umul_sat (count, size);
368
378
void * ret = UMM_CALLOC_FL (1 , total_size, file, line, caller);
379
+ ret = _HEAP_DEBUG_PROBE_PSFLC_CB (heap_calloc_cb_id, ret, size, file, line, caller);
369
380
OOM_CHECK__LOG_LAST_FAIL_FL (ret, total_size, file, line, caller);
370
381
return ret;
371
382
}
372
383
373
384
void * IRAM_ATTR _heap_pvPortRealloc (void *ptr, size_t size, const char * file, int line, const void *caller)
374
385
{
375
386
INTEGRITY_CHECK__PANIC_FL (file, line, caller);
387
+ ptr = _HEAP_DEBUG_PROBE_PSFLC_CB (heap_realloc_in_cb_id, ptr, size, file, line, caller);
376
388
void * ret = UMM_REALLOC_FL (ptr, size, file, line, caller);
389
+ ret = _HEAP_DEBUG_PROBE_PSFLC_CB (heap_realloc_out_cb_id, ret, size, file, line, caller);
377
390
POISON_CHECK__PANIC_FL (file, line, caller);
378
391
OOM_CHECK__LOG_LAST_FAIL_FL (ret, size, file, line, caller);
379
392
return ret;
@@ -382,6 +395,7 @@ void* IRAM_ATTR _heap_pvPortRealloc(void *ptr, size_t size, const char* file, in
382
395
void IRAM_ATTR _heap_vPortFree (void *ptr, const char * file, int line, [[maybe_unused]] const void *caller)
383
396
{
384
397
INTEGRITY_CHECK__PANIC_FL (file, line, caller);
398
+ ptr = _HEAP_DEBUG_PROBE_PSFLC_CB (heap_free_cb_id, ptr, 0 , file, line, caller);
385
399
UMM_FREE_FL (ptr, file, line, caller);
386
400
POISON_CHECK__PANIC_FL (file, line, caller);
387
401
}
@@ -579,10 +593,10 @@ void system_show_malloc(void)
579
593
#endif
580
594
}
581
595
582
- #if !defined(__cpp_exceptions)
596
+ #if defined(DEBUG_ESP_OOM) || !defined(__cpp_exceptions) || defined(DEBUG_ESP_PORT )
583
597
// /////////////////////////////////////////////////////////////////////////////
584
598
// heap allocator for "new" (ABI) - To support collecting OOM info, always defined
585
- void * _heap_abi_malloc (size_t size, bool unhandle , const void * caller)
599
+ void * _heap_abi_malloc (size_t size, bool unhandled , const void * caller)
586
600
{
587
601
[[maybe_unused]] const char *file = NULL ;
588
602
[[maybe_unused]] const int line = 0 ;
@@ -591,16 +605,15 @@ void* _heap_abi_malloc(size_t size, bool unhandle, const void* caller)
591
605
INTEGRITY_CHECK__PANIC_FL (file, line, caller);
592
606
POISON_CHECK__PANIC_FL (file, line, caller);
593
607
void * ret = UMM_MALLOC_FL (size, file, line, caller);
594
- if (!OOM_CHECK__LOG_LAST_FAIL_FL (ret, size, file, line, caller) && unhandle) {
595
- __unhandled_exception (PSTR (" OOM" ));
596
- }
608
+ bool ok = OOM_CHECK__LOG_LAST_FAIL_FL (ret, size, file, line, caller);
597
609
#else
598
610
void * ret = UMM_MALLOC (size);
599
- // Always do some level of OOM check
600
- if (!OOM_CHECK__LOG_LAST_FAIL_LITE_FL (ret, size, file, line, caller) && unhandle) {
611
+ // minimum OOM check
612
+ bool ok = OOM_CHECK__LOG_LAST_FAIL_LITE_FL (ret, size, file, line, caller)
613
+ #endif
614
+ if (!ok && unhandled) {
601
615
__unhandled_exception (PSTR (" OOM" ));
602
616
}
603
- #endif
604
617
return ret;
605
618
}
606
619
#endif
@@ -617,23 +630,7 @@ void* _heap_abi_malloc(size_t size, bool unhandle, const void* caller)
617
630
// Replacement C++ delete operator to capture callers address
618
631
//
619
632
#include < bits/c++config.h>
620
-
621
- #if !_GLIBCXX_HOSTED
622
- // A freestanding C runtime may not provide "free" -- but there is no
623
- // other reasonable way to implement "operator delete".
624
- namespace std
625
- {
626
- _GLIBCXX_BEGIN_NAMESPACE_VERSION
627
- extern " C" void free (void *);
628
- _GLIBCXX_END_NAMESPACE_VERSION
629
- } // namespace
630
- #pragma message("!_GLIBCXX_HOSTED")
631
- #else
632
- // #pragma message("_GLIBCXX_HOSTED")
633
- // This is the path taken
634
633
#include < cstdlib>
635
- #endif
636
-
637
634
#include " new"
638
635
639
636
// The sized deletes are defined in other files.
0 commit comments