Add MemAudit: per-subsystem heap accounting in the boot log (#10900)
* Add MemAudit: per-subsystem heap accounting in the boot log The 2.8.0 nRF52840 heap-exhaustion field reports had to be diagnosed by hand, reconstructing each subsystem's heap footprint from source and build flags one report at a time. This makes every future report self-diagnosing from the serial log: a tiny fixed-size registry (src/memory/MemAudit.*) that big long-lived allocations report into, printed as one line at the end of setup() and alongside the periodic "Heap free:" log: MemAudit[boot]: tmm=2500 warm=4000 pkthist=5824 nodedb=13440 msgstore=2200 pktpool(live)=3270 total=31234 Instrumented: NodeDB hot vector (nodedb) + satellite maps (satmaps, rb-tree overhead estimated), WarmNodeStore (warm), PacketHistory records and hash index (pkthist), TrafficManagement caches (tmm/tmm_ni), MessageStore text pool (msgstore), TFT line/repaint buffers (display), and live in-flight packets (pktpool(live)) via an optional audit tag on the packet pool allocator - the one hot path, counted with a relaxed 32-bit atomic add (single instructions on Cortex-M, no locks). Cost: 128 B RAM for the 16-tag table, well under 1 KB flash on rak4631. MESHTASTIC_MEM_AUDIT=0 compiles it out to inline no-op stubs (call sites need no ifdefs); STM32WL, the tightest flash target, defaults off. New native suite test_mem_audit covers add/set/snapshot arithmetic, tag reuse (pointer and cross-TU strcmp fallback), null/unknown tags, and table-full behavior; test/native-suite-count bumped to 28. * native-wasm: add src/memory/ to the curated source filter The wasm env denies all sources and adds an explicit file list; MemAudit callers (main, MeshService, NodeDB, PacketHistory) are in that list but src/memory/MemAudit.cpp was not, so wasm-ld failed on undefined memaudit:: symbols.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "TypeConversions.h"
|
||||
#include "error.h"
|
||||
#include "main.h"
|
||||
#include "memory/MemAudit.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
#include "mesh/generated/meshtastic/deviceonly_legacy.pb.h"
|
||||
#include "meshUtils.h"
|
||||
@@ -1796,6 +1797,25 @@ bool NodeDB::enforceSatelliteCaps()
|
||||
#endif
|
||||
|
||||
(void)trim; // all four maps may be compiled out
|
||||
|
||||
// Approximate satellite heap usage: each std::map entry is one rb-tree node,
|
||||
// value_type plus ~44 B of node overhead (parent/left/right pointers, color,
|
||||
// allocator rounding on 32-bit targets - an estimate, not exact bookkeeping).
|
||||
size_t satBytes = 0;
|
||||
#if !MESHTASTIC_EXCLUDE_POSITIONDB
|
||||
satBytes += nodePositions.size() * (sizeof(decltype(nodePositions)::value_type) + 44);
|
||||
#endif
|
||||
#if !MESHTASTIC_EXCLUDE_TELEMETRYDB
|
||||
satBytes += nodeTelemetry.size() * (sizeof(decltype(nodeTelemetry)::value_type) + 44);
|
||||
#endif
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTDB
|
||||
satBytes += nodeEnvironment.size() * (sizeof(decltype(nodeEnvironment)::value_type) + 44);
|
||||
#endif
|
||||
#if !MESHTASTIC_EXCLUDE_STATUSDB
|
||||
satBytes += nodeStatus.size() * (sizeof(decltype(nodeStatus)::value_type) + 44);
|
||||
#endif
|
||||
memaudit::set("satmaps", satBytes);
|
||||
|
||||
return trimmedAny;
|
||||
}
|
||||
|
||||
@@ -2080,6 +2100,7 @@ void NodeDB::nodeDBSelfCare()
|
||||
// Normalise the backing store to the hot cap so getOrCreateMeshNode always
|
||||
// has spare slots to append into (it indexes meshNodes->at(numMeshNodes++)).
|
||||
meshNodes->resize(MAX_NUM_NODES);
|
||||
memaudit::set("nodedb", MAX_NUM_NODES * sizeof(meshtastic_NodeInfoLite));
|
||||
|
||||
const bool satsTrimmed = enforceSatelliteCaps();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user