NodeMCU crashes while Json Parsing

Hello,

I'm trying to run a sketch for a LED Matrix Display on my NodeMCU.
Most parts - also the Wifi connections - are working fine; but the following function "void displayWeatherData()" causes a loop and crashes the ESP.

void displayWeatherData() {
  if (ow_APIKEY == "")
    return;

  static bool ow_current = true;
  String url;
  String result;
  WiFiClient client;

  if (!client.connect(ow_servername, ow_port))
    return;

  String cityID = ow_cityIDs[ow_cityIDLoop];

  if (ow_current)                               // get current weather check weather properties at https://openweathermap.org/current
    url = "/data/2.5/weather?id=";
  else                                          // get forecast check properties forecasts at https://openweathermap.org/forecast5
    url = "/data/2.5/forecast?id=";

  url = url + cityID + "&units=metric&cnt=1&lang=" + ow_language + "&APPID=" + ow_APIKEY;
  client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + ow_servername + "\r\n" + "Connection: close\r\n\r\n");

#ifdef DEBUG
  Serial.println(url);
#endif

  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 1000) {
      client.stop();
      return;
    }
  }

  result = "";
  while (client.available())
    result = client.readStringUntil('\r');

  client.stop();

  if (!ow_current) {
    result.replace('[', ' ');
    result.replace(']', ' ');
  }
  
#ifdef DEBUG
  Serial.println(result);
#endif
  delay(50);
  char jsonArray [result.length() + 1];
  result.toCharArray(jsonArray, sizeof(jsonArray));
  jsonArray[result.length() + 1] = '\0';

  StaticJsonBuffer<1024> json_buf;
  JsonObject &root = json_buf.parseObject(jsonArray);

  if (!root.success())
    strcpy(pd_message2, msgOpenweatherFailed);

  else {
    if (ow_current) {
      String wcit = root["name"];
      String wdes = root["weather"][0]["description"];
      float  wtem = root["main"]["temp"];
      float  whum = root["main"]["humidity"];
      float  wclo = root["clouds"]["all"];
      float  wrai = root["rain"]["3h"];
      float  wwsp = root["wind"]["speed"];
      int    wwde = root["wind"]["deg"];

      snprintf(pd_message2, sizeof(pd_message2), "%s %s : %s, %s %2.1f %c  %s %3.0f%%  %s %3.0f%%  %s %3.1f mm  %s %2.0f m/s %s", 
        msgCurrentWeather, wcit.c_str(), wdes.c_str(), msgTemp, wtem, degCascii, msgHumidity, whum, msgClouds, wclo, msgRain, wrai, msgWind, wwsp, getWindDirection(wwde).c_str());
    } else {
      String wcit = root["city"]["name"];
      String wdes = root["list"]["weather"]["description"];
      float  wtmi = root["list"]["main"]["temp_min"];
      float  wtma = root["list"]["main"]["temp_max"];
      float  whum = root["list"]["main"]["humidity"];
      float  wclo = root["list"]["clouds"]["all"];
      float  wrai = root["list"]["rain"]["3h"];
      float  wwsp = root["list"]["wind"]["speed"];
      int    wwde = root["list"]["wind"]["deg"];

      snprintf(pd_message2, sizeof(pd_message2), "%s %s : %s, %s %2.1f %c - %2.1f %c  %s %3.0f%%  %s %3.0f%%  %s %3.1f mm  %s %2.0f m/s %s", 
        msgForecast, wcit.c_str(), wdes.c_str(), msgTemp, wtmi, degCascii, wtma, degCascii, msgHumidity, whum, msgClouds, wclo, msgRain, wrai, msgWind, wwsp, getWindDirection(wwde).c_str());
    }
  }



#ifdef DEBUG
  Serial.println(pd_message2);
#endif

  ow_cityIDLoop = (++ow_cityIDLoop) % FN_ARRAY_SIZE(ow_cityIDs);

  if (ow_cityIDLoop == 0)                       // after a loop of all cities, toggle between current weather/forecasts
    ow_current = !ow_current;
}

I think i figured out the problem occurs when parsing data with Json starts.
The connection to the host is established, I get a response, but this process of connecting and responding repeats until the device crashes and restarts.

