0

I want My ESP32 to send it's log messages over Wi-Fi. For this I register a uri handler that starts an async response. In principle, this works fine but it crashes at a random moment. Sometimes instantly when I connect, sometimes after several minutes. The core dump message is different. Most of the time is says LoadProhibited, but sometimes also LoadStoreAlignment or the ESP32 just freezes. Looks like something is really messed up.

Logging to UART with the same framework works fine and as long as I don't connect to api/log http is also stable.

/** Handler that will be registered on the httpd. */
esp_err_t uri_handler(httpd_req_t *r) {
    addResponseHeaders(r);
    DEBUG << "Sending log stream";
    auto out = std::make_shared<httpd_req_t*>(nullptr);
    const auto err = httpd_req_async_handler_begin(r, out.get());
    if (err != ESP_OK || *out == nullptr) {
        ERROR << "Failed to start async handler: " << esp_err_to_name(err);
        return err;
    }
    auto receiverId = std::make_shared<int>(0);
    /* Handler that will be registeres on the logging framework */
    auto logReceiver = [out, receiverId] (Log::Level level, const char* tag, const char* file, int line, const std::string_view& message) {
        if (*out) {
            using namespace std;
            string json = format(
                R"({{"uptime":{},"level":{},"tag":"{}","file":"{}","line":{},"message":"{}"}})",
                xTaskGetTickCount(), Log::levelName(level),
                tag, file, line, message
            );
            if (httpd_resp_send_chunk(*out, json.data(), json.size()) != ESP_OK) {
                Log::unregisterLogReceiver(*receiverId);
                if (*out) {
                    httpd_req_async_handler_complete(*out);
                }
                *out = nullptr;
                DEBUG << "Log stream closed";
            }
        } else {
            Log::unregisterLogReceiver(*receiverId);
            DEBUG << "Log stream closed unexpectedly";
        }
    };
    *receiverId = Log::registerLogReceiver(logReceiver);
    return ESP_OK;
}

/** Will be called at program start. */
void registerLogHandler() {
    httpd_uri_t httpd_uri = {
        .uri = "/api/log",
        .method = HTTP_GET,
        .handler = &uri_handler,
        .user_ctx = nullptr,
        .is_websocket = false};
    auto result = httpd_register_uri_handler(HttpServer::handle, &httpd_uri);
}

I have seen the espressif example but don't see any difference except that the whole application architecture is different.

2
  • I'm curious, esp-idf is a framework written in c, how does c++ code like using namespace std; and std::make_shared<httpd_req_t*>(nullptr); mixed in the function work? If you are using ESP32-Arduino (which is in C++), then look into ESPAsyncWebServer and tag your question as arduino-esp32 instead of esp-idf. Commented May 24 at 5:47
  • @hcheung The IDF supports C++ just fine. Use .cpp as extension for your source file names - done. (And use the occasional extern "C" for C++ functions which are called from the IDF's C code, like app_main().) Commented Jun 1 at 22:34

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.