[Flutter Desktop Linux] sentry_init fails on fresh flutter app
Platform
Flutter Desktop Linux
Obfuscation
Disabled
Debug Info
Disabled
Doctor
[✓] Flutter (Channel stable, 3.32.4, on Ubuntu 24.04.2 LTS 6.8.0-62-generic, locale en_US.UTF-8) [170ms]
• Flutter version 3.32.4 on channel stable at ~/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 6fba2447e9 (12 days ago), 2025-06-12 19:03:56 -0700
• Engine revision 8cd19e509d
• Dart version 3.8.1
• DevTools version 2.45.1
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0) [1,183ms]
• Android SDK at ~/Android/Sdk
• Platform android-36, build-tools 35.0.0
• Java binary at: /opt/android-studio/jbr/bin/java
This is the JDK bundled with the latest Android Studio installation on this machine.
To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
• Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)
• All Android licenses accepted.
[✗] Chrome - develop for the web (Cannot find Chrome executable at google-chrome) [106ms]
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✓] Linux toolchain - develop for Linux desktop [334ms]
• Ubuntu clang version 21.0.0 (++20250624083533+8d9911e4a06c-1~exp1~20250624083644.991)
• cmake version 3.28.3
• ninja version 1.11.1.git.kitware.jobserver-1
• pkg-config version 1.8.1
• OpenGL core renderer: NVIDIA GeForce RTX 3070/PCIe/SSE2 (X11)
• OpenGL core version: 4.6.0 NVIDIA 550.144.03 (X11)
• OpenGL core shading language version: 4.60 NVIDIA (X11)
• OpenGL ES renderer: NVIDIA GeForce RTX 3070/PCIe/SSE2 (X11)
• OpenGL ES version: OpenGL ES 3.2 NVIDIA 550.144.03 (X11)
• OpenGL ES shading language version: OpenGL ES GLSL ES 3.20 (X11)
• GL_EXT_framebuffer_blit: yes (X11)
• GL_EXT_texture_format_BGRA8888: yes (X11)
[✓] Android Studio (version 2024.3) [104ms]
• Android Studio at /opt/android-studio
• Flutter plugin version 86.0.1
• Dart plugin version 243.26753.1
• android-studio-dir = /opt/android-studio
• Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)
[✓] VS Code (version unknown) [15ms]
• VS Code at /snap/code/current/usr/share/code
• Flutter extension version 3.112.0
✗ Unable to determine VS Code version.
[✓] Connected device (1 available) [88ms]
• Linux (desktop) • linux • linux-x64 • Ubuntu 24.04.2 LTS 6.8.0-62-generic
[✓] Network resources [226ms]
• All expected network resources are available.
Version
9.1.0
Steps to Reproduce
Create app from template:
flutter create -t app my-app
cd my-app
flutter pub add sentry_flutter
Modify main.dart:
Future<void> main() async {
await SentryFlutter.init((options) {
options.dsn = 'some-dsn'; // insert dsn here
options.diagnosticLevel = SentryLevel.debug;
}, appRunner: () => runApp(const MyApp()));
}
Build and run:
flutter build linux
flutter run
Expected Result
Sentry builds and launches successfully.
Actual Result
Several warnings while compiling flutter build linux, still builds though.
~/Downloads/my-app/build/linux/x64/release/_deps/sentry-native-src/external/crashpad/util/linux/thread_info.cc:22:10: warning: first argument in call to 'memset' is a pointer to non-trivially copyable type 'crashpad::ThreadContext' [-Wnontrivial-memcall]
~/Downloads/my-app/build/linux/x64/release/_deps/sentry-native-src/external/crashpad/util/linux/thread_info.cc:28:10: warning: first argument in call to 'memset' is a pointer to non-trivially copyable type 'crashpad::FloatContext' [-Wnontrivial-memcall]
/usr/bin/ld: warning: crashpad_info_note.S.o: missing .note.GNU-stack section implies executable stack
/usr/bin/ld: warning: crashpad_info_note.S.o: missing .note.GNU-stack section implies executable stack
Log messages indicating that sentry_init failed due to invalid handler_path
(com.example.fluttertest:76207): Atk-CRITICAL **: 13:58:20.973: atk_socket_embed: assertion 'plug_id != NULL' failed
[sentry] INFO using database path "~/Downloads/my-app/.sentry-native"
[sentry] DEBUG starting transport
[sentry] DEBUG starting background worker thread
[sentry] DEBUG starting backend
[sentry] DEBUG background worker thread started
[sentry] WARN unable to start crashpad backend, invalid handler_path
[sentry] WARN failed to initialize backend
[sentry] WARN `sentry_init` failed
[sentry] DEBUG shutting down transport
[sentry] DEBUG shutting down background worker thread
[sentry] DEBUG submitting task to background worker thread
[sentry] DEBUG executing task on worker thread
[sentry] DEBUG background worker thread shut down
Are you willing to submit a PR?
No
hey, it seems our native crash handler is failing to set up. It does not affect the rest of the SDK but we'll have a look.
You can disable it by setting the SENTRY_NATIVE_BACKEND env var to none or try setting it to breakpad instead.
@jefflongo would you mind checking what the value of crashpadPath is in this line when you init Sentry https://github.com/getsentry/sentry-dart/blob/e788bd4a93003174ff6134df5ac6dd50c3d8e09a/flutter/lib/src/native/c/sentry_native.dart#L80
@buenaflor I've tracked down the cause of this problem. There are two issues:
First, this code checks the app dir for the crashpad handler. For me, it resided in appDir/lib.
sentry-dart/flutter/lib/src/native/c/sentry_native.dart
So adding this line allowed it to find the crashpad handler.
'$appDir${Platform.pathSeparator}lib/crashpad_handler'
Second, the native init fails because the crashpad handler does not have execute permissions. If I chmod +x the crashpad handler everything works. However, the crashpad handler seems to get regenerated without execute permissions every time I build the app.
thanks for the in-depth research. I'll add $appDir${Platform.pathSeparator}lib/crashpad_handler to the candidates paths.
as for the permissions: @JoshuaMoelans do you know more about how to handle this? is this generally an issue in sentry-native?
cc @vaind maybe you have an idea
Flutter's SDK sentry-native integration just uses upstream CMake to build things.
@supervacuus WDYT? maybe we could/should add POST_BUILD step with chmod +x to crashpad?
I'm wondering if the problem has to do with crashpad_handler ending up in the lib folder. Guessing here without much understanding of how Flutter installs crashpad_handler, but maybe Flutter copies files into lib in such a way where permissions are not maintained. If this is the case, chmod +x in a POST_BUILD step would not help. Seems like getting crashpad_handler to end up in bin would be more likely to maintain the execute permission, given that it's a bin folder.
I think @jefflongo is right. This is not a build issue. Any toolchain should create executable binaries; doing it in the CMake build script is either too soon (because the toolchain set the executable bit correctly already, but then something else post-build or post-install modifies it) or too late (the toolchain couldn't set the executable bit, which was probably due to some filesystem restrictions, in which case the POST_BUILD step won't fix it either).
@jefflongo, could you have a look at the intermediate build output path:
<your_app>/build/linux/x64/release/_deps/sentry-native-build/crashpad_build/handler
whether the executable permission bit of the crashpad_handler is set?
I think @jefflongo is right. This is not a
CMakeissue. Any toolchain should create executable binaries; doing it in theCMakebuild script is either too soon (because the toolchain set the executable bit correctly already, but then something else post-build or post-install modifies it) or too late (the toolchain couldn't set the executable bit, which was probably due to some filesystem restrictions, in which case thePOST_BUILDstep won't fix it either).@jefflongo, could you have a look at the intermediate build output path:
<your_app>/build/linux/x64/release/_deps/sentry-native-build/crashpad_build/handlerwhether the executable permission bit of the
crashpad_handleris set?
The intermediate build has permissions 0775 (execute bit is set), the output build has permissions 0644 (execute bit is not set). This confirms that Flutter is copying the file over in a way that strips the execute permission.
sentry-dart/flutter/sentry-native/sentry-native.cmake(which is used by../linux/CmakeLists.txt) appends the crashpad handler executable tosentry_flutter_bundled_librarieslist- this list is appended to
PLUGIN_BUNDLED_LIBRARIESby the flutter-generated<your-app>/linux/flutter/generated_plugins.cmake PLUGIN_BUNDLED_LIBRARIESis set up withinstall()cmake command in<your-app>/linux/CMakeLists.txtas follows (by default when first generated by new flutter app template, however, you may have edited it manually):install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime)- I believe the former is the culprit. Although I have worked a quite a bit with cmake, somehow I've had basically zero experience with
install()configuration. However, from what I could find online, it's possible install strips permissions. There seem to be settings to preserve (or explicitly configure) permissions, see cmake docs, but I'm unfamiliar with them to know for sure.
However, from what I could find online, it's possible install strips permissions.
Yes, that is very true, and install(FILES ...) is the core of the problem.
Binaries (and executables specifically) should be installed using install(TARGETS ...) or, in cases like this one, where the targets are not part of the install project and you still want to maintain executable bits, with install(PROGRAMS ...).
Can't say how well this integrates, but maybe a second variable PLUGIN_BUNDLED_EXECUTABLES (or *_PROGRAMS) is the right choice here, then you won't have to handle permissions in the install path explicitly.
This proposal by a Flutter developer is close to what I have in mind if one wanted to fix this upstream.
I'm not really knowledgable in cmake, does that mean we have a potential way to work around this without fixing it upstream?
is this something you can take care of? @vaind
if you're busy I can also take a look
I'm not really knowledgable in cmake, does that mean we have a potential way to work around this without fixing it upstream?
While Flutter's usage of CMake install() is at the core of this issue, it boils down to the options you have inside the Flutter build environment (of which I have not enough insight).
I was able to verify that special-casing the crashpad_handler by patching <your-app>/linux/CMakeLists.txt with the following fixes the problem:
foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
if("${bundled_library}" STREQUAL "$<TARGET_FILE:crashpad_handler>")
install(PROGRAMS "${bundled_library}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
else()
install(FILES "${bundled_library}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()
endforeach()
Of course, this requires your users to modify the auto-generated build script, which is not great. When I speak of upstreaming, I mean that Flutter could provide additional lists (such as PLUGIN_BUNDLED_TARGETS and PLUGIN_BUNDLED_PROGRAMS) as an interface to this auto-generated build script, which would use the respective install command, thereby eliminating the need for special casing. I have no idea if there are better hooks available to either fix up the permissions after bundle installation or modify the build script automatically.
In that case one option for now could be to document this properly and have users patch their CMakeLists.txt
and additionally we could let our wizard patch it as well
Updated the docs for patching the user's cmakelists and the additional path to look for the crashpad handler has been added in 9.4.0
I'll add the link here in case people come directly to this issue from google: https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting/#issues-with-native-crashes-on-linux-andor-windows