-
Notifications
You must be signed in to change notification settings - Fork 222
Bugfix: memory leak caused by variables not being deleted in end() #237
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
Conversation
buffcode
commented
May 20, 2022
This will crash the board on Arduino Uno Wifi Rev2. At first I thought it worked because the memory was freed, but it was only because the board resets and starts all over (observable by logging something in setup
).
It does not reset in the current master
, but instead will eat memory
Minimal reproduction sketch
#include <MemoryUsage.h>
#include <ArduinoBLE.h>
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("===================");
Serial.println("Setup, you should only see this once");
Serial.println("===================");
}
void loop() {
// begin initialization
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
while (1);
}
// start scanning for peripheral
Serial.println("starting Bluetooth® Low Energy scan");
Serial.print("Free memory: ");
Serial.println(mu_freeRam());
BLE.scan();
BLE.stopScan();
// crashes here
Serial.println("BLE.end");
BLE.end();
}
Output with this PR:
09:00:58.238 -> ===================
09:00:58.272 -> Setup, you should only see this once
09:00:58.306 -> ===================
09:00:59.228 -> starting Bluetooth® Low Energy scan
09:00:59.262 -> Free memory: 4587
09:00:59.296 -> BLE.end
09:00:59.296 -> ⸮==================
09:00:59.330 -> Setup, you should only see this once
09:00:59.364 -> ===================
09:01:00.286 -> starting Bluetooth® Low Energy scan
09:01:00.320 -> Free memory: 4587
09:01:00.320 -> BLE.end
09:01:00.353 -> ===================
09:01:00.387 -> Setup, you should only see this once
09:01:00.422 -> ===================
Output in `master`:
09:02:10.105 -> ===================
09:02:10.105 -> Setup, you should only see this once
09:02:10.171 -> ===================
09:02:11.060 -> starting Bluetooth® Low Energy scan
09:02:11.129 -> Free memory: 4587
09:02:11.129 -> BLE.end
09:02:12.052 -> starting Bluetooth® Low Energy scan
09:02:12.086 -> Free memory: 4271
09:02:12.120 -> BLE.end
09:02:13.042 -> starting Bluetooth® Low Energy scan
09:02:13.076 -> Free memory: 3955
09:02:13.110 -> BLE.end
09:02:14.031 -> starting Bluetooth® Low Energy scan
09:02:14.066 -> Free memory: 3639
09:02:14.100 -> BLE.end
09:02:15.021 -> starting Bluetooth® Low Energy scan
09:02:15.055 -> Free memory: 3323
09:02:15.055 -> BLE.end
483e70d
to
afccc49
Compare
Hi @buffcode ,
I retested this branch (with a couple of patches on top) with a slight modification of your code on all the boards currently supported by the library.
Everything looks ok, no leaks and no reboots; here's the code I used if you want to try replicate in your setup
#ifdef __MBED__ #include <mbed.h> #include <mbed_mem_trace.h> #else #include <MemoryFree.h> #endif #include <ArduinoBLE.h> #ifdef __MBED__ REDIRECT_STDOUT_TO(Serial) void print_memory_info() { // allocate enough room for every thread's stack statistics int cnt = osThreadGetCount(); mbed_stats_stack_t *stats = (mbed_stats_stack_t*) malloc(cnt * sizeof(mbed_stats_stack_t)); cnt = mbed_stats_stack_get_each(stats, cnt); for (int i = 0; i < cnt; i++) { printf("Thread: 0x%lX, Stack size: %lu / %lu\r\n", stats[i].thread_id, stats[i].max_size, stats[i].reserved_size); } free(stats); // Grab the heap statistics mbed_stats_heap_t heap_stats; mbed_stats_heap_get(&heap_stats); printf("Heap size: %lu / %lu bytes\r\n", heap_stats.current_size, heap_stats.reserved_size); } #else void print_memory_info() { Serial.println(freeMemory()); } #endif void setup() { Serial.begin(9600); while (!Serial); Serial.println("==================="); Serial.println("Setup, you should only see this once"); Serial.println("==================="); } void loop() { print_memory_info(); // begin initialization if (!BLE.begin()) { Serial.println("starting Bluetooth® Low Energy module failed!"); while (1); } // start scanning for peripheral Serial.println("starting Bluetooth® Low Energy scan"); BLE.scan(); BLE.stopScan(); Serial.println("BLE.end"); BLE.end(); }
Hi @buffcode I tried release 1.3.0 and your test code above on the Artemis Redboard (uses Apollo3 chipset) and got the same crash as before. I'm running this release of the Sparkfun Apollo3 board: https://github.com/sparkfun/Arduino_Apollo3/releases/tag/v2.2.1
A couple things about my test...
- I had to comment out this line REDIRECT_STDOUT_TO(Serial) since it wouldn't compile for me
- printing out the memory info always just printed: 11:02:32.209 -> Heap size: 0 / 0 bytes. There was no printout for any running threads.
- It crashed at the same place as before (after 25 cycles of BLE.begin() followed by BLE.end())
This pull request addresses the issue described in #192 caused by variables initialized in begin() not being deleted in end(). This leads to hangs and crashes reported also in other issues.