I'm want to give logging functionality to a class ("UhServer" in the code below). To make it dynamic I want to pass a lambda, so that I could use some different logging stuff in the future.
So I made a little mockup with a lamda that just calls logger->log(); ("Logger" handles the logging by keep track of sinks and passing on log message). When I run this on my ESP12E just calling logger->log(); works fine but calling it from inside the lambda throws a "LoadProhibited" exception. It specifically happens when I try to access the instance variable "sinks". I tried to create everything dynamically instead of on the stack to check if it's a scope issue but that doesn't help either? I don't think I'm doing any really weird memory stuff so I'm kind of at a loss here...
#include <Arduino.h>
#include <cstddef>
const int baudRate = 115200;
using byte = unsigned char;
class LogSink {
public:
LogSink(){};
void out(){};
};
class Logger {
public:
Logger() {
sinks = new LogSink*[5];
}
virtual ~Logger() {
delete[] sinks;
}
void log() {
Serial.println("Crashing...");
LogSink* sink = sinks[0];
Serial.println("no crash");
// Never true; tricks compiler into not deleting the line above
if (sink != nullptr) {
Serial.print("out");
sink->out();
}
// Logging stuff would happen here
};
LogSink** sinks;
};
using LogHandler = std::function<void()>;
class UhServer {
public:
UhServer(LogHandler logHandler) : logHandler(logHandler) {};
void testLog() {
logHandler();
};
LogHandler& logHandler;
};
void setup() {
Serial.begin(baudRate);
Logger* logger = new Logger();
UhServer uhServer([logger]() {
logger->log();
});
// >>>> No crash here
logger->log();
// >>>> Crash here
uhServer.testLog();
};
void loop() {
delay(1000);
Serial.print(".");
};