Skip to content
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

BLE library has a memory leak. #4753

Closed
ushiboy opened this issue Jan 29, 2021 · 10 comments
Closed

BLE library has a memory leak. #4753

ushiboy opened this issue Jan 29, 2021 · 10 comments

Comments

@ushiboy
Copy link
Contributor

ushiboy commented Jan 29, 2021

Hardware:

Board: ESP32 Dev Module
Core Installation version: 1.0.5-rc6
IDE name: Arduino IDE 1.8.13
Flash Frequency: 80Mhz
PSRAM enabled: no
Upload Speed: 921600
Computer OS: Ubuntu 18.04.5 LTS

Description:

I ran the following code as a central device for BLE.
Then the free space in the heap memory gradually decreased and finally the device hung.
I used the BLE_server sample sketch for the peripherals.

Sketch:

#include "src/BLEDevice.h"

static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
static BLEUUID charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8");

uint32_t count = 0;
static boolean doConnect = false;
static boolean doScan = false;
static BLEAdvertisedDevice *myDevice;

bool connectToServer()
{
  BLEClient *pClient = BLEDevice::createClient();
  if (!pClient->connect(myDevice))
  {
    Serial.print("Failed to find our service UUID: ");
    Serial.println(serviceUUID.toString().c_str());
    return false;
  }

  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;
  }

  BLERemoteCharacteristic *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;
  }

  if (pRemoteCharacteristic->canRead())
  {
    std::string value = pRemoteCharacteristic->readValue();
    Serial.print("The characteristic value was: ");
    Serial.println(value.c_str());
  }

  pClient->disconnect();
  return true;
}

class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
  void onResult(BLEAdvertisedDevice advertisedDevice)
  {
    doScan = true;
    if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID))
    {
      BLEDevice::getScan()->stop();
      if (myDevice != nullptr)
      {
        delete myDevice;
      }
      myDevice = new BLEAdvertisedDevice(advertisedDevice);
      doConnect = true;
      doScan = false;
    }
  }
};

void setup()
{
  Serial.begin(115200);
  Serial.println("Starting Arduino BLE Client application...");
  BLEDevice::init("");
  BLEScan *pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setInterval(1349);
  pBLEScan->setWindow(449);
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5, false);
}

void loop()
{
  if (doConnect)
  {
    count++;
    Serial.printf("Count: %d\n", count);
    Serial.printf("Free Heap Size: %d\n", esp_get_free_heap_size());
    Serial.printf("System Free Heap Size: %d\n", system_get_free_heap_size());
    Serial.printf("Minimum Free Heap Size: %d\n", esp_get_minimum_free_heap_size());

    connectToServer();
    doConnect = false;
    doScan = true;
  }
  else if (doScan)
  {
    doScan = false;
    BLEDevice::getScan()->start(0);
  }

  delay(1000);
}

Debug Messages:

Count: 47
Free Heap Size: 6896
System Free Heap Size: 6896
Minimum Free Heap Size: 1812
[V][BLEDevice.cpp:60] createClient(): >> createClient
[V][BLEDevice.cpp:66] createClient(): << createClient
[V][BLEClient.cpp:96] connect(): >> connect(80:7d:3a:dc:d5:4a)
[I][BLEDevice.cpp:614] addPeerDevice(): add conn_id: 46, GATT role: client
[V][FreeRTOS.cpp:189] take(): Semaphore taking: name: RegEvt (0x3fffee78), owner: <N/A> for connect
[V][FreeRTOS.cpp:198] take(): Semaphore taken:  name: RegEvt (0x3fffee78), owner: connect
[V][FreeRTOS.cpp:63] wait(): >> wait: Semaphore waiting: name: RegEvt (0x3fffee78), owner: connect for connect
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 0
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 0
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 0
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown
[V][FreeRTOS.cpp:143] give(): Semaphore giving: name: RegEvt (0x3fffee78), owner: connect
[V][FreeRTOS.cpp:77] wait(): << wait: Semaphore released: name: RegEvt (0x3fffee78), owner: <N/A>
[V][FreeRTOS.cpp:189] take(): Semaphore taking: name: OpenEvt (0x3fffff4c), owner: <N/A> for connect
[V][FreeRTOS.cpp:198] take(): Semaphore taken:  name: OpenEvt (0x3fffff4c), owner: connect
[V][FreeRTOS.cpp:63] wait(): >> wait: Semaphore waiting: name: OpenEvt (0x3fffff4c), owner: connect for connect
@h2zero
Copy link
Contributor

h2zero commented Jan 29, 2021

Your memory leak is because you create a new BLEClient instance every time connectToServer() is called and returning without deleting the instance.
Also, if you want to save a lot of memory try using NimBLE.

@chegewara
Copy link
Contributor

BLEClient should be deleted by library after disconnecting, but i agree, try to use NimBLE, more pros than cons.

@ushiboy
Copy link
Contributor Author

ushiboy commented Jan 29, 2021

Thanks for the reply.

I fixed it to delete the client at the end of connectToServer, but now the device crashes.

bool connectToServer()
{
  BLEClient *pClient = BLEDevice::createClient();
  if (!pClient->connect(myDevice))
  {
    Serial.print("Failed to find our service UUID: ");
    Serial.println(serviceUUID.toString().c_str());
    return false;
  }

  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;
  }

  BLERemoteCharacteristic *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;
  }

  if (pRemoteCharacteristic->canRead())
  {
    std::string value = pRemoteCharacteristic->readValue();
    Serial.print("The characteristic value was: ");
    Serial.println(value.c_str());
  }

  pClient->disconnect();
  delete pClient;   // added
  return true;
}

Here is the log.

Count: 3
Free Heap Size: 138840
System Free Heap Size: 138840
Minimum Free Heap Size: 130840
[V][BLEDevice.cpp:60] createClient(): >> createClient
[V][BLEDevice.cpp:66] createClient(): << createClient
[V][BLEClient.cpp:96] connect(): >> connect(80:7d:3a:dc:d5:4a)
[I][BLEDevice.cpp:614] addPeerDevice(): add conn_id: 2, GATT role: client
[V][FreeRTOS.cpp:189] take(): Semaphore taking: name: RegEvt (0x3ffdf304), owner: <N/A> for connect
[V][FreeRTOS.cpp:198] take(): Semaphore taken:  name: RegEvt (0x3ffdf304), owner: connect
[V][FreeRTOS.cpp:63] wait(): >> wait: Semaphore waiting: name: RegEvt (0x3ffdf304), owner: connect for connect
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 0
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 0
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 0
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][FreeRTOS.cpp:143] give(): Semaphore giving: name: RegEvt (0x3ffdf304), owner: connect
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 0
[V][FreeRTOS.cpp:77] wait(): << wait: Semaphore released: name: RegEvt (0x3ffdf304), owner: <N/A>
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][FreeRTOS.cpp:189] take(): Semaphore taking: name: OpenEvt (0x3ffdd44c), owner: <N/A> for connect
[V][FreeRTOS.cpp:143] give(): Semaphore giving: name: RegEvt (0x3ffdf304), owner: <N/A>
[V][FreeRTOS.cpp:198] take(): Semaphore taken:  name: OpenEvt (0x3ffdd44c), owner: connect
[V][FreeRTOS.cpp:63] wait(): >> wait: Semaphore waiting: name: OpenEvt (0x3ffdd44c), owner: connect for connect
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 40
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 40
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 40
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 40
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 40
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 40
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 40
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 40
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 2
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 2
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 2
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][FreeRTOS.cpp:143] give(): Semaphore giving: name: OpenEvt (0x3ffdd44c), owner: connect
[V][FreeRTOS.cpp:77] wait(): << wait: Semaphore released: name: OpenEvt (0x3ffdd44c), owner: <N/A>
[V][BLEClient.cpp:131] connect(): << connect(), rc=1
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 2
[V][BLEClient.cpp:386] getService(): >> getService: uuid: 4fafc201-1fb5-459e-8fcc-c5c9c331914b
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEClient.cpp:422] getServices(): >> getServices
[V][FreeRTOS.cpp:143] give(): Semaphore giving: name: OpenEvt (0x3ffdd44c), owner: <N/A>
[V][BLEClient.cpp:71] clearServices(): >> clearServices
[V][BLEClient.cpp:78] clearServices(): << clearServices
[V][FreeRTOS.cpp:189] take(): Semaphore taking: name: SearchCmplEvt (0x3ffdd4ac), owner: <N/A> for getServices
[V][FreeRTOS.cpp:198] take(): Semaphore taken:  name: SearchCmplEvt (0x3ffdd4ac), owner: getServices
[V][FreeRTOS.cpp:63] wait(): >> wait: Semaphore waiting: name: SearchCmplEvt (0x3ffdd4ac), owner: getServices for getServices
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLERemoteService.cpp:26] BLERemoteService(): >> BLERemoteService()
[V][BLERemoteService.cpp:34] BLERemoteService(): << BLERemoteService()
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLERemoteService.cpp:26] BLERemoteService(): >> BLERemoteService()
[V][BLERemoteService.cpp:34] BLERemoteService(): << BLERemoteService()
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLERemoteService.cpp:26] BLERemoteService(): >> BLERemoteService()
[V][BLERemoteService.cpp:34] BLERemoteService(): << BLERemoteService()
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLERemoteService.cpp:26] BLERemoteService(): >> BLERemoteService()
[V][BLERemoteService.cpp:34] BLERemoteService(): << BLERemoteService()
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLERemoteService.cpp:26] BLERemoteService(): >> BLERemoteService()
[V][BLERemoteService.cpp:34] BLERemoteService(): << BLERemoteService()
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 7
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLERemoteService.cpp:26] BLERemoteService(): >> BLERemoteService()
[V][BLERemoteService.cpp:34] BLERemoteService(): << BLERemoteService()
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 6
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 6
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 6
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][FreeRTOS.cpp:143] give(): Semaphore giving: name: SearchCmplEvt (0x3ffdd4ac), owner: getServices
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 6
[V][FreeRTOS.cpp:77] wait(): << wait: Semaphore released: name: SearchCmplEvt (0x3ffdd4ac), owner: <N/A>
[V][BLEClient.cpp:439] getServices(): << getServices
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEClient.cpp:399] getService(): << getService: found the service with uuid: 4fafc201-1fb5-459e-8fcc-c5c9c331914b
[V][FreeRTOS.cpp:143] give(): Semaphore giving: name: SearchCmplEvt (0x3ffdd4ac), owner: <N/A>
[V][BLERemoteService.cpp:162] retrieveCharacteristics(): >> getCharacteristics() for service: 4fafc201-1fb5-459e-8fcc-c5c9c331914b
[D][BLERemoteService.cpp:193] retrieveCharacteristics(): Found a characteristic: Handle: 42, UUID: beb5483e-36e1-4688-b7f5-ea07361b26a8
[V][BLERemoteCharacteristic.cpp:36] BLERemoteCharacteristic(): >> BLERemoteCharacteristic: handle: 42 0x42, uuid: beb5483e-36e1-4688-b7f5-ea07361b26a8
[V][BLERemoteCharacteristic.cpp:258] retrieveDescriptors(): >> retrieveDescriptors() for characteristic: beb5483e-36e1-4688-b7f5-ea07361b26a8
[E][BLERemoteCharacteristic.cpp:282] retrieveDescriptors(): esp_ble_gattc_get_all_descr: Unknown
[V][BLERemoteCharacteristic.cpp:302] retrieveDescriptors(): << retrieveDescriptors(): Found 0 descriptors.
[V][BLERemoteCharacteristic.cpp:46] BLERemoteCharacteristic(): << BLERemoteCharacteristic
[V][BLERemoteService.cpp:209] retrieveCharacteristics(): << getCharacteristics()
[V][BLERemoteCharacteristic.cpp:417] readValue(): >> readValue(): uuid: beb5483e-36e1-4688-b7f5-ea07361b26a8, handle: 42 0x2a
[V][FreeRTOS.cpp:189] take(): Semaphore taking: name: ReadCharEvt (0x3ffdf71c), owner: <N/A> for readValue
[V][FreeRTOS.cpp:198] take(): Semaphore taken:  name: ReadCharEvt (0x3ffdf71c), owner: readValue
[V][FreeRTOS.cpp:63] wait(): >> wait: Semaphore waiting: name: ReadCharEvt (0x3ffdf71c), owner: readValue for readValue
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 3
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 3
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 3
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][FreeRTOS.cpp:143] give(): Semaphore giving: name: ReadCharEvt (0x3ffdf71c), owner: readValue
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 3
[V][FreeRTOS.cpp:77] wait(): << wait: Semaphore released: name: ReadCharEvt (0x3ffdf71c), owner: <N/A>
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLERemoteCharacteristic.cpp:445] readValue(): << readValue(): length: 21
[V][FreeRTOS.cpp:143] give(): Semaphore giving: name: ReadCharEvt (0x3ffdf71c), owner: <N/A>
[V][BLEClient.cpp:141] disconnect(): >> disconnect()
[V][BLEClient.cpp:147] disconnect(): << disconnect()
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 5
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 5
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 5
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 5
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 41
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 41
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 41
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 41
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 41
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 41
[V][BLEUtils.cpp:1283] dumpGattClientEvent(): GATT Event: Unknown
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 41
[D][BLEClient.cpp:160] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 6] ... Unknown
[V][FreeRTOS.cpp:143] give(): Semaphore giving: name: OpenEvt (0x3ffdd44c), owner: <N/A>
/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c:720 (xQueueGenericSend)- assert failed!
abort() was called at PC 0x4008d9bc on core 0

Backtrace: 0x40091498:0x3ffcdf90 0x400916c9:0x3ffcdfb0 0x4008d9bc:0x3ffcdfd0 0x400d8a5d:0x3ffce010 0x400d8a91:0x3ffce050 0x400d4529:0x3ffce070 0x400d54b9:0x3ffce120 0x40106aae:0x3ffce190 0x400ff83a:0x3ffce1e0 0x4008e089:0x3ffce210

Rebooting...

I'll refer to NimBLE.

@h2zero
Copy link
Contributor

h2zero commented Jan 29, 2021

BLEClient should be deleted by library after disconnecting

Oops, I forgot about this, sorry for bad info. Curious about the memory leak then.

@ushiboy
Copy link
Contributor Author

ushiboy commented Jan 30, 2021

I've tried different approach.

Changed the client to a global variable and delete the previous instance before create a new instance.
(It's not good enough, it still crashes occasionally)

static BLEClient *pClient;

bool connectToServer()
{
  if (pClient != nullptr)
  {
    delete pClient;
  }
  pClient = BLEDevice::createClient();
  if (!pClient->connect(myDevice))
  {
    Serial.print("Failed to find our service UUID: ");
    Serial.println(serviceUUID.toString().c_str());
    return false;
  }

  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;
  }

  BLERemoteCharacteristic *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;
  }

  if (pRemoteCharacteristic->canRead())
  {
    std::string value = pRemoteCharacteristic->readValue();
    Serial.print("The characteristic value was: ");
    Serial.println(value.c_str());
  }

  pClient->disconnect();
  return true;
}

I used the serial plotter in the Arduino IDE to plot the heap size, and it looks like this
heap-size

For Your Information

@h2zero
Copy link
Contributor

h2zero commented Jan 30, 2021

Good approach, definitely looks like there's some bugs to stomp.

@ushiboy
Copy link
Contributor Author

ushiboy commented Jan 31, 2021

The crashes that sometimes occurred with the above approach seem to have gone away after the following modification to the BLEClient destructor.

BLEClient::~BLEClient() {
	// We may have allocated service references associated with this client.  Before we are finished
	// with the client, we must release resources.
	for (auto &myPair : m_servicesMap) {
	   delete myPair.second;
	}
	m_servicesMap.clear();
	m_servicesMapByInstID.clear();  // added
} // ~BLEClient

But, the free space in the heap memory is still decreasing.

@ushiboy
Copy link
Contributor Author

ushiboy commented Feb 1, 2021

I found the cause.
The m_rawData variable was not released in the destructor of BLERemoteCharacteristic.
I made the following changes to the destructor.

BLERemoteCharacteristic::~BLERemoteCharacteristic() {
	removeDescriptors();   // Release resources for any descriptor information we may have allocated.
	if (m_rawData != nullptr)
	{
		free(m_rawData);
	}
} // ~BLERemoteCharacteristic

The graph of free heap memory space after the change is as follows.
fixed

@everslick
Copy link
Contributor

just a side note: it is perfectly legal to call free() or delete() on a nullptr, so any check that only guards one of the two calls is unnecessary at best or confusing otherwise.

@ushiboy
Copy link
Contributor Author

ushiboy commented Feb 2, 2021

Thanks for your advice.
I will remove the guards.

me-no-dev pushed a commit that referenced this issue Feb 15, 2021
* Fixed crash on delete after disconnect

* Fixed memory leak when getting characteristics

* Removed guard

Co-authored-by: ushiboy <[email protected]>
@ushiboy ushiboy closed this as completed Feb 16, 2021
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