Skip to content

Commit 18fb562

Browse files
authored
FreeRTOS: fix SIGSEV on shutdown by checking if heapTrackingAlive (#197)
On shutdown some global variables are cleaned up. In our case it is the `allocatedMemory` global variable. Check if the heap tracking is still possible by logging the bool variable `heapTrackingAlive` to `false` on destructor. Then we can ignore heap tracking as the `allocatedMemory` map is already freed. Co-authored-by: https://github.com/sofar
1 parent 2ec60f0 commit 18fb562

1 file changed

Lines changed: 35 additions & 14 deletions

File tree

sim/FreeRTOS.cpp

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,39 +12,60 @@ void APP_ERROR_HANDLER(int err) {
1212
}
1313

1414
namespace {
15-
std::unordered_map<void*, size_t> allocatedMemory;
16-
size_t currentFreeHeap = configTOTAL_HEAP_SIZE;
17-
size_t minimumEverFreeHeap = configTOTAL_HEAP_SIZE;
15+
bool heapTrackingAlive = false;
16+
17+
struct HeapTracking {
18+
std::unordered_map<void*, size_t> allocatedMemory;
19+
size_t currentFreeHeap = configTOTAL_HEAP_SIZE;
20+
size_t minimumEverFreeHeap = configTOTAL_HEAP_SIZE;
21+
22+
HeapTracking() {
23+
heapTrackingAlive = true;
24+
}
25+
26+
~HeapTracking() {
27+
heapTrackingAlive = false;
28+
}
29+
};
30+
31+
HeapTracking heapTracking;
1832
}
1933

2034
void* pvPortMalloc(size_t xWantedSize) {
2135
void* ptr = malloc(xWantedSize);
22-
allocatedMemory[ptr] = xWantedSize;
36+
if (!heapTrackingAlive) {
37+
return ptr;
38+
}
39+
heapTracking.allocatedMemory[ptr] = xWantedSize;
2340

24-
const size_t currentSize =
25-
std::accumulate(allocatedMemory.begin(), allocatedMemory.end(), 0, [](const size_t lhs, const std::pair<void*, size_t>& item) {
26-
return lhs + item.second;
27-
});
41+
const size_t currentSize = std::accumulate(heapTracking.allocatedMemory.begin(),
42+
heapTracking.allocatedMemory.end(),
43+
0,
44+
[](const size_t lhs, const std::pair<void*, size_t>& item) {
45+
return lhs + item.second;
46+
});
2847

29-
currentFreeHeap = configTOTAL_HEAP_SIZE - currentSize;
30-
minimumEverFreeHeap = std::min(currentFreeHeap, minimumEverFreeHeap);
48+
heapTracking.currentFreeHeap = configTOTAL_HEAP_SIZE - currentSize;
49+
heapTracking.minimumEverFreeHeap = std::min(heapTracking.currentFreeHeap, heapTracking.minimumEverFreeHeap);
3150

3251
return ptr;
3352
}
3453

3554
void vPortFree(void* pv) {
36-
allocatedMemory.erase(pv);
37-
return free(pv);
55+
if (heapTrackingAlive) {
56+
heapTracking.allocatedMemory.erase(pv);
57+
}
58+
free(pv);
3859
}
3960

4061
size_t xPortGetHeapSize(void) {
4162
return configTOTAL_HEAP_SIZE;
4263
}
4364

4465
size_t xPortGetFreeHeapSize(void) {
45-
return currentFreeHeap;
66+
return heapTracking.currentFreeHeap;
4667
}
4768

4869
size_t xPortGetMinimumEverFreeHeapSize(void) {
49-
return minimumEverFreeHeap;
70+
return heapTracking.minimumEverFreeHeap;
5071
}

0 commit comments

Comments
 (0)