Exception message is (28). Using the ESP-Detection decoder, I get the follwing result:

Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
Decoding 46 results
0x4021f996: ets_vsnprintf at ?? line ?
0x401073a8: snprintf at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/libc_replacements.c line 342
0x40203b4d: displayWeatherData() at C:\Users\Isabel\Documents\Arduino\Test und Beispielprogramme\Parola Displays\Test_ES-Mix/Test_ES-Mix.ino line 601
0x40101e3a: pp_post at ?? line ?
0x40105117: lmacRxDone at ?? line ?
0x40102b4d: trc_NeedRTS at ?? line ?
0x40102cdc: trc_NeedRTS at ?? line ?
0x4010311a: wDev_ProcessFiq at ?? line ?
0x40102eb4: wDev_ProcessFiq at ?? line ?
0x402139b7: ieee80211_send_nulldata at ?? line ?
0x4021319b: ieee80211_output_pbuf at ?? line ?
0x4020c18e: pp_attach at ?? line ?
0x4020c29a: pp_attach at ?? line ?
0x40101e3a: pp_post at ?? line ?
0x4020b5df: ppTxPkt at ?? line ?
0x4021334c: ieee80211_output_pbuf at ?? line ?
0x4020c13b: pp_attach at ?? line ?
0x4020c18e: pp_attach at ?? line ?
0x4020c29a: pp_attach at ?? line ?
0x40101e3a: pp_post at ?? line ?
0x4020b5df: ppTxPkt at ?? line ?
0x4021334c: ieee80211_output_pbuf at ?? line ?
0x4022ae4a: etharp_query at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/netif/etharp.c line 1139
0x4022aa5c: etharp_send_ip at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/netif/etharp.c line 435
0x4022afbd: etharp_output at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/netif/etharp.c line 999
0x402153e2: scan_pm_channel_op_cb at ?? line ?
0x40215349: scan_start at ?? line ?
0x4022ad41: etharp_output_to_arp_index at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/netif/etharp.c line 890
0x4021587c: scan_clear_channles at ?? line ?
0x4010053d: _umm_realloc at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1491
:  (inlined by) realloc at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1709
0x4022bef0: ip_output_if_opt at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/core/ipv4/ip.c line 780
0x4010053d: _umm_realloc at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1491
:  (inlined by) realloc at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1709
0x40208fab: String::reserve(unsigned int) at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.cpp line 623
0x40208f5c: String::changeBuffer(unsigned int) at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.cpp line 623
0x40208fab: String::reserve(unsigned int) at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.cpp line 623
0x4010020c: _umm_free at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1287
0x4010068c: free at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1733
0x4021fa06: ets_vsprintf at ?? line ?
0x40208efc: String::~String() at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.cpp line 623
0x4010020c: _umm_free at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1287
0x40202344: displayDateShort() at C:\Users\Isabel\Documents\Arduino\Test und Beispielprogramme\Parola Displays\Test_ES-Mix/Test_ES-Mix.ino line 505
0x40203e04: loop at C:\Users\Isabel\Documents\Arduino\Test und Beispielprogramme\Parola Displays\Test_ES-Mix/Test_ES-Mix.ino line 685
0x402093fc: loop_wrapper at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_main.cpp line 56
0x40100718: cont_norm at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/cont.S line 109

I'm far from being an expert and so I don't know how to understand the exception messages correctly. And I have no idea what could cause the loop in this function.

I have spent many many hours on this issue - without success; so any help would be much appreciated!

Through initial google searches, this exception is caused either by referencing invalid memory location or failing to allocate the requested memory.

String cityID = ow_cityIDs[ow_cityIDLoop];

Try to print out "ow_cityIDLoop" to verify valid value.

Maybe the size of your json buffer is too small :

StaticJsonBuffer<1024> json_buf;

If (as I guess) you use the arduinojson library, then you should try the assistant which will give you the best parameter set

  char jsonArray [result.length() + 1];
  result.toCharArray(jsonArray, sizeof(jsonArray));
  jsonArray[result.length() + 1] = '\0';

This writes past the end of the array, which will crash an ESP.

I think that third line should be just:
jsonArray[result.length()] = '\0';

Thank you!

"ow_ cityIDLoop" works fine. I think the error occurs later.

Yes, I use the Json Lib. I' ll try it with the assistant an will report.
The strange thing is: This code should be ok, it's taken from a well running Esp32 project I found in the web.
I see no reason, why it shouldn't work on my Esp8266. As said before, all other WiFi functions run fine.

GypsumFantastic:

  char jsonArray [result.length() + 1];

result.toCharArray(jsonArray, sizeof(jsonArray));
  jsonArray[result.length() + 1] = '\0';




This writes past the end of the array, which will crash an ESP.

I think that third line should be just:
jsonArray[result.length()] = '\0';

Thank you.
I tried your code, but the device crashes anyway.
The really strange thing is: I get another Error Message (No.3), even if I retry it with my code version.
Exception Decoder shows:

Exception 3: LoadStoreError: Processor internal physical address or data error during load or store
Decoding 37 results
0x4021f9bf: ets_vsnprintf at ?? line ?
0x4021f9a6: ets_vsnprintf at ?? line ?
0x401073a8: snprintf at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/libc_replacements.c line 342
0x40203b5d: displayWeatherData() at C:\Users\Isabel\Documents\Arduino\Test und Beispielprogramme\Parola Displays\Test_ES-Mix/Test_ES-Mix.ino line 601
0x40102eb4: wDev_ProcessFiq at ?? line ?
0x4020c19e: pp_attach at ?? line ?
0x4020c2aa: pp_attach at ?? line ?
0x40101e3a: pp_post at ?? line ?
0x4020b5ef: ppTxPkt at ?? line ?
0x4021335c: ieee80211_output_pbuf at ?? line ?
0x4022ae5a: etharp_query at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/netif/etharp.c line 1139
0x4022aa6c: etharp_send_ip at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/netif/etharp.c line 435
0x4022afcd: etharp_output at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/netif/etharp.c line 999
0x402153f2: scan_pm_channel_op_cb at ?? line ?
0x40215359: scan_start at ?? line ?
0x4022ad51: etharp_output_to_arp_index at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/netif/etharp.c line 890
0x4021588c: scan_clear_channles at ?? line ?
0x4010053d: _umm_realloc at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1491
:  (inlined by) realloc at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1709
0x4022bf00: ip_output_if_opt at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/core/ipv4/ip.c line 780
0x4010053d: _umm_realloc at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1491
:  (inlined by) realloc at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1709
0x40208fbb: String::reserve(unsigned int) at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.cpp line 623
0x40208f6c: String::changeBuffer(unsigned int) at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.cpp line 623
0x40208fbb: String::reserve(unsigned int) at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.cpp line 623
0x4010020c: _umm_free at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1287
0x4010068c: free at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1733
0x4021fa16: ets_vsprintf at ?? line ?
0x40208f0c: String::~String() at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.cpp line 623
0x4010020c: _umm_free at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1287
0x40202344: displayDateShort() at C:\Users\Isabel\Documents\Arduino\Test und Beispielprogramme\Parola Displays\Test_ES-Mix/Test_ES-Mix.ino line 505
0x40203e14: loop at C:\Users\Isabel\Documents\Arduino\Test und Beispielprogramme\Parola Displays\Test_ES-Mix/Test_ES-Mix.ino line 685
0x4020940c: loop_wrapper at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_main.cpp line 56
0x40100718: cont_norm at C:\Users\Isabel\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/cont.S line 109

The last thing the serial monitor shows before crashing is:

{"coord":{"lon":8.33,"lat":48.8},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"base":"stations","main":{"temp":10.88,"pressure":1021,"humidity":76,"temp_min":8.33,"temp_max":13},"visibility":10000,"wind":{"speed":3.1,"deg":230},"clouds":{"all":75},"dt":1570096836,"sys":{"type":1,"id":1314,"message":0.0071,"country":"DE","sunrise":1570080496,"sunset":1570122193},"timezone":7200,"id":2923362,"name":"Gaggenau","cod":200}

You are making it hard to spot the error since the code is partial and some declarations are missing. Your issue may be that your are accessing a JSON object / field which does not exist.

1: float  wtma = root["list"]["main"]["temp_max"]
2: snprintf(pd_message2, ..);
  1. If "root.list.main.temp_max" does not exist, you will cause an error.
  2. Where is "pd_message2" declared and is it large enough to hold the result?

You should also mind the answer in #3 since the answer fixes a bug for you.

const char BUFLEN = 10;
char buf[BUFLEN + 1]; //Size = 11, valid indicies = 0..10
buf[BUFLEN + 1] = 0; //Access element 11 = out of bounds!

Finally I got it running.

I had made a mistake outside of this function and - obviously - wasn't able any more to recognize this after having spent hours and hours in front of my laptop. I paused my project for some days - and found the wrong code after that...

Thanks to all for their friendly help!