AVR + Debug mode = Assert failed
Created by: labodj
Hi, I think I have found a bug in 6.15 version, the problem doesn't occur in 6.14.1, i'm compiling with GCC 9.2.0 (https://blog.zakkemble.net/avr-gcc-builds/) using platformio and VSCode under linux 64bit for Controllino Maxi (ATmega2560).
I have this method that prepares a json to be sent:
void Serializer::serializeNetworkClick(uint8_t buttonIndex, constants::ButtonClickType clickType, bool confirm) const
{
using namespace constants;
StaticJsonDocument<JSON_OBJECT_SIZE(4)> doc;
// Write the Json
doc[JSON_PAYLOAD] = serialized(JSON_PAYLOAD_COMMAND_NETWORK_CLICK_SERIALIZED);
switch (clickType)
{
case ButtonClickType::LONG:
doc[JSON_DATA_CLICK_TYPE] = serialized(JSON_DATA_CLICK_TYPE_LONG_SERIALIZED);
break;
case ButtonClickType::SUPER_LONG:
doc[JSON_DATA_CLICK_TYPE] = serialized(JSON_DATA_CLICK_TYPE_SUPER_LONG_SERIALIZED);
break;
default:
return;
}
doc[JSON_DATA_BUTTONS_IDS] = this->device.getButton(buttonIndex)->getId();
doc[JSON_DATA_CONFIRM] = confirm;
// Send the Json
this->com->sendJson(doc);
}
Useful related code: Merged from various constants .hpp files
namespace constants
{
static constexpr const char *JSON_PAYLOAD = "p";
static constexpr const char *JSON_DATA_CLICK_TYPE = "ct";
static constexpr const char *JSON_DATA_BUTTONS_IDS = "bi";
static constexpr const char *JSON_DATA_CONFIRM = "c";
static constexpr const char *JSON_PAYLOAD_COMMAND_NETWORK_CLICK_SERIALIZED = "\"c_nc\"";
static constexpr const char *JSON_DATA_CLICK_TYPE_LONG_SERIALIZED = "\"lc\"";
static constexpr const char *JSON_DATA_CLICK_TYPE_SUPER_LONG_SERIALIZED = "\"slc\"";
enum class ButtonClickType
{
NONE,
SHORT,
LONG,
SUPER_LONG
};
} // namespace constants
from device.cpp
Clickable *Device::getButton(uint8_t buttonIndex) const
{
return this->buttons[buttonIndex]; // this->buttons is a std::vector<Clickable *>
}
from clickable.cpp
const char *Clickable::getId() const
{
return this->id; // this->id is a const char *const
}
from espcom.cpp
void EspCom::sendJson(const JsonDocument &json)
{
serializeJson(json, (*this->serial)); // this->serial is a HardwareSerial *const
DJ(json);
this->storeSentPayloadTime();
}
from debug.hpp
#define DJ(x) \
do \
{ \
serializeJson(x, Serial); \
Serial.println(); \
} while (0)
The problem is that when all 4 fields are set the program crashes at runtime. If any of these 4 fields are removed the program runs fine. I tried to use larger StaticJsonDocument without success.
At the moment I'll stay with 6.14.1 until I find a fix or a workaround.
Another unrelated question: is serialized used like the code above actually faster than passing a normal (not preformatted) static constexpr const char *? like
doc[JSON_PAYLOAD] = constants::JSON_PAYLOAD_COMMAND_NETWORK_CLICK;
namespace constants
{
static constexpr const char *JSON_PAYLOAD_COMMAND_NETWORK_CLICK = "c_nc";
} // namespace constants
EDIT: I've just tested it with GCC-9.3.0 (https://blog.zakkemble.net/avr-gcc-builds/comment-page-1/#comment-209216) with Ofast, Os, O1 and O2 optimizations and latest commit on master targeting the library on platformio wih this repo link, same problem.