bblanchon / ArduinoJson

📟 JSON library for Arduino and embedded C++. Simple and efficient.
https://arduinojson.org
MIT License
6.75k stars 1.12k forks source link

ESP8266 crash on iterator #233

Closed koffienl closed 8 years ago

koffienl commented 8 years ago

I have a valid JSON containing lots of stuff, but here is the part I want to use for the iterator:

{
    "plugins": {
        "ds18b20": "enables the use of DS18B20 sensor",
        "dht": "enables the use of DHT sensor"
    }
}

I use the following code:

  DynamicJsonBuffer jsonBuffer;
  JsonObject& json = jsonBuffer.parseObject(const_cast<char*>(jsonstring.c_str()));

  if (!json.success())
  {
    Serial.println("Failed to parse config file");
  }
  else
  {
    JsonObject& plugins = json["plugins"];
    for (JsonObject::iterator it=plugins.begin(); it!=plugins.end(); ++it)
    {
      Serial.println(it->key);
      Serial.println(it->value.asString());
    }
  }

This works fine, but a few seconds after finishing this code, the ESP crashes:

ets Jan  8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x4010f000, len 1264, room 16 
tail 0
chksum 0x42
csum 0x42
~ld

Every other functions regarding json to the same json don't have this behaviour. Can someone point me where I'm wrong with this piece of code ?

bblanchon commented 8 years ago

As far as I can tell, you code contains no error, nor anything suspicious. You may have found a bug in the library.

However, I was not able to reproduce the bug. Please post a complete program

koffienl commented 8 years ago

You are right. When I use a small piece of code with the same config,json , it works without any problem. My current project is to complex to post entire code. I will dig further to find out what I'm doing wrong.

bblanchon commented 8 years ago

A common cause of crash on the ESP8266 is a stack overflow. Indeed, the stack is limited to 4KB, so if you have a big JsonBuffer (ie more than 500 bytes), you should use DynamicJsonBuffer instead of StaticJsonBuffer.

koffienl commented 8 years ago

Thanks, I'm allready using a dynamic buffer. Just to be sure : the buffer is destroid once the function where the json is used ends? I don't have to clean the buffer at the end of a function ?

bblanchon commented 8 years ago

It is destroyed as soon as it goes out of scope, like a std::vector. You don't have to do anything special, everything is handled by the destructor.

koffienl commented 8 years ago

Perhaps I'm doin something terribly wrong with the usage of your library waht causes my crash. Let me explain, in general, how I use your library in my code. I have the following functions:

I have choosen this path to eliminate multiple reads an writes to flash only to get some information from the json object.

bblanchon commented 8 years ago

It's very important that in GetVal(), you don't return a reference.

For instance don't do that:

JsonObject& GetVal() {
   DynamicJsonBuffer buf;
   return buf.parseObject(json); // <- DON'T DO THAT!
}

because it would return a reference to a destroyed object.

Please have a look at the wiki:

  1. ArduinoJson: Avoiding pitfalls
  2. ArduinoJson: FAQ
raimohanska commented 8 years ago

I also get crashes on ESP8266.

Latest problem was, when upgrading from bd0ea42 to c8448b0abf2278dc1cdd089c72f3127511348249, that when I try to send JSON messages, I get a crash (wdc reset). The code I use is like this:

void sendMeasurement(String type, float value) {
  StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
  JsonObject& message = jsonBuffer.createObject();
  message["type"] = type;
  message["value"] = value;
  send(message); 
}

I reverted to bd0ea42 and now it works.

bblanchon commented 8 years ago

@raimohanska Thanks, that information is golden! Do you think you can write a small program that reproduce the issue, so I can try it here?

Also, what is BUFFER_SIZE and do you have the same issue with DynamicJsonBuffer?

raimohanska commented 8 years ago

I don't have time now, but maybe later. BUFFER_SIZE is 200 and I haven't tried DynamicJsonBuffer.

koffienl commented 8 years ago

@bblanchon Thanks for the heads up, but in the functions I return a converted string, not the object.

I think my problem should be found in some excesive memory usage, have not lokked into it anymore yet.

raimohanska commented 8 years ago

Another thing that always causes a crash:

When I receive a message like

{"lightId":"56d1b15c56b3e20300612d33","room":"makuuhuone","light":"Valolista","type":"brightness","value":29}

I do the following first:

    StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
    readJsonLine(jsonBuffer);
    JsonObject& message = jsonBuffer.parseObject(inputBuffer);
    Serial.print("Received "); message.printTo(Serial); Serial.println();

... so far so good, I can see the message in the Serial monitor. Then I

    String type = message["type"];
    if (type == "brightness")
    {
      int brightness = message["value"];
      setBrightness(brightness);  

And BOOM. Always crashes. But If I change it to

    String type = message["type"];
    if (type == "brightness")
    {
      String str = message["value"];
      int brightness = str.toInt();
      setBrightness(brightness);  

It works like a charm. Just reporting this for now, I hope I can produce a more isolated repeatable test case for you later.

Anyway, thanks for the great library!

bblanchon commented 8 years ago

@raimohanska: this curiously look like issue #101, which was a bug in the ESP8266 core for Arduino.

See Compatibility issues: ESP8266:

There is a known bug in Arduino core for ESP8266 WiFi chip that has been fixed on August 25th 2015.

Please make sure you're using a newer version before posting a new issue. As I'm writing theses lines, you need to use the "staging" version because the "stable" version is too old.

Can you please check that your core is up to date?

raimohanska commented 8 years ago

I updated ESP8266 Arduino to version 2.1.0 and the parsing related bug just vanished.

raimohanska commented 8 years ago

..and I can now also use the MASTER version of ArduinoJson without crashing. So, all my troubles are solved with 2.1.0, which, by the way is now available as "stable".

bblanchon commented 8 years ago

@koffienl I'm closing this issue since it's stale and I don't want other users to post unrelated questions in this thread.

Please open a new issue when needed.