Description
Hardware:
Board: WEMOS LOLIN32
Core Installation/update date: Commit c3ec91f
IDE name: Arduino IDE 1.8.6
Flash Frequency: 80Mhz
PSRAM enabled: NoUpload Speed: 921600
Computer OS: Windows 10 x64
Description:
Updating to the latest commit (c3ec91f) yesterday broke my app in a very strange way. After hours trying to figure out what's wrong, it seems that when a String object is passed in a function that uses httpclient it results in a Guru Meditation Error.
You should have no problem reproducing the issue using the following sketch:
#include <WiFi.h>
#include <HTTPClient.h>
const String APSSID = "xxxxxxx";
const String APPassphrase = "yyyyyyy";
const String unavailableString = "unavailable";
const String serverURL = "http://example.com/";
const unsigned int timeoutInSeconds = 8;
void setup() {
Serial.begin(115200);
delay(1000);
WiFi.mode(WIFI_STA);
WiFi.begin(APSSID.c_str(), APPassphrase.c_str());
Serial.print("Connecting.");
int i = 0;
while ((WiFi.status() != WL_CONNECTED) && (WiFi.status() != WL_NO_SSID_AVAIL) && (WiFi.status() != WL_CONNECT_FAILED) && (i < (timeoutInSeconds))) {
delay(1000);
Serial.print(".");
i++;
}
Serial.println();
if ((WiFi.status() == WL_CONNECTED)) {
Serial.println("Connected to the WiFi network");
Serial.println(getPayloadFromServer("nikos"));
} else {
Serial.println("Failed to connect to the WiFi network");
}
WiFi.disconnect();
}
void loop() {
}
String getPayloadFromServer(String message) {
HTTPClient http;
Serial.println("Attempting server connection.");
http.begin(serverURL);
Serial.println("Sending GET request.");
int httpCode = http.GET();
if (httpCode > 0) {
Serial.println("Server reached and responded to GET request.");
if (httpCode == HTTP_CODE_OK) {
Serial.print("Server responded with requested payload: ");
String payload = http.getString();
Serial.println(payload);
http.end();
return payload;
} else {
Serial.println("Server error: Server did not provide the requested payload.");
}
} else {
Serial.println("Server could not be reached or server did not reply to GET request.");
}
http.end();
return unavailableString;
}
Just edit APSSID and APPassphrase to your situation and this will cause a Guru Meditation Error with this trace:
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x4015e078 PS : 0x00060e30 A0 : 0x800d3130 A1 : 0x3ffb1e50
A2 : 0x3ffb1ecc A3 : 0x00000000 A4 : 0x00000013 A5 : 0x0000ff00
A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x800d4d42 A9 : 0x3ffb1e50
A10 : 0x3ffb1f00 A11 : 0x3ffb7d84 A12 : 0x000000ff A13 : 0x0000ff00
A14 : 0x00ff0000 A15 : 0xff000000 SAR : 0x00000018 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000010 LBEG : 0x400013f9 LEND : 0x4000140d LCOUNT : 0xfffffffb
Backtrace: 0x4015e078:0x3ffb1e50 0x400d312d:0x3ffb1e70 0x400d40c9:0x3ffb1e90 0x400d1bf6:0x3ffb1ec0 0x400d1d5e:0x3ffb1f60 0x4013f7cb:0x3ffb1fb0 0x4008ba0d:0x3ffb1fd0
Using ESP Exception Decoder with the above trace, I get this:
PC: 0x4015e078: HTTPClient::connected() at C:\Users\Nikos\Documents\Arduino\hardware\espressif\esp32\libraries\HTTPClient\src\HTTPClient.cpp line 381
EXCVADDR: 0x00000010
Decoding stack results
0x4015e078: HTTPClient::connected() at C:\Users\Nikos\Documents\Arduino\hardware\espressif\esp32\libraries\HTTPClient\src\HTTPClient.cpp line 381
0x400d312d: HTTPClient::disconnect() at C:\Users\Nikos\Documents\Arduino\hardware\espressif\esp32\libraries\HTTPClient\src\HTTPClient.cpp line 347
0x400d40c9: HTTPClient::begin(String) at C:\Users\Nikos\Documents\Arduino\hardware\espressif\esp32\libraries\HTTPClient\src\HTTPClient.cpp line 336
0x400d1bf6: getPayloadFromServer(String) (C:\Users\Nikos\OneDrive\Workspace\Electronics\Projects\TimeSquare2\Code\DeviceBeforeVersioning\LOLIN32 at ESP32)\HelpingScripts\BasicHttpClientMod/BasicHttpClientMod.ino line 40
0x400d1d5e: setup() (C:\Users\Nikos\OneDrive\Workspace\Electronics\Projects\TimeSquare2\Code\DeviceBeforeVersioning\LOLIN32 at ESP32)\HelpingScripts\BasicHttpClientMod/BasicHttpClientMod.ino line 25
0x4013f7cb: loopTask(void*) at C:\Users\Nikos\Documents\Arduino\hardware\espressif\esp32\cores\esp32\main.cpp line 15
0x4008ba0d: vPortTaskWrapper at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/port.c line 141
Now... somehow this problem doesn't happen if the String type parameter is removed from the getPayloadFromServer function. Allow me to offer the same sketch with only two changes in two lines to reflect the parameter removal from the getPayloadFromServer function:
#include <WiFi.h>
#include <HTTPClient.h>
const String APSSID = "xxxxxxx";
const String APPassphrase = "yyyyyyy";
const String unavailableString = "unavailable";
const String serverURL = "http://example.com/";
const unsigned int timeoutInSeconds = 8;
void setup() {
Serial.begin(115200);
delay(1000);
WiFi.mode(WIFI_STA);
WiFi.begin(APSSID.c_str(), APPassphrase.c_str());
Serial.print("Connecting.");
int i = 0;
while ((WiFi.status() != WL_CONNECTED) && (WiFi.status() != WL_NO_SSID_AVAIL) && (WiFi.status() != WL_CONNECT_FAILED) && (i < (timeoutInSeconds))) {
delay(1000);
Serial.print(".");
i++;
}
Serial.println();
if ((WiFi.status() == WL_CONNECTED)) {
Serial.println("Connected to the WiFi network");
Serial.println(getPayloadFromServer());
} else {
Serial.println("Failed to connect to the WiFi network");
}
WiFi.disconnect();
}
void loop() {
}
String getPayloadFromServer() {
HTTPClient http;
Serial.println("Attempting server connection.");
http.begin(serverURL);
Serial.println("Sending GET request.");
int httpCode = http.GET();
if (httpCode > 0) {
Serial.println("Server reached and responded to GET request.");
if (httpCode == HTTP_CODE_OK) {
Serial.print("Server responded with requested payload: ");
String payload = http.getString();
Serial.println(payload);
http.end();
return payload;
} else {
Serial.println("Server error: Server did not provide the requested payload.");
}
} else {
Serial.println("Server could not be reached or server did not reply to GET request.");
}
http.end();
return unavailableString;
}
This only changes lines 25 and 36 from the previous sketch and it executes fine!
Another way to avoid the issue is to fallback to commit b70737d, right before httpclient lib was updated to 1.2.
Can anybody offer any possible explanation why this happens?
I hope it's clear that I'm not looking for workarounds. In the above example sketch passing the String object as a parameter is useless (the message variable is not even used anywhere in the function). But in my full app I really need to pass a String object to the function. I am well aware that there are other ways to access a piece of text from the function (setting a global var, using char arrays etc).
I really can't understand how passing a String object that is not even used affects httpclient...
Thanks