Finding memory leaks in Flutter applications

Aug 22, 2023

Sérgio Martins

cd blog-flutter-leak-santizer/flutter_leak/
export EXTRA_GEN_SNAPSHOT_OPTIONS=--no-strip
flutter build linux --release
file ./build/linux/x64/release/bundle/lib/libapp.so # Confirm it's not stripped
# Usually unneeded as it's the default on Linux, but not on all platforms, so please do it just in case:
export ASAN_OPTIONS=detect_leaks=1 
./build/linux/x64/release/bundle/flutter_leak
Direct leak of 23 byte(s) in 1 object(s) allocated from:
    #0 0x55a6dab7eec9 in malloc (build/linux/x64/release/bundle/flutter_leak+0xd9ec9) (BuildId: 05ef2556bb59b33549f8c962343474459a21e821)
    #1 0x7f3490072a3c in FfiTrampoline_posixMalloc dart:ffi
    #2 0x7f34900729df in FfiTrampoline_posixMalloc dart:ffi
    #3 0x7f3490072688 in MallocAllocator.allocate package:ffi/src/allocation.dart:65
    #4 0x7f34900723cc in StringUtf8Pointer.toNativeUtf8 package:ffi/src/utf8.dart
    #5 0x7f349007234a in _MyHomePageState._incrementCounter.<anonymous closure> package:flutter_leak/main.dart:69
    #6 0x7f34900265d2 in State.setState package:flutter/src/widgets/framework.dart:1139
    #7 0x7f349007230c in _MyHomePageState._incrementCounter package:flutter_leak/main.dart:62
    #8 0x7f34900722b2 in _MyHomePageState._incrementCounter package:flutter_leak/main.dart:61
    #9 0x7f3490065298 in _InkResponseState.handleTap package:flutter/src/material/ink_well.dart:1154
add_compile_options(-fsanitize=address -fno-omit-frame-pointer)
add_link_options(-fsanitize=address -fno-omit-frame-pointer)
cd blog-flutter-leak-santizer/dart_leak/
gcc mylib.c -shared -g -fPIC -o mylib.so -Wno-unused-result
dart pub get
dart compile aot-snapshot main.dart
dartaotruntime main.aot
LD_PRELOAD=/usr/lib/libasan.so dartaotruntime main.aot
==133278==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 100 byte(s) in 1 object(s) allocated from:
    #0 0x55de7714203e in __interceptor_malloc (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0xad203e)
    #1 0x7fa2bcb06116 in createCLeak /blog-lsan/dart_leak/mylib.c:3:22
    #2 0x7fa2ba7f7c2d in FfiTrampoline_createLeak2 dart:ffi
    #3 0x7fa2ba7f7bd0 in FfiTrampoline_createLeak2 dart:ffi
    #4 0x7fa2ba7f7b71 in createLeak2 file:///blog-lsan/dart_leak/main.dart:21
    #5 0x7fa2ba7f7abf in createLeaks file:///blog-lsan/dart_leak/main.dart:26
    #6 0x7fa2ba7f7a8e in main file:///blog-lsan/dart_leak/main.dart:30
    #7 0x7fa2ba7f7a8e in main file:///blog-lsan/dart_leak/main.dart
    #8 0x7fa2ba7f8d2f in _Closure.call dart:core-patch/function.dart
    #9 0x7fa2ba75dbc5 in _delayEntrypointInvocation.<anonymous closure> dart:isolate-patch/isolate_patch.dart:289
    #10 0x7fa2ba7f8d2f in _Closure.call dart:core-patch/function.dart
    #11 0x7fa2ba79828c in _RawReceivePort._handleMessage dart:isolate-patch/isolate_patch.dart:184
    #12 0x7fa2ba728a4a in stub InvokeDartCode (/blog-lsan/dart_leak/main.aot+0xe0a4a) (BuildId: b44fdaafe233826999d93fb8af8b13d3)
    #13 0x55de77799553 in dart::DartEntry::InvokeFunction(dart::Function const&, dart::Array const&, dart::Array const&) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x1129553)
    #14 0x55de777990b3 in dart::DartEntry::InvokeFunction(dart::Function const&, dart::Array const&) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x11290b3)
    #15 0x55de777a3106 in dart::DartLibraryCalls::HandleMessage(long, dart::Instance const&) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x1133106)
    #16 0x55de7782ac42 in dart::IsolateMessageHandler::HandleMessage(std::__2::unique_ptr<dart::Message, std::__2::default_delete<dart::Message>>) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x11bac42)
    #17 0x55de7786baee in dart::MessageHandler::HandleMessages(dart::MonitorLocker*, bool, bool) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x11fbaee)
    #18 0x55de7786ed6f in dart::MessageHandler::TaskCallback() (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x11fed6f)
    #19 0x55de7787399d  (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x120399d)
    #20 0x55de77e9fbdb in dart::ThreadPool::WorkerLoop(dart::ThreadPool::Worker*) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x182fbdb)
    #21 0x55de77ea20a5 in dart::ThreadPool::Worker::Main(unsigned long) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x18320a5)
    #22 0x55de77c633d4  (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x15f33d4)
    #23 0x7fa2bd5a744a  (/usr/lib/libc.so.6+0x8744a) (BuildId: 2f005a79cd1a8e385972f5a102f16adba414d75e)

Direct leak of 12 byte(s) in 1 object(s) allocated from:
    #0 0x55de7714203e in __interceptor_malloc (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0xad203e)
    #1 0x7fa2ba7c4130 in FfiTrampoline_posixMalloc dart:ffi
    #2 0x7fa2ba7c40d3 in FfiTrampoline_posixMalloc dart:ffi
    #3 0x7fa2ba7c3e3a in _MallocAllocator.allocate package:ffi/src/allocation.dart:63
    #4 0x7fa2ba7c2b53 in Utf8Codec.encode dart:convert/utf.dart
    #5 0x7fa2ba7c2b53 in StringUtf8Pointer.toNativeUtf8 package:ffi/src/utf8.dart:82
    #6 0x7fa2ba7f7aba in createLeak1 file:///blog-lsan/dart_leak/main.dart:9
    #7 0x7fa2ba7f7aba in createLeaks file:///blog-lsan/dart_leak/main.dart:25
    #8 0x7fa2ba7f7a8e in main file:///blog-lsan/dart_leak/main.dart:30
    #9 0x7fa2ba7f7a8e in main file:///blog-lsan/dart_leak/main.dart
    #10 0x7fa2ba7f8d2f in _Closure.call dart:core-patch/function.dart
    #11 0x7fa2ba75dbc5 in _delayEntrypointInvocation.<anonymous closure> dart:isolate-patch/isolate_patch.dart:289
    #12 0x7fa2ba7f8d2f in _Closure.call dart:core-patch/function.dart
    #13 0x7fa2ba79828c in _RawReceivePort._handleMessage dart:isolate-patch/isolate_patch.dart:184
    #14 0x7fa2ba728a4a in stub InvokeDartCode (/blog-lsan/dart_leak/main.aot+0xe0a4a) (BuildId: b44fdaafe233826999d93fb8af8b13d3)
    #15 0x55de77799553 in dart::DartEntry::InvokeFunction(dart::Function const&, dart::Array const&, dart::Array const&) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x1129553)
    #16 0x55de777990b3 in dart::DartEntry::InvokeFunction(dart::Function const&, dart::Array const&) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x11290b3)
    #17 0x55de777a3106 in dart::DartLibraryCalls::HandleMessage(long, dart::Instance const&) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x1133106)
    #18 0x55de7782ac42 in dart::IsolateMessageHandler::HandleMessage(std::__2::unique_ptr<dart::Message, std::__2::default_delete<dart::Message>>) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x11bac42)
    #19 0x55de7786baee in dart::MessageHandler::HandleMessages(dart::MonitorLocker*, bool, bool) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x11fbaee)
    #20 0x55de7786ed6f in dart::MessageHandler::TaskCallback() (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x11fed6f)
    #21 0x55de7787399d  (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x120399d)
    #22 0x55de77e9fbdb in dart::ThreadPool::WorkerLoop(dart::ThreadPool::Worker*) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x182fbdb)
    #23 0x55de77ea20a5 in dart::ThreadPool::Worker::Main(unsigned long) (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x18320a5)
    #24 0x55de77c633d4  (/dart/dart-sdk/sdk/out/DebugASANX64/dart-sdk/bin/dartaotruntime+0x15f33d4)
    #25 0x7fa2bd5a744a  (/usr/lib/libc.so.6+0x8744a) (BuildId: 2f005a79cd1a8e385972f5a102f16adba414d75e)

SUMMARY: AddressSanitizer: 112 byte(s) leaked in 2 allocation(s).

Leave a Comment

Your Email address will not be published