Skip to content

assertion "heap != NULL && "free() target pointer is outside heap areas"" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/heap_caps.c", line 267, function: heap_caps_free abort() was called at PC 0x400e89a7 on core 1 #3417

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
simon1516 opened this issue Oct 27, 2019 · 11 comments

Comments

@simon1516
Copy link

simon1516 commented Oct 27, 2019

Good day everybody,

I'm currently having a programming problem and hope you can see something I do not currently see :-)

I did the following:

  • Two ESP32 ROOM
  • BLE examples from the Arduino IDE uploaded (1x ESP server, 1x ESP client)
  • Server sends 1xService and 6xCharacteristics (also works, checked by NRFconnect APP)
  • Client should receive this data and output it via serial.print

Unfortunately, the following happens now:
If I only read ONE value (or a characteristic) in the loop in my loop, it works.

If I read and output ALL six values ​​(or six characteristics) in the sketch in my loop, it will NOT work.

Error in Serial Monitor:

assertion "heap != NULL && "free() target pointer is outside heap areas"" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/heap_caps.c", line 267, function: heap_caps_free
abort() was called at PC 0x400e89a7 on core 1

Backtrace: 0x40091470:0x3ffc8aa0 0x400916a1:0x3ffc8ac0 0x400e89a7:0x3ffc8ae0 0x40084b1f:0x3ffc8b10 0x400850e1:0x3ffc8b30 0x4000bec7:0x3ffc8b50 0x40177b91:0x3ffc8b70 0x40178316:0x3ffc8b90 0x400d2d8e:0x3ffc8bb0 0x400d8949:0x3ffc8dc0 0x4008e089:0x3ffc8de0

Decoded Backtrace:

Decoding stack results
0x40091f40: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 155
0x40092171: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 170
0x40110aeb: __assert_func at ../../../.././newlib/libc/stdlib/assert.c line 63
0x40084b7f: heap_caps_free at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/heap_caps.c line 267
0x40085141: _free_r at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/syscalls.c line 42
0x401b7021: operator delete(void*) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/del_op.cc line 46
0x401b77be: std::__cxx11::basic_string  , std::allocator  >::_M_dispose() at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/build/build-cc-gcc-final/xtensa-esp32-elf/libstdc++-v3/include/ext/new_allocator.h line 110
0x400d292e: loop() at c:\users\simon\appdata\local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\xtensa-esp32-elf\include\c++\5.2.0\bits/basic_string.h line 544
0x400ddb3d: loopTask(void*) at C:\Users\simon\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32\main.cpp line 19
0x4008e689: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

Decoding stack results
0x40091f40: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 155
0x40092171: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 170
0x40110aeb: __assert_func at ../../../.././newlib/libc/stdlib/assert.c line 63
0x40084b7f: heap_caps_free at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/heap_caps.c line 267
0x40085141: _free_r at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/syscalls.c line 42
0x401b7021: operator delete(void*) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/del_op.cc line 46
0x401b77be: std::__cxx11::basic_string  , std::allocator  >::_M_dispose() at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/build/build-cc-gcc-final/xtensa-esp32-elf/libstdc++-v3/include/ext/new_allocator.h line 110
0x400d292e: loop() at c:\users\simon\appdata\local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\xtensa-esp32-elf\include\c++\5.2.0\bits/basic_string.h line 544
0x400ddb3d: loopTask(void*) at C:\Users\simon\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32\main.cpp line 19
0x4008e689: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

I suspect that it has something to do with the "BLERemoteCharacteristic::readValue()" function. This has already been discussed in the past (#2800). Unfortunaly, this solution went wrong for me.

This is my sketch, running on ESP32 ROOM:

#include<WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include "BLEDevice.h"

const char* ssid = "UPC226A38D";
const char* password = "neu1NEU2//";

std::string value[5];

float f_Acceleration_X = 0;
float f_Acceleration_Y = 0;
float f_Acceleration_Z = 0;
float f_Gyro_X = 0;
float f_Gyro_Y = 0;
float f_Gyro_Z = 0;




// The remote service we wish to connect to.
static BLEUUID serviceUUID("4fafc201-1fb5-459e-0001-c5c9c331914b");
// The characteristic of the remote service we are interested in.
static BLEUUID    charUUID("beb5483e-36e1-4688-0001-ea07361b26a8");
static BLEUUID    charUUID2("beb5483e-36e1-4688-0002-ea07361b26a8");
static BLEUUID    charUUID3("beb5483e-36e1-4688-0003-ea07361b26a8");
static BLEUUID    charUUID4("beb5483e-36e1-4688-0004-ea07361b26a8");
static BLEUUID    charUUID5("beb5483e-36e1-4688-0005-ea07361b26a8");
static BLEUUID    charUUID6("beb5483e-36e1-4688-0006-ea07361b26a8");

static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLERemoteCharacteristic* pRemoteCharacteristic2;
static BLERemoteCharacteristic* pRemoteCharacteristic3;
static BLERemoteCharacteristic* pRemoteCharacteristic4;
static BLERemoteCharacteristic* pRemoteCharacteristic5;
static BLERemoteCharacteristic* pRemoteCharacteristic6;
static BLEAdvertisedDevice* myDevice;

static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {
    Serial.print("Notify callback for characteristic ");
    Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
    Serial.print(" of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println((char*)pData);
}

class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pclient) {
  }

  void onDisconnect(BLEClient* pclient) {
    connected = false;
    Serial.println("onDisconnect");
  }
};

bool connectToServer() {
    Serial.print("Forming a connection to ");
    Serial.println(myDevice->getAddress().toString().c_str());
    
    BLEClient*  pClient  = BLEDevice::createClient();
    Serial.println(" - Created client");

    pClient->setClientCallbacks(new MyClientCallback());

    // Connect to the remove BLE Server.
    pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
    Serial.println(" - Connected to server");

    // Obtain a reference to the service we are after in the remote BLE server.
    BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
    if (pRemoteService == nullptr) {
      Serial.print("Failed to find our service UUID: ");
      Serial.println(serviceUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our service");


    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
    if (pRemoteCharacteristic == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic");

        // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic2 = pRemoteService->getCharacteristic(charUUID2);
    if (pRemoteCharacteristic2 == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charUUID2.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic2");

            // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic3 = pRemoteService->getCharacteristic(charUUID3);
    if (pRemoteCharacteristic3 == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charUUID3.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic3");

            // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic4 = pRemoteService->getCharacteristic(charUUID4);
    if (pRemoteCharacteristic4 == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charUUID4.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic4");

            // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic5 = pRemoteService->getCharacteristic(charUUID5);
    if (pRemoteCharacteristic5 == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charUUID5.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic5");

            // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic6 = pRemoteService->getCharacteristic(charUUID6);
    if (pRemoteCharacteristic6 == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charUUID6.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic6");

        if(pRemoteCharacteristic->canNotify()){
            pRemoteCharacteristic->registerForNotify(notifyCallback);
            Serial.print("notify1");
        }
    
      
              if(pRemoteCharacteristic2->canNotify()){
      pRemoteCharacteristic2->registerForNotify(notifyCallback);
      Serial.print("notify2");
      }
              if(pRemoteCharacteristic3->canNotify()){
      pRemoteCharacteristic3->registerForNotify(notifyCallback);
      Serial.print("notify3");
      }
              if(pRemoteCharacteristic4->canNotify()){
      pRemoteCharacteristic4->registerForNotify(notifyCallback);
      Serial.print("notify4");
      }
              if(pRemoteCharacteristic5->canNotify()){
      pRemoteCharacteristic5->registerForNotify(notifyCallback);
      Serial.print("notify5");
      }
              if(pRemoteCharacteristic6->canNotify()){
      pRemoteCharacteristic6->registerForNotify(notifyCallback);
      Serial.print("notify6");
      }

      
    connected = true;
    return true;
        
 
}
/**
 * Scan for BLE servers and find the first one that advertises the service we are looking for.
 */
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
 /**
   * Called for each advertising BLE server.
   */
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    Serial.print("BLE Advertised Device found: ");
    Serial.println(advertisedDevice.toString().c_str());

    // We have found a device, let us now see if it contains the service we are looking for.
    if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {

      BLEDevice::getScan()->stop();
      myDevice = new BLEAdvertisedDevice(advertisedDevice);
      doConnect = true;
      doScan = true;

    } // Found our server
  } // onResult
}; // MyAdvertisedDeviceCallbacks


void setup() {
  Serial.begin(115200);
  Serial.println("Starting Arduino BLE Client application...");
  BLEDevice::init("");

  // Retrieve a Scanner and set the callback we want to use to be informed when we
  // have detected a new device.  Specify that we want active scanning and start the
  // scan to run for 5 seconds.
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setInterval(1349);
  pBLEScan->setWindow(449);
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5, false);
}
// This is the Arduino main loop function.
void loop() {

  // If the flag "doConnect" is true then we have scanned for and found the desired
  // BLE Server with which we wish to connect.  Now we connect to it.  Once we are 
  // connected we set the connected flag to be true.
  if (doConnect == true) {
    if (connectToServer()) {
      Serial.println("We are now connected to the BLE Server.");
    } else {
      Serial.println("We have failed to connect to the server; there is nothin more we will do.");
    }
    doConnect = false;
  }

  // If we are connected to a peer BLE Server, update the characteristic each time we are reached
  // with the current time since boot.
  if (connected) {
   
    String newValue[5];
    
    Serial.println("Setting new characteristic value1 to \"" + String(value[0].c_str()) + "\"");
    value[0] = pRemoteCharacteristic->readValue();
    // Set the characteristic's value to be the array of bytes that is actually a string.
    pRemoteCharacteristic->writeValue(newValue[0].c_str(), newValue[0].length());

            Serial.println("Setting new characteristic value2 to \"" + String(value[1].c_str()) + "\"");
    value[1] = pRemoteCharacteristic2->readValue();
    // Set the characteristic's value to be the array of bytes that is actually a string.
    pRemoteCharacteristic2->writeValue(newValue[1].c_str(), newValue[1].length());

        Serial.println("Setting new characteristic value3 to \"" + String(value[2].c_str()) + "\"");
    value[2] = pRemoteCharacteristic3->readValue();
    // Set the characteristic's value to be the array of bytes that is actually a string.
    pRemoteCharacteristic3->writeValue(newValue[2].c_str(), newValue[2].length());

        Serial.println("Setting new characteristic value4 to \"" + String(value[3].c_str()) + "\"");
    value[3] = pRemoteCharacteristic4->readValue();
    // Set the characteristic's value to be the array of bytes that is actually a string.
    pRemoteCharacteristic4->writeValue(newValue[3].c_str(), newValue[3].length());

        Serial.println("Setting new characteristic value5 to \"" + String(value[4].c_str()) + "\"");
    value[4] = pRemoteCharacteristic5->readValue();
    // Set the characteristic's value to be the array of bytes that is actually a string.
    pRemoteCharacteristic5->writeValue(newValue[4].c_str(), newValue[4].length());

        Serial.println("Setting new characteristic value6 to \"" + String(value[5].c_str()) + "\"");
    value[5] = pRemoteCharacteristic6->readValue();
    // Set the characteristic's value to be the array of bytes that is actually a string.
    pRemoteCharacteristic6->writeValue(newValue[5].c_str(), newValue[5].length());
      
 
  }else if(doScan){
    BLEDevice::getScan()->start(0);  // this is just eample to start scan after disconnect, most likely there is better way to do it in arduino
  }
  delay(1000); // Delay a second between loops.
} // End of loop

I look forward to your tips and say thank you for your help.

greeting

Simon

@lbernstone
Copy link
Contributor

lbernstone commented Oct 27, 2019

Please follow the instructions in the ISSUE TEMPLATE to decode your backtrace and properly format your code.

@simon1516
Copy link
Author

simon1516 commented Oct 28, 2019

Please follow the instructions in the ISSUE TEMPLATE to decode your backtrace and properly format your code.

Hello lbernstone,

can youplease tell me how to insert the full code as code?

I´ve tried to Edit, but the character "" for CODE` doesn´t works. Not the entire code is shown as code :-( Just a piece of it. What I´m doing wrong?

How can I decode the backtrace?

@lbernstone
Copy link
Contributor

@simon1516
Copy link
Author

https://github.com/me-no-dev/EspExceptionDecoder
https://help.github.com/articles/creating-and-highlighting-code-blocks/

Thank you for your links. I have updated my first post. I´m sorry for the first formatting.

@simon1516
Copy link
Author

Is anyone here who can help me? :-)

@lbernstone
Copy link
Contributor

Nobody has answered b/c your code is too complicated. Cut it down to the smallest bit that shows the error. The general error is that you are trying to access a string that has been destroyed. Converting back and forth b/w char* and String (String(value[0].c_str())) cannot be helping things.

@simon1516
Copy link
Author

simon1516 commented Oct 29, 2019

Nobody has answered b/c your code is too complicated. Cut it down to the smallest bit that shows the error. The general error is that you are trying to access a string that has been destroyed. Converting back and forth b/w char* and String (String(value[0].c_str())) cannot be helping things.

Okay, thank you for this information. I changed this:

Serial.println("Setting new characteristic value1 to \"" + String(value[0].c_str()) + "\"");
    value[0] = pRemoteCharacteristic->readValue();
    // Set the characteristic's value to be the array of bytes that is actually a string.
    pRemoteCharacteristic->writeValue(newValue[0].c_str(), newValue[0].length());

to just one, easy row:

value[0] = pRemoteCharacteristic->readValue();

This works. But if I want to read all six characteristics, I get furthermore an error. I just read six instead of one value, nothing other changed.

    value[0] = pRemoteCharacteristic->readValue();
    value[1] = pRemoteCharacteristic2->readValue();
    value[2] = pRemoteCharacteristic3->readValue();
    value[3] = pRemoteCharacteristic4->readValue();
    value[4] = pRemoteCharacteristic5->readValue();
    value[5] = pRemoteCharacteristic6->readValue();

Here is the decoded backtrace result:

Decoding stack results
0x40091f40: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 155
0x40092171: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 170
0x4011062f: __assert_func at ../../../.././newlib/libc/stdlib/assert.c line 63
0x40084b7f: heap_caps_free at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/heap_caps.c line 267
0x40085141: _free_r at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/syscalls.c line 42
0x401b6a9d: operator delete(void*) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/del_op.cc line 46
0x401b723a: std::__cxx11::basic_string  , std::allocator  >::_M_dispose() at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/build/build-cc-gcc-final/xtensa-esp32-elf/libstdc++-v3/include/ext/new_allocator.h line 110
0x400d25e5: loop() at c:\users\simon\appdata\local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\xtensa-esp32-elf\include\c++\5.2.0\bits/basic_string.h line 544
0x400dd68d: loopTask(void*) at C:\Users\simon\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32\main.cpp line 19
0x4008e689: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

Could you please have a look, what´s furthermore going wrong? Thank You in advance

@stickbreaker
Copy link
Contributor

std::string value[5];
   value[0] = pRemoteCharacteristic->readValue();
    value[1] = pRemoteCharacteristic2->readValue();
    value[2] = pRemoteCharacteristic3->readValue();
    value[3] = pRemoteCharacteristic4->readValue();
    value[4] = pRemoteCharacteristic5->readValue();
    value[5] = pRemoteCharacteristic6->readValue();

Do you see any problem with this?
You allocated value[] as an array of five elements [0..4] but you you are accessing six elements [0..5].

Chuck.

@stickbreaker
Copy link
Contributor

Also, look at your decoded back trace.

Start at the end and work forwards:

0x4008e689: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

just the initial code for Arduino framework

0x400dd68d: loopTask(void*) at C:\Users\simon\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32\main.cpp line 19

The default for Arduino.

0x400d25e5: loop() at c:\users\simon\appdata\local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\xtensa-esp32-elf\include\c++\5.2.0\bits/basic_string.h line 544

The String() object code.

0x401b723a: std::__cxx11::basic_string , std::allocator >::_M_dispose() at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/build/build-cc-gcc-final/xtensa-esp32-elf/libstdc++-v3/include/ext/new_allocator.h line 110

Creating a new String() Object

0x401b6a9d: operator delete(void*) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/del_op.cc line 46

Deleting the existing object to create a new modified version.

What this looks like to me is that when you accessed the 6th element of a five element array, the String library interpreted the current memory image of the '6th' element as a pre-allocated String that needed to be recreated to hold the 'new' value you assigned. since the memory image was not a string an explosion inssued.

Chuck.

@simon1516
Copy link
Author

std::string value[5];
   value[0] = pRemoteCharacteristic->readValue();
    value[1] = pRemoteCharacteristic2->readValue();
    value[2] = pRemoteCharacteristic3->readValue();
    value[3] = pRemoteCharacteristic4->readValue();
    value[4] = pRemoteCharacteristic5->readValue();
    value[5] = pRemoteCharacteristic6->readValue();

Do you see any problem with this?
You allocated value[] as an array of five elements [0..4] but you you are accessing six elements [0..5].

Chuck.

that was it! It work´s! Thank you both so much! :-)

@MedAmineDALAA
Copy link

This error refers to a depassement of an array elements or capacity of a memory size in general ! please verify your arrays sizes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants