Skip to content

Strange error from new httpclient #2092

Closed
@mouridis

Description

@mouridis

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions