Skip to content

Commit a0aab9b

Browse files
committed
no-throw/thread-safe baseline
1 parent c0b87e9 commit a0aab9b

4 files changed

Lines changed: 43 additions & 19 deletions

File tree

.github/workflows/ci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,22 @@ on:
88
workflow_dispatch:
99

1010
jobs:
11+
source-audit:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: Audit production sources
18+
run: |
19+
if rg -n '\bthrow\b|std::abort\(' src; then
20+
echo "Embedded safety audit failed"
21+
exit 1
22+
fi
23+
1124
build-examples:
1225
runs-on: ubuntu-latest
26+
needs: source-audit
1327
strategy:
1428
fail-fast: false
1529
matrix:
@@ -56,6 +70,7 @@ jobs:
5670
5771
arduino-cli:
5872
runs-on: ubuntu-latest
73+
needs: source-audit
5974
env:
6075
ESP32_CORE_VERSION: 3.3.3
6176
ARDUINO_BOARDS: |

library.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
"headers": ["ESPMemoryMonitor.h"],
3636
"build": {
3737
"flags": [
38-
"-std=gnu++17"
38+
"-std=gnu++17",
39+
"-fno-exceptions"
3940
]
4041
}
4142
}

src/esp_memory_monitor/memory_monitor.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@ inline size_t saturatingSubtract(size_t value, size_t delta) {
2626
return value > delta ? value - delta : 0;
2727
}
2828

29+
template <typename Callback, typename... Args>
30+
void invokeMemoryMonitorCallback(const Callback &callback, Args... args) noexcept {
31+
if (!callback) {
32+
return;
33+
}
34+
35+
#if defined(__cpp_exceptions)
36+
try {
37+
callback(args...);
38+
} catch (...) {
39+
}
40+
#else
41+
callback(args...);
42+
#endif
43+
}
44+
2945
} // namespace
3046

3147
ESPMemoryMonitor *gPanicInstance = nullptr;
@@ -230,18 +246,18 @@ MemorySnapshot ESPMemoryMonitor::sampleNow() {
230246

231247
for (const auto &evt : events) {
232248
if (thresholdCb) {
233-
thresholdCb(evt);
249+
invokeMemoryMonitorCallback(thresholdCb, evt);
234250
}
235251
}
236252

237253
for (const auto &evt : stackEvents) {
238254
if (stackCb) {
239-
stackCb(evt);
255+
invokeMemoryMonitorCallback(stackCb, evt);
240256
}
241257
}
242258

243259
if (sampleCb) {
244-
sampleCb(publicSnapshot);
260+
invokeMemoryMonitorCallback(sampleCb, publicSnapshot);
245261
}
246262

247263
return publicSnapshot;
@@ -369,7 +385,7 @@ LeakCheckResult ESPMemoryMonitor::markLeakCheckPoint(const std::string &label) {
369385
LeakCheckResult result = toPublicLeakCheckResult(internal);
370386

371387
if (cb && !result.deltas.empty()) {
372-
cb(result);
388+
invokeMemoryMonitorCallback(cb, result);
373389
}
374390

375391
return result;
@@ -547,12 +563,12 @@ ScopeStats ESPMemoryMonitor::finalizeScope(const MemoryScope &scope) {
547563
}
548564

549565
if (scopeCb) {
550-
scopeCb(toPublicScopeStats(stats));
566+
invokeMemoryMonitorCallback(scopeCb, toPublicScopeStats(stats));
551567
}
552568

553569
if (tagCb) {
554570
for (const auto &evt : tagEvents) {
555-
tagCb(evt);
571+
invokeMemoryMonitorCallback(tagCb, evt);
556572
}
557573
}
558574

@@ -716,7 +732,7 @@ void ESPMemoryMonitor::handleAllocEvent(
716732
event.functionName = functionName;
717733
event.timestampUs = esp_timer_get_time();
718734

719-
cb(event);
735+
invokeMemoryMonitorCallback(cb, event);
720736
}
721737

722738
void ESPMemoryMonitor::allocFailedHook(
@@ -1189,7 +1205,7 @@ void ESPMemoryMonitor::runPanicHook() {
11891205
}
11901206

11911207
if (cb) {
1192-
cb(snapshot);
1208+
invokeMemoryMonitorCallback(cb, snapshot);
11931209
}
11941210
}
11951211

src/esp_memory_monitor/memory_monitor_allocator.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,12 @@ template <typename T> class MemoryMonitorAllocator {
6262
return nullptr;
6363
}
6464
if (n > (std::numeric_limits<std::size_t>::max() / sizeof(T))) {
65-
#if defined(__cpp_exceptions)
66-
throw std::bad_alloc();
67-
#else
68-
std::abort();
69-
#endif
65+
return nullptr;
7066
}
7167

7268
void *memory = memory_monitor_allocator_detail::allocate(n * sizeof(T), _usePSRAMBuffers);
7369
if (memory == nullptr) {
74-
#if defined(__cpp_exceptions)
75-
throw std::bad_alloc();
76-
#else
77-
std::abort();
78-
#endif
70+
return nullptr;
7971
}
8072

8173
return static_cast<T *>(memory);

0 commit comments

Comments
 (0)