fl_crashpad 1.0.2
fl_crashpad: ^1.0.2 copied to clipboard
Native crash reporting for Flutter with Google Crashpad: sanitised minidumps of crashes the Dart VM never sees, on desktop, Android and iOS, for any minidump backend.
Changelog #
What an app can do with each version, newest first. The reasoning behind a
change lives beside the code in CLAUDE.md; this file only says what changed.
1.0.2 #
requestUploadsends at once on desktop, as it did on Android and iOS, whenstartwas given anuploadEndpoint: the report has gone by the time the future completes, instead of on the handler's next pass up to fifteen minutes later.- A refused upload is tried again on desktop, on each later start, five
times in all, as it already was on Android and iOS. Only while consent
stands, or for a report the app asked for with
requestUpload. - Listing reports while one was being uploaded no longer makes the
package forget it had sanitised that report: on Linux and Android,
CrashReportDatabase.reports()during a handler's upload had it cleaned a second time and asked for again on the next start. - The first build no longer runs the build hook twice. It printed "File
modified during build. Build must be rerun." after downloading the native
half, from
dart run fl_crashpad:prefetchand the firstflutter buildalike.
1.0.1 #
- 1.0.0 could not be built. Its archive on pub.dev was missing
lib/src/build/native_artifacts.dart, which the build hook anddart run fl_crashpad:prefetchimport, so every build that depended on it failed. Nothing else changed: the same API, the samenative-v0.1.0archives. hooksandcode_assetsare accepted at either 1.x or 2.x, whichever the app's other plugins resolve.
1.0.0 #
The API is stable from here. The native half is unchanged — the same
native-v0.1.0 archives, the same digests — and so is everything on disk: a
user's consent given under 0.1 is still their consent.
The changes are to what the API says to whoever reads a call to it. Consent reads as consent, the one switch that sends a user's data out as it was written reads as the decision it is, and a name that answered two questions now answers the one it can.
Renamed #
| 0.1.0 | 1.0.0 |
|---|---|
CrashpadOptions(uploadsEnabled: …) |
CrashpadOptions(uploadConsent: …) |
database.uploadsEnabled |
database.uploadConsent |
CrashpadOptions(sanitize: false) |
CrashpadOptions(disableSanitization: true) |
CrashpadOptions(upload: CrashpadUpload(url: …)) |
CrashpadOptions(uploadEndpoint: CrashpadUploadEndpoint(url: …)) |
CrashpadOptions(annotations: …) |
CrashpadOptions(fixedAnnotations: …) |
Crashpad.isSupported |
Crashpad.isAvailable |
uploadConsent(null: keep the last answer, which isfalseuntil somebody says otherwise). It is the user's answer, not a switch on the uploader, and its doc says to pass what they answered rather thantruebecause an endpoint exists. The settings file keeps itsuploadsEnabledkey, so no consent already given is withdrawn. consent given under 0.1 is still consent intest/api_test.dart.disableSanitization(false). Sanitising is the default you never write; the other path is one deliberate, conspicuous line.CrashpadUploadEndpointunderuploadEndpoint: it is where reports go, not an upload.fixedAnnotations: they never join the runtimeCrashpad.annotationsand nothing changes them afterstart.isAvailable: whether this build carries the native library in the version this code speaks.isSupportedansweredtrueon Android 8 and 9, wherestartthen refuses; the doc now lists whatstartcan still refuse with, as aCrashpadErrorCodeto branch on.
Removed from the barrel #
sanitizeReportFiles: what the database calls on each report, documented for nobody else.ReportSanitizeris the API.
Documentation #
crashForTestingsays first that it terminates the process;CrashpadHandlersays it is for custom packaging.- The README follows the order an app is set up in — install, start, what you get, sanitising, consent and uploads, reading reports, trying it out, then the platforms and how the native half gets built — and says what sanitising cannot catch beside the promise it makes, not after it.
SECURITY.md: what the package promises, what it cannot, what you are running and how it is verified, and how to report a vulnerability.
Android and iOS, and since 0.1.0 #
-
Windows:
Crashpad.startlistscrashpad_wer.dllin the registry under the current user, so fast-fail crashes — a/GSfailure, a Rust abort — are reported with no installer step (registerWerModule,true). It also lets WER see the process, which the Dart runtime's error mode had stopped, asking WER for no crash dialog in its place. -
Android 10 and later, arm64-v8a and x86_64: the handler is the library itself, started at a crash by the system linker through
libcrashpad_handler_trampoline.so. Both travel through the build hook, with nothing to add to the app. Nothing runs until a crash. -
iOS: crashes are caught in process and become reports on the next launch.
attachments,handlerArguments,metricsDirectoryandperiodicTasksdo nothing there. -
On both, reports are uploaded by the package from Dart, on the launch after the crash, once sanitised — the same request Crashpad's handler sends, which on Android cannot speak https. A report that cannot be sent is tried again on later launches, five times in all.
CrashReportDatabase.requestUploadsends at once whenstartwas given aCrashpadOptions.uploadEndpoint. -
Crashpad.sanitizationIdlealso covers the upload on mobile. -
Android's versioned system libraries (
android.hardware.drm@1.4.so) are no longer masked as email addresses;ReportSanitizer.rulesVersionis 2. -
The native ABI is 2.
-
CrashReportDatabase.recordUpload(id, remoteId:)records a report the app sent its own way, from any state, so a backend that is not a minidump collector needs noCrashpadOptions.uploadEndpoint. -
CrashReport.attachments: a report's attachments, sanitised like its minidump ([]when there are none).
0.1.0 #
The first release: native crash reporting for Flutter desktop apps on Linux,
Windows and macOS, x64 and arm64, over Google Crashpad (ce308a86).
Crashpad.start(CrashpadOptions)starts the handler and installs process-wide crash handlers: a crash anywhere in the process — the engine, a plugin, a native library loaded over FFI — leaves a minidump indatabaseDirectory. A handler that is missing, not executable, from another Crashpad build or unable to run is refused with aCrashpadExceptionrather than trusted.- Reports are sanitised before they can be read or sent
(
CrashpadOptions.sanitize,true): the home directory, the account name, emails, credentials, secret-named environment variables, IP addresses and private paths are masked inside the minidump in place, byte for byte, and text attachments are rewritten. While it is on, a report is uploaded on the launch after the crash, once cleaned.ReportSanitizercarries the rules;ReportSanitizer.forHost(secrets:, sensitiveRoots:)adds an app's own.CrashReport.sanitizedsays a report has been through it. CrashpadOptions.annotations, fixed at start, andCrashpad.annotations, changeable at any time and usable beforestart, within Crashpad's limits of 64 entries and 255-byte keys and values.CrashpadOptions.attachments, read at the moment of the crash.CrashpadUploadfor any minidump endpoint, andCrashpadOptions.uploadsEnabled(null, keeping the last answer, which starts asfalse) as consent kept in the database.CrashReportDatabase: consent, pending and completed reports, upload requests (Future<void> requestUpload) and deletion, beforestartand from any isolate.Crashpad.dumpWithoutCrash()andCrashpad.crashForTesting().CrashpadOptions.registerWerModule(true): Windows fast-fail crashes, Rust'sprocess::abortamong them, reported throughcrashpad_wer.dll.- The native half arrives through Flutter's own build — the library through a
build hook, the handler through the package's platform files — from a
per-user cache filled by a verified download or by
tool/build_native.dart --install.dart run fl_crashpad:prefetchfills it ahead of a build.