NimBLEDevice::deinit() causing crash on 2.3.2
I encountered an issue with a bit of code I had not had issues with in much earlier versions of NimBLE, such as 1.3.8 for example. I have created this small sketch to cleanly demonstrate the issue I am experiencing. I am running this on an ESP32-C5-DevKitC-1 v1.2 on Arduino-ESP32 v3.3.0 with NimBLE-Arduino v2.3.2.
The goal with this sketch is to simply initialize NimBLE, prepare a scan callback method that doesn't actually do anything, then deinitialize NimBLE. In the past, this has not been an issue but on 2.3.2, it seems to cause a crash (see Serial Output below).
#include <Arduino.h>
#include <NimBLEDevice.h>
NimBLEScan* pBLEScan;
// ⚠️ Define the callback object statically
class scanCallbacks : public NimBLEScanCallbacks {
void onDiscovered(const NimBLEAdvertisedDevice* advertisedDevice) override {
// No-op
}
};
scanCallbacks bleCallback; // <-- static global, never delete
void deinitBLE() {
Serial.println("Deinitializing BLE...");
if (pBLEScan != nullptr) {
if (pBLEScan->isScanning()) {
Serial.println("Stopping BLE scan...");
pBLEScan->stop();
while (pBLEScan->isScanning()) {
delay(10);
}
}
Serial.println("Clearing results...");
pBLEScan->clearResults();
Serial.println("Unbinding callbacks...");
pBLEScan->setScanCallbacks(nullptr); // Detach only, DO NOT delete
delay(10); // Let BLE stack catch up
}
NimBLEDevice::deinit();
Serial.println("Finished deinitializing BLE");
}
void initBLE() {
NimBLEDevice::init("demo");
pBLEScan = NimBLEDevice::getScan();
pBLEScan->setScanCallbacks(&bleCallback, false); // Use address of static object
pBLEScan->setActiveScan(true);
pBLEScan->setDuplicateFilter(false);
pBLEScan->setMaxResults(0);
}
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
initBLE();
Serial.println("Init BLE complete");
delay(1000);
deinitBLE();
Serial.println("Deinit BLE complete");
}
void loop() {}
Serial Output
17:06:09.978 -> Init BLE complete
17:06:10.964 -> Deinitializing BLE...
17:06:10.964 -> Clearing scan results...
17:06:10.964 -> Releasing scan callbacks...
17:06:10.964 -> CORRUPT HEAP: Bad tail at 0x4085c834. Expected 0xbaad5678 got 0xba000000
17:06:10.964 ->
17:06:10.997 -> assert failed: multi_heap_free multi_heap_poisoning.c:279 (head != NULL)
17:06:10.997 -> Core 0 register dump:
17:06:10.997 -> MEPC : 0x408007ec RA : 0x4080dd28 SP : 0x4085ed10 GP : 0x40814c84
17:06:11.031 -> TP : 0x4085ef60 T0 : 0x37363534 T1 : 0x7271706f T2 : 0x33323130
17:06:11.031 -> S0/FP : 0x00000001 S1 : 0x4085ee88 A0 : 0x4085ed74 A1 : 0x4081694d
17:06:11.031 -> A2 : 0x00000001 A3 : 0x00000029 A4 : 0x00000001 A5 : 0x4081a000
17:06:11.064 -> A6 : 0x0000000c A7 : 0x76757473 S2 : 0x0000007f S3 : 0x4085ed68
17:06:11.064 -> S4 : 0x4085ed68 S5 : 0x4085ed74 S6 : 0x00000000 S7 : 0x00000000
17:06:11.064 -> S8 : 0x00000000 S9 : 0x00000000 S10 : 0x00000000 S11 : 0x00000000
17:06:11.064 -> T3 : 0x6e6d6c6b T4 : 0x6a696867 T5 : 0x66656463 T6 : 0x62613938
17:06:11.064 -> MSTATUS : 0x00001881 MTVEC : 0x40800003 MCAUSE : 0x00000002 MTVAL : 0x00000000
17:06:11.097 -> MHARTID : 0x00000000
17:06:11.097 ->
17:06:11.097 -> Stack memory:
17:06:11.097 -> 4085ed10: 0x00000000 0x00000000 0x4209d770 0x408127b4 0xffffffff 0x00000046 0x0000000a 0x4081694c
17:06:11.097 -> 4085ed30: 0x4085eda0 0x00000018 0x40827858 0x00393732 0xffffffff 0x40816934 0x4209d770 0x40816dd0
17:06:11.097 -> 4085ed50: 0x420952fe 0x40816944 0x4085ed3c 0x40816948 0x420952d8 0x4081694c 0x00000000 0x00000000
17:06:11.097 -> 4085ed70: 0x00000000 0x65737361 0x66207472 0x656c6961 0x6d203a64 0x69746c75 0x6165685f 0x72665f70
17:06:11.131 -> 4085ed90: 0x6d206565 0x69746c75 0x6165685f 0x6f705f70 0x6e6f7369 0x2e676e69 0x37323a63 0x68282039
17:06:11.131 -> 4085edb0: 0x20646165 0x4e203d21 0x294c4c55 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
17:06:11.131 -> 4085edd0: 0x4081a000 0x00000001 0x4085c828 0x4001db2c 0x4085ef60 0x40020d0c 0x42029cca 0x00000200
17:06:11.131 -> 4085edf0: 0x408224e8 0x00000000 0x0000001f 0x4085ee14 0x00000001 0xf7000002 0x00000000 0x40812430
17:06:11.164 -> 4085ee10: 0xfff00000 0x4085c834 0xbaad5678 0xba000000 0x4081a000 0xba000000 0xfff00000 0x00000000
17:06:11.164 -> 4085ee30: 0x00000000 0x00000000 0x00000000 0xbc0abd07 0x40860000 0x00000000 0x00000000 0x00000000
17:06:11.164 -> 4085ee50: 0x4081a000 0x4085c830 0x4085c5a0 0x408121fe 0x4081a000 0x4081a000 0x40821fa8 0x420403a6
17:06:11.164 -> 4085ee70: 0x4081a000 0x4081a000 0x4081a4b0 0x42045184 0x4081a000 0x00000000 0x206d0000 0x42030008
17:06:11.197 -> 4085ee90: 0x4081a000 0x00000000 0x206d0000 0x4204c8f8 0x4081a000 0x00000000 0x40816000 0x42029984
17:06:11.197 -> 4085eeb0: 0x4081a000 0x00000000 0x00000000 0x42013c36 0x4081a000 0x00000000 0x00000000 0x42001644
17:06:11.197 -> 4085eed0: 0x40860000 0x4081ddcc 0x4081a680 0x4002d77c 0x00000000 0x4081ddd4 0x4081a680 0x00000000
17:06:11.231 -> 4085eef0: 0x00000000 0x4081a000 0x40818000 0x4200009e 0x00000000 0x00000000 0x40818000 0x420001fe
17:06:11.231 -> 4085ef10: 0x00000000 0x00000000 0x00000000 0x4201627a 0x00000000 0x00000000 0x00000000 0x4080eb90
17:06:11.231 -> 4085ef30: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
17:06:11.231 -> 4085ef50: 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
17:06:11.264 -> 4085ef70: 0xbaad5678 0x00000168 0xabba1234 0x0000015c 0x4085edd0 0x00000621 0x40818718 0x40818718
17:06:11.264 -> 4085ef90: 0x4085ef80 0x40818710 0x00000018 0x00000000 0x00000000 0x4085ef80 0x00000000 0x00000001
17:06:11.264 -> 4085efb0: 0x4085cf70 0x706f6f6c 0x6b736154 0x00000000 0x00000000 0x4085ef60 0x00000004 0x00000000
17:06:11.264 -> 4085efd0: 0x00000001 0x00000000 0x00000000 0x00000000 0x00087b79 0x00000000 0x4081b07c 0x4081b0e4
17:06:11.297 -> 4085eff0: 0x4081b14c 0x00000000 0x00000000 0x00000001 0x00000000 0x00000000 0x00000000 0x4201ff38
17:06:11.297 -> 4085f010: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
17:06:11.297 -> 4085f030: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
17:06:11.297 -> 4085f050: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
17:06:11.331 -> 4085f070: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
17:06:11.331 -> 4085f090: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
17:06:11.331 -> 4085f0b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
17:06:11.331 -> 4085f0d0: 0x00000000 0x00000000 0x00000000 0xbaad5678 0x00000068 0xabba1234 0x0000005c 0x00000000
17:06:11.377 -> 4085f0f0: 0x4085f0ec 0x00000000 0x00000000 0x00000000 0x4085f104 0xffffffff 0x4085f104 0x4085f104
17:06:11.377 ->
17:06:11.377 ->
17:06:11.377 ->
17:06:11.377 -> ELF file SHA256: e0cfe4d84
17:06:11.377 ->
17:06:11.424 -> Rebooting...
I have tried keeping it as simple as just using NimBLEDevice::deinit() without the additional NimBLEScan cleanup calls but have experienced the same result.
Any chance you can decode that backtrace?
I don't have much experience doing that. I have only done it a few times and it was a long time ago.
Honestly, your code to deinit isn't required as the call to NimBLEDevice::deinit(); will do the same thing anyway. Try that and let me know what happens.
Yea that's what I tried first. My first attempt was the initialization function you see there followed by a simple NimBLEDevice::deinit() but it yields the same result
Okay, I'll look into it, thanks!
I am having this same issue, and it is related to the nimble_port_deinit() command on the NimBLEDevice::deinit(bool clearAll);
https://github.com/h2zero/NimBLE-Arduino/blob/5aaade087896d0da77d4e2ff821eaa2a637c3de8/src/NimBLEDevice.cpp#L1014
~probably an issue with the ESP-IDF 5.5 release used to build the Arduino-Esp32 framework, that is bound to commit cc3ac5416b46e6e9363dae357378c03b4975cfdb of https://github.com/espressif/esp-nimble/~
I am using the latest version, 2.3.4, the Stack trace related to the code above is this:
Largest Free Block: 180212 B ( 176.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
Chip Size : 8388608 B (8 MB)
Block Size : 65536 B ( 64.0 KB)
Sector Size : 4096 B ( 4.0 KB)
Page Size : 256 B ( 0.2 KB)
Bus Mode : QIO
------------------------------------------
Partitions Info:
------------------------------------------
nvs : addr: 0x00009000, size: 24.0 KB, type: DATA, subtype: NVS
app0 : addr: 0x00010000, size: 4992.0 KB, type: APP, subtype: OTA_0
spiffs : addr: 0x004F0000, size: 3072.0 KB, type: DATA, subtype: SPIFFS
coredump : addr: 0x007F0000, size: 64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
Compile Date/Time : Aug 11 2025 17:36:08
ESP-IDF Version : v5.5-1-gb66b5448e0
Arduino Version : 3.3.0
------------------------------------------
Board Info:
------------------------------------------
Arduino Board : Espressif ESP32-C5-DevKitC-1 8MB no PSRAM
Arduino Variant : pinouts
Core Debug Level : 5
Arduino Runs Core : 0
Arduino Events on : 0
Arduino USB Mode : 1
CDC On Boot : 1
============ Before Setup End ============
[ 4779][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 13 already has type USB_DM (38) with bus 0x4081fc00
#0 0x4081fc00 in ?? at C:/Users/bmorcelli/.platformio/packages/framework-arduinoespressif32/cores/esp32/HWCDC.cpp:611
[ 4779][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 14 already has type USB_DP (39) with bus 0x4081fc00
#0 0x4081fc00 in ?? at C:/Users/bmorcelli/.platformio/packages/framework-arduinoespressif32/cores/esp32/HWCDC.cpp:611
I NimBLEDevice: BLE Host Task Started
I NimBLEDevice: NimBle host synced.
Init BLE complete
Deinitializing BLE...
Clearing results...
Unbinding callbacks...
assert failed: multi_heap_free multi_heap_poisoning.c:279 (head != NULL)
Core 0 register dump:
MEPC : 0x40800e40 RA : 0x4080ee88 SP : 0x4085ec30 GP : 0x40819484
#0 0x40800e40 in panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/panic.c:483
TP : 0x4085ee80 T0 : 0x37363534 T1 : 0x7271706f T2 : 0x33323130
S0/FP : 0x00000001 S1 : 0x4085eda8 A0 : 0x4085ec94 A1 : 0x4081d0b9
A2 : 0x00000001 A3 : 0x00000029 A4 : 0x00000001 A5 : 0x40828000
A6 : 0x0000000c A7 : 0x76757473 S2 : 0x0000007f S3 : 0x4085ec88
S4 : 0x4085ec88 S5 : 0x4085ec94 S6 : 0x00000000 S7 : 0x00000000
S8 : 0x00000000 S9 : 0x00000000 S10 : 0x00000000 S11 : 0x00000000
T3 : 0x6e6d6c6b T4 : 0x6a696867 T5 : 0x66656463 T6 : 0x62613938
MSTATUS : 0x00001881 MTVEC : 0x40800003 MCAUSE : 0x00000002 MTVAL : 0x00000000
MHARTID : 0x00000000
Stack memory:
4085ec30: 0x00000000 0x00000000 0x4213e298 0x408144d8 0x30303030 0xba000000 0x4085ed40 0x4081d0b8
#0 0x408144d8 in esp_libc_include_assert_impl at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/src/assert.c:96
#1 0x4081d0b8 in __global_pointer$ at ??:?
4085ec50: 0xffffffff 0x00000046 0x40828000 0x00393732 0x4212cd54 0x4081d0a0 0x4213e298 0x4081d53c
#0 0x4081d0a0 in __global_pointer$ at ??:?
#1 0x4081d53c in __global_pointer$ at ??:?
4085ec70: 0x4212cdb6 0x4081d0b0 0x4085ec5c 0x4081d0b4 0x4212cd90 0x4081d0b8 0x00000000 0x00000000
#0 0x4081d0b0 in __global_pointer$ at ??:?
#1 0x4081d0b4 in __global_pointer$ at ??:?
#2 0x4081d0b8 in __global_pointer$ at ??:?
4085ec90: 0x00000000 0x65737361 0x66207472 0x656c6961 0x6d203a64 0x69746c75 0x6165685f 0x72665f70
4085ecb0: 0x6d206565 0x69746c75 0x6165685f 0x6f705f70 0x6e6f7369 0x2e676e69 0x37323a63 0x68282039
4085ecd0: 0x20646165 0x4e203d21 0x294c4c55 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
4085ecf0: 0x40828000 0x00000001 0x4082fd70 0x4001db2c 0x4085ee80 0x40020d0c 0x4207075a 0x00000200
#0 0x4207075a in npl_freertos_callout_deinit at ??:?
4085ed10: 0x408302b0 0x00000000 0x0000001f 0x4085ed34 0x00000001 0xf7000002 0x00000000 0x40814120
#0 0x40814120 in verify_allocated_region at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c:102
4085ed30: 0xfff00000 0x4082fd7c 0xbaad5678 0xba000000 0x40828000 0xba000000 0xfff00000 0x00000000
4085ed50: 0x00000000 0x00000000 0x00000000 0x747a959f 0x40860000 0x00000000 0x00000000 0x00000000
4085ed70: 0x40828000 0x4082fd78 0x40828260 0x40813eee 0x40828000 0x40828000 0x4082fd5c 0x4208b172
#0 0x40813eee in multi_heap_free at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c:286
#1 0x4208b172 in r_ble_ll_mem_generic_data_deinit at ??:?
4085ed90: 0x40828000 0x40828000 0x4082809c 0x4208ff50 0x40828000 0x00000000 0x206d0000 0x4207add4
#0 0x4208ff50 in r_ble_ll_scan_env_deinit at ??:?
#1 0x4207add4 in r_ble_ll_env_deinit at ??:?
4085edb0: 0x40828000 0x00000000 0x206d0000 0x420976c4 0x40828000 0x00000000 0x4081c000 0x42070414
#0 0x420976c4 in r_ble_controller_deinit at ??:?
#1 0x4081c000 in __global_pointer$ at ??:?
#2 0x42070414 in esp_bt_controller_deinit at ??:?
4085edd0: 0x40828000 0x00000000 0x00000000 0x42020670 0x40828000 0x00000000 0x00000000 0x4200cd3a
#0 0x42020670 in nimble_port_deinit at .pio/libdeps/esp32-c5/NimBLE-Arduino/src/nimble/porting/nimble/src/nimble_port.c:231
#1 0x4200cd3a in NimBLEDevice::deinit(bool) at .pio/libdeps/esp32-c5/NimBLE-Arduino/src/NimBLEDevice.cpp:1024
4085edf0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000014 0x40828000 0x40828000 0x00000000
4085ee10: 0x00000000 0x40828000 0x40820000 0x42022242 0x00000014 0x00000000 0x40820000 0x4202236a
#0 0x42022242 in deinitBLE() at src/main.cpp:544
#1 0x4202236a in setup() at src/main.cpp:567
4085ee30: 0x00000000 0x00000000 0x40828000 0x4202b6a4 0x00000000 0x00000000 0x00000000 0x40810222
#0 0x4202b6a4 in loopTask(void*) at C:/Users/bmorcelli/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:75
#1 0x40810222 in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c:258
4085ee50: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
4085ee70: 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
4085ee90: 0xbaad5678 0x00000168 0xabba1234 0x0000015c 0x4085ecf0 0x00001805 0x4082072c 0x4082072c
4085eeb0: 0x4085eea0 0x40820724 0x00000018 0x4085f228 0x4085f228 0x4085eea0 0x00000000 0x00000001
4085eed0: 0x4085ce90 0x706f6f6c 0x6b736154 0x00000000 0x00000000 0x4085ee80 0x00000005 0x00000000
4085eef0: 0x00000001 0x00000000 0x00000000 0x00000000 0x00098813 0x00000000 0x4082891c 0x40828984
4085ef10: 0x408289ec 0x00000000 0x00000000 0x00000001 0x00000000 0x00000000 0x4085f3a8 0x420361d8
#0 0x420361d8 in esp_cleanup_r at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/src/newlib_init.c:42
4085ef30: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
4085ef50: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
4085ef70: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
4085ef90: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
4085efb0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
4085efd0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
4085eff0: 0x00000000 0x00000000 0x00000000 0xbaad5678 0x00000068 0xabba1234 0x0000005c 0x00000000
4085f010: 0x4085f00c 0x00000000 0x00000000 0x00000000 0x4085f024 0xffffffff 0x4085f024 0x4085f024
ELF file SHA256: f609e5db1
Rebooting...
same here 😥
I'm experiencing the same issue on ESP32-C6 with 2.3.4, instant crash on deinit() and reboot. It happens with either value of the argument.
This appears to be an issue upstream, the backtrace indicates that when esp_bt_controller_deinit is called is when the crash occurs, which is not a function in this library. I do not have a C5 to test with I'll check with a C6.
I have confirmed the issue on an esp32c6 and also confirmed that the cause is an upstream bug as it also happens with the BLE library included in the Arduino core:
#include <BLEDevice.h>
void setup() {
BLEDevice::init("");
delay(1000);
BLEDevice::deinit();
}
void loop() {}
Not sure if I can workaround this or not.
So could potentially have to wait for an upstream fix in the esp32 core before this gets resolved?
The only workaround for now is to comment out the call to esp_bt_controller_deinit, the controller won't deinitailize so the resources will still be consumed but at least the rest of the stack will be.
Hi @h2zero
I am facing above same issue in ESP32 H2 board. When call NimBLEDevice::deinit(); crash the ESP and reboot it NimBLE lib version 2.3.6 ESP board version : 3.3.0
@keenravi-hub Unfortunately this is not fixable within this library as it is an upstream bug and will need to wait for the Arduino core to be updated.