Add magic value
This commit is contained in:
+17
-5
@@ -8,14 +8,25 @@
|
|||||||
// Simple ring buffer log, useful for error reporting when we encounter a crash
|
// Simple ring buffer log, useful for error reporting when we encounter a crash
|
||||||
RTC_NOINIT_ATTR char logMessages[MAX_LOG_LINES][MAX_ENTRY_LEN];
|
RTC_NOINIT_ATTR char logMessages[MAX_LOG_LINES][MAX_ENTRY_LEN];
|
||||||
RTC_NOINIT_ATTR size_t logHead = 0;
|
RTC_NOINIT_ATTR size_t logHead = 0;
|
||||||
|
// Magic word written alongside logHead to detect uninitialized RTC memory.
|
||||||
|
// RTC_NOINIT_ATTR is not zeroed on cold boot, so logHead may appear in-range
|
||||||
|
// (0..MAX_LOG_LINES-1) by chance even though logMessages is garbage. The magic
|
||||||
|
// value is only set by clearLastLogs(), so its absence means the buffer was
|
||||||
|
// never properly initialized.
|
||||||
|
RTC_NOINIT_ATTR uint32_t rtcLogMagic;
|
||||||
|
static constexpr uint32_t fnv1a32(const char* s, uint32_t h = 2166136261u) {
|
||||||
|
return *s ? fnv1a32(s + 1, (h ^ static_cast<uint32_t>(*s)) * 16777619u) : h;
|
||||||
|
}
|
||||||
|
static constexpr uint32_t LOG_RTC_MAGIC = fnv1a32("crosspoint-reader");
|
||||||
|
|
||||||
void addToLogRingBuffer(const char* message) {
|
void addToLogRingBuffer(const char* message) {
|
||||||
// Add the message to the ring buffer, overwriting old messages if necessary
|
// Add the message to the ring buffer, overwriting old messages if necessary.
|
||||||
// If RTC_NOINIT_ATTR left logHead out of range on cold boot, all slots are
|
// If the magic is wrong or logHead is out of range (RTC_NOINIT_ATTR garbage
|
||||||
// garbage too — clear the entire buffer so subsequent reads are safe.
|
// on cold boot), clear the entire buffer so subsequent reads are safe.
|
||||||
if (logHead >= MAX_LOG_LINES) {
|
if (rtcLogMagic != LOG_RTC_MAGIC || logHead >= MAX_LOG_LINES) {
|
||||||
memset(logMessages, 0, sizeof(logMessages));
|
memset(logMessages, 0, sizeof(logMessages));
|
||||||
logHead = 0;
|
logHead = 0;
|
||||||
|
rtcLogMagic = LOG_RTC_MAGIC;
|
||||||
}
|
}
|
||||||
strncpy(logMessages[logHead], message, MAX_ENTRY_LEN - 1);
|
strncpy(logMessages[logHead], message, MAX_ENTRY_LEN - 1);
|
||||||
logMessages[logHead][MAX_ENTRY_LEN - 1] = '\0';
|
logMessages[logHead][MAX_ENTRY_LEN - 1] = '\0';
|
||||||
@@ -81,7 +92,7 @@ std::string getLastLogs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool sanitizeLogHead() {
|
bool sanitizeLogHead() {
|
||||||
if (logHead >= MAX_LOG_LINES) {
|
if (rtcLogMagic != LOG_RTC_MAGIC || logHead >= MAX_LOG_LINES) {
|
||||||
logHead = 0;
|
logHead = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -93,4 +104,5 @@ void clearLastLogs() {
|
|||||||
logMessages[i][0] = '\0';
|
logMessages[i][0] = '\0';
|
||||||
}
|
}
|
||||||
logHead = 0;
|
logHead = 0;
|
||||||
|
rtcLogMagic = LOG_RTC_MAGIC;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,10 +57,10 @@ void logPrintf(const char* level, const char* origin, const char* format, ...);
|
|||||||
|
|
||||||
std::string getLastLogs();
|
std::string getLastLogs();
|
||||||
void clearLastLogs();
|
void clearLastLogs();
|
||||||
// Clamps logHead into range. Returns true if logHead was out of range (repaired),
|
// Validates the RTC log state (magic word + logHead range). Returns true if
|
||||||
// which also means logMessages is untrusted garbage. Callers should call
|
// corruption was detected (magic mismatch or logHead out of range), meaning
|
||||||
// clearLastLogs() when this returns true so getLastLogs() does not dump corrupt
|
// logMessages is untrusted garbage. Callers should call clearLastLogs() when
|
||||||
// data into crash reports.
|
// this returns true so getLastLogs() does not dump corrupt data into crash reports.
|
||||||
bool sanitizeLogHead();
|
bool sanitizeLogHead();
|
||||||
|
|
||||||
class MySerialImpl : public Print {
|
class MySerialImpl : public Print {
|
||||||
|
|||||||
Reference in New Issue
Block a user