Difference in Execution between RELEASE and DEBUG

I have edited the title of this since realizing where my issue really is. Simply put: My code runs fine when in RELEASE but fails in DEBUG:

CONFIGURATION: https://docs.platformio.org/page/boards/espressif8266/d1_mini.html
PLATFORM: Espressif 8266 2.3.3 > WeMos D1 R2 and mini
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash

I noticed my sketch would fail to read a JSON file in SPIFFS correctly (using ArduinoJson) when build_type is “debug,” but not when it is “release.” So, what’s going on internally with debug vs release? I have to admit - discovering this feels like a win, but it still means something weird is going on.

I’m just looking for a way forward here, something to tell the class developer. Any ideas?

For the sake of completeness, below is my test program:

main.cpp:

#include <FS.h>
#include "Config.h"

const char *filename = "/config.json";
Config config;

void printFile(const char *filename) {
    File file = SPIFFS.open(filename, "r");
    if (!file) {
        Serial.println(F("Failed to open config file"));
        return;
    }

    while (file.available()) {
        Serial.print((char)file.read());
    }
    Serial.println();
}

bool loadFile(const char *filename, Config &config) {
    File file = SPIFFS.open(filename, "r");

    if (!SPIFFS.exists(filename) || !file) {
        Serial.println(F("Failed to open config file"));
        return false;
    }

    bool success = deserializeConfig(file, config);

    if (!success) {
        Serial.println(F("Failed to deserialize configuration, printing current file:"));
        printFile(filename);
        Serial.println(F("^^^^^^^^^^^^^^ config file"));
        return false;
    }

    return true;
}

void saveFile(const char *filename, const Config &config) {
    File file = SPIFFS.open(filename, "w");
    if (!file) {
        Serial.println(F("Failed to create config file"));
        return;
    }

    bool success = serializeConfig(config, file);
    if (!success) {
        Serial.println(F("Failed to serialize configuration"));
    }
}

void setup() {
    Serial.begin(BAUD);

    delay(1000);
    if (!SPIFFS.begin()) {
        Serial.println(F("Failed to mount SPIFFS"));
        return;
    }

    bool loaded = loadFile(filename, config);

    if (!loaded) {
        Serial.println(F("Using default config"));
        strcpy(config.accessPoint.ssid, "MySSID");
        strcpy(config.accessPoint.passphrase, "s3cretp@$$word");
    }

    saveFile(filename, config);
    printFile(filename);

    if (!loaded)
        Serial.println(F("Restart to load the config"));
    else
        Serial.println(F("Done!"));
}

void loop() {}

config.h:

#ifndef _CONFIG_H
#define _CONFIG_H

#include <ArduinoJson.h>

struct ApConfig
{
    char ssid[32];
    char passphrase[64];

    void load(JsonObjectConst);
    void save(JsonObject) const;
};

struct Config
{
    ApConfig accessPoint;

    void load(JsonObjectConst);
    void save(JsonObject) const;
};

bool serializeConfig(const Config &config, Print &dst);
bool deserializeConfig(Stream &src, Config &config);

#endif // _CONFIG_H

config.cpp:

#include "config.h"

void ApConfig::save(JsonObject obj) const {
    obj["ssid"] = ssid;
    obj["passphrase"] = passphrase;
}

void ApConfig::load(JsonObjectConst obj) {
    strlcpy(ssid, obj["ssid"] | "", sizeof(ssid));
    strlcpy(passphrase, obj["passphrase"] | "", sizeof(passphrase));
}

void Config::load(JsonObjectConst obj) {
    accessPoint.load(obj["access_point"]);
}

void Config::save(JsonObject obj) const {
    accessPoint.save(obj.createNestedObject("access_point"));
}

bool serializeConfig(const Config &config, Print &dst) {
    DynamicJsonDocument doc(512);
    JsonObject root = doc.to<JsonObject>();
    config.save(root);
    return serializeJsonPretty(doc, dst) > 0;
}

bool deserializeConfig(Stream &src, Config &config) {
    DynamicJsonDocument doc(1024);
    DeserializationError err = deserializeJson(doc, src);
    if (err)
        return false;

    config.load(doc.as<JsonObject>());
    return true;
}

platformio.ini:

[platformio]
default_envs = d1_mini

[common_env_data]
upload_speed = 460800
monitor_speed = 74880
framework = arduino
build_flags =
    -DBAUD=${common_env_data.monitor_speed}
lib_deps = ArduinoJson
build_type = release

[env:d1_mini]
upload_speed = ${common_env_data.upload_speed}
monitor_speed = ${common_env_data.monitor_speed}
framework = ${common_env_data.framework}
build_flags = ${common_env_data.build_flags}
lib_deps = ${common_env_data.lib_deps}
build_type = ${common_env_data.build_type}
platform = espressif8266
platform_packages =
    framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git
board = d1_mini
1 Like

Turns out this was a small bug in the library. Apparently I’m the only one to have hit it. :slight_smile: