btleplug icon indicating copy to clipboard operation
btleplug copied to clipboard

Serious memory leaks inside the winrtble backend

Open NuLL3rr0r opened this issue 7 months ago • 4 comments

Describe the bug I've produced a very minimal example to demonstrate serious memory leaks possibly from the FFI calls into/from Windows API. It could be win-rs or btelplug. But, I'll first report it here, since I am not sure.

To give a bit more context. We have a cross platform C++ app/library running on Microsoft Windows and GNU/Linux. We noticed (especially whenever we turn off the connected devices) we get noticable memory leaks. Initially we though our program or library leaks. Hopefully, we narrowed it down to the BLE code. Then, further investigation revealed it's not our C++ BLE wrapper or the Rust BLE code around the btleplug.

How are we sure? Well, we created a simple Rust library, copied the code from btleplug examples, then wrapped it inside a function called start_ble() and exposed it via Rust FFI. Then we write a C++ program calling that function. The code is attached.

Why did we do that? Well, because we could use Windows memory leak trackers like Dr Memory, Visual Leak Tracker (a header file you include in your program), or even Deleaker (a Visual Studio / Qt Creator extention). All of them report the leaks from the Rust code. Screenshots for Deleaker are attached since it has a nice GUI to demonstrate it.

Expected behavior The library should not leak memory on Windows. As Linux does not either.

Actual behavior The program leaks memory, this is an issue if we make many calls to the underlying API. The OS evantually kills the app because of this, when we run out of memory.

Additional context I've attached screenshots, a sample Rust / C++ program that you can use to confirm the leaks with any of the tools mentioned above. Also since the full binaries are over 1 GB. I'll only attach the soure files. You then can:

  1. Extract.
  2. Run cargo build to generate the FFI header and the .lib file.
  3. Open the .sln file in Visual Studio.
  4. Run.

You can obtain Deleaker with a trial license to see the leaks in Visual Studio. Also, you can obtain VLD or Dr Memory which are open source. For VLD you need some setup to include it and build. Feel free to let me know if you want to try it and I can set it up and upload another zip. Dr Memory you just drag the app into its shortcut.

Also, an XML file with all the leaks for this simple program is attached.

NuLL3rr0r avatar May 20 '25 19:05 NuLL3rr0r

The files and screenshots

minible.zip

xml-leaks.zip

Image Image Image Image Image Image Image Image

NuLL3rr0r avatar May 20 '25 19:05 NuLL3rr0r

Tried your example, I'm not seeing any leaks? There's a steady flow of allocations due to device discovery, but full deallocations once the tokio runtime in cleaned up after the timer goes up. You're saying you were able to trigger the leak with your example?

Also: Why are you using our rust library and not something C++ native like simpleble?

qdot avatar May 21 '25 02:05 qdot

Thank you for your quick response!

Well, the reason is initially we planned to gradually migrate away from C++ in our code base by trying Rust. For that, once we had the need to use integrate BLE support, we saw this as an opportunity to try Rust and evaluate it.

Well, I have not tested this example extensively, but in our code base (which is proprietary) the memory leaks. We have tested that extensively with as many tools as we could and for our FFI layer between Rust/C++ we wrote a little memory allocation/deallocation tracker and that one also confirms the memory is cleaned up.

The only report we see, is similar to the above screenshots. But, I cannot confirm whether these are false-positive or not.

Hope that helps clarify your questions. Also, if there's anything we can try to narrow it down, your suggestions are very welcome.

NuLL3rr0r avatar May 21 '25 08:05 NuLL3rr0r

Given that you're working in a complex cross language environment, unless you can provide me with a working repro, there's not much we can do for you. Memory leaks may just be memory usage that isn't being freed due to runtime handling, creating streams without proper cleanup/drops, etc... This library has at least 100s if not 1000s of users, and is currently shipping in my own product that has 10ks of users across desktop and mobile, and we haven't seen memory issues there, so we can't just go off of "there may be a problem".

qdot avatar May 21 '25 19:05 qdot