Closed ushiboy closed 3 years ago
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.
BLEClient should be deleted by library after disconnecting, but i agree, try to use NimBLE, more pros than cons.
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.
BLEClient should be deleted by library after disconnecting
Oops, I forgot about this, sorry for bad info. Curious about the memory leak then.
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
For Your Information
Good approach, definitely looks like there's some bugs to stomp.
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.
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.
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.
Thanks for your advice. I will remove the guards.
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:
Debug Messages: