Flutter崩溃报告插件quick_breakpad的使用

Flutter崩溃报告插件quick_breakpad的使用

quick_breakpad 是一个跨平台的 Flutter 插件,用于通过 Google Breakpad 进行 C/C++/Objective-C 的崩溃报告。

使用 Breakpad 进行崩溃报告

Android

在 macOS/Linux 上运行
# 设备/模拟器已连接
$ android_abi=$(adb shell getprop ro.product.cpu.abi)
$ pushd example
$ flutter run
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
I/quick_breakpad(28255): JNI_OnLoad
I quick_breakpad_example(28255): JNI_OnLoad
D quick_breakpad(28255): Dump path: /data/data/com.example.quick_breakpad_example/cache/54ecbb9d-cef5-4fa9-5b6869b2-198bc87e.dmp
$ popd
$ adb shell "run-as com.example.quick_breakpad_example sh -c 'cat /data/data/com.example.quick_breakpad_example/cache/54ecbb9d-cef5-4fa9-5b6869b2-198bc87e.dmp'" > 54ecbb9d-cef5-4fa9-5b6869b2-198bc87e.dmp
在 Linux 上运行(例如使用 Multipass)
$ $CLI_BREAKPAD/breakpad/linux/$(arch)/dump_syms example/build/app/intermediates/cmake/debug/obj/${android_abi}/libquick-breakpad-example.so > libquick-breakpad-example.so.sym
$ uuid=$(awk 'FNR==1{print $4}' libquick-breakpad-example.so.sym)
$ mkdir -p symbols/libquick-breakpad-example.so/$uuid/
$ mv ./libquick-breakpad-example.so.sym symbols/libquick-breakpad-example.so/$uuid/
$ $CLI_BREAKPAD/breakpad/linux/$(arch)/minidump_stackwalk 54ecbb9d-cef5-4fa9-5b6869b2-198bc87e.dmp symbols > libquick-breakpad-example.so.log
显示解析后的 Android 日志
$ head -n 20 libquick-breakpad-example.so.log

崩溃发生在 quick_breakpad_example.cpp 文件的第 30 行。

崩溃位置

iOS

在 macOS 上运行
  1. 获取模拟器 UUID 并在其中运行
$ flutter devices
1 connected device:
iPhone SE (2nd generation) (mobile) • C7E50B0A-D9AE-4073-9C3C-14DAF9D93329 • ios        • com.apple.CoreSimulator.SimRuntime.iOS-14-5 (simulator)
$ device=C7E50B0A-D9AE-4073-9C3C-14DAF9D93329
$ pushd example
$ flutter run -d $device
Running Xcode build...
 └─Compiling, linking and signing...                      2,162ms
Xcode build done.                                            6.2s
Lost connection to device.
$ popd
  1. 查找应用程序数据并获取 dump 文件
$ data=$(xcrun simctl get_app_container booted com.example.quickBreakpadExample data)
$ ls $data/Library/Caches/Breakpad
A1D2CF75-848E-42C4-8F5C-0406E8520647.dmp        Config-FsNxCZ
$ cp $data/Library/Caches/Breakpad/A1D2CF75-848E-42C4-8F5C-0406E8520647.dmp .
  1. 通过符号文件解析 dump 文件
$ dsymutil example/build/ios/Debug-iphonesimulator/Runner.app/Runner -o Runner.dSYM
$ $CLI_BREAKPAD/breakpad/mac/dump_syms Runner.dSYM > Runner.sym
$ uuid=$(awk 'FNR==1{print $4}' Runner.sym)
$ mkdir -p symbols/Runner/$uuid/
$ mv ./Runner.sym symbols/Runner/$uuid/
$ $CLI_BREAKPAD/breakpad/mac/$(arch)/minidump_stackwalk A1D2CF75-848E-42C4-8F5C-0406E8520647.dmp symbols > Runner.log
显示解析后的 iOS 日志
$ head -n 20 Runner.log

崩溃发生在 AppDelegate.m 文件的第 11 行。

崩溃位置

Windows

  1. 运行示例
rem 命令提示符
> pushd example
> flutter run -d windows
Building Windows application...
dump_path: .
minidump_id: 34cd2b95-aef1-4003-ae75-1c848b18aad2
> popd
> copy example\34cd2b95-aef1-4003-ae75-1c848b18aad2.dmp .
  1. 解析 dump 文件
rem 命令提示符
> %CLI_BREAKPAD%\windows\%PROCESSOR_ARCHITECTURE%\dump_syms example\build\windows\runner\Debug\quick_breakpad_example.pdb > quick_breakpad_example.sym
# bash 或 zsh
$ uuid=$(awk 'FNR==1{print $4}' quick_breakpad_example.sym)
$ mkdir -p symbols/quick_breakpad_example.pdb/$uuid/
$ mv ./quick_breakpad_example.sym symbols/quick_breakpad_example.pdb/$uuid/
$ ./breakpad/linux/$(arch)/minidump_stackwalk 34cd2b95-aef1-4003-ae75-1c848b18aad2.dmp symbols > quick_breakpad_example.log
  1. 显示解析后的 Linux 日志
# bash 或 zsh
$ head -n 20 quick_breakpad_example.log

崩溃发生在 flutter_windows.cpp 文件的第 23 行。

崩溃位置

macOS

有关 macOS 的信息,请参阅此链接


#### Linux

1. 在 Linux 上运行

```bash
$ pushd example
$ flutter run -d linux
Building Linux application...
Dump path: /tmp/d4a1c6ac-2ad7-4301-c22e3c9b-0a4c5588.dmp
$ popd
$ cp /tmp/d4a1c6ac-2ad7-4301-c22e3c9b-0a4c5588.dmp .
  1. 解析 dump 文件
# flutterArch=x64 或 arm64
$ $CLI_BREAKPAD/breakpad/linux/$(arch)/dump_syms build/linux/${flutterArch}/debug/bundle/quick_breakpad_example > quick_breakpad_example.sym
$ uuid=$(awk 'FNR==1{print $4}' quick_breakpad_example.sym)
$ mkdir -p symbols/quick_breakpad_example/$uuid/
$ mv ./quick_breakpad_example.sym symbols/quick_breakpad_example/$uuid/
$ $CLI_BREAKPAD/breakpad/linux/$(arch)/minidump_stackwalk d4a1c6ac-2ad7-4301-c22e3c9b-0a4c5588.dmp symbols > quick_breakpad_example.log
  1. 显示解析后的 Linux 日志
$ head -n 20 quick_breakpad_example.log

崩溃发生在 my_application.cc 文件的第 19 行。

崩溃位置

示例代码

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:quick_breakpad/quick_breakpad.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';

  [@override](/user/override)
  void initState() {
    super.initState();
    initPlatformState();
  }

  // 平台消息是异步的,因此我们在异步方法中初始化
  Future<void> initPlatformState() async {
    String platformVersion;
    // 平台消息可能会失败,因此我们使用 try/catch PlatformException。
    try {
      platformVersion = await QuickBreakpad.platformVersion;
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    // 如果小部件在异步平台消息飞行时从树中移除,我们希望丢弃回复而不是调用
    // setState 以更新我们的不存在的外观。
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('插件示例应用'),
        ),
        body: Center(
          child: Text('运行在: $_platformVersion\n'),
        ),
      ),
    );
  }
}

更多关于Flutter崩溃报告插件quick_breakpad的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter崩溃报告插件quick_breakpad的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


quick_breakpad 是一个用于 Flutter 应用的崩溃报告插件,它基于 Google 的 Breakpad 库,可以帮助你捕获和报告应用程序的崩溃信息。Breakpad 是一个跨平台的崩溃报告工具,支持捕获原生代码(如 C/C++)的崩溃信息。

以下是使用 quick_breakpad 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 quick_breakpad 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  quick_breakpad: ^1.0.0  # 使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 初始化插件

在你的 Flutter 应用中初始化 quick_breakpad 插件。通常,你可以在 main.dart 文件中进行初始化:

import 'package:flutter/material.dart';
import 'package:quick_breakpad/quick_breakpad.dart';

void main() {
  // 初始化 Breakpad
  QuickBreakpad().init();

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Breakpad Demo'),
      ),
      body: Center(
        child: Text('Hello, world!'),
      ),
    );
  }
}

3. 捕获崩溃信息

quick_breakpad 会自动捕获原生代码的崩溃信息。当应用崩溃时,它会生成一个 .dmp 文件,通常存储在设备的特定目录中。

4. 上传崩溃报告

你可以通过自定义逻辑将崩溃报告上传到你的服务器或第三方服务(如 Sentry、Firebase Crashlytics 等)。以下是一个简单的示例,展示如何获取崩溃文件并上传:

import 'package:quick_breakpad/quick_breakpad.dart';
import 'dart:io';

void uploadCrashReports() async {
  // 获取崩溃文件目录
  String crashDir = await QuickBreakpad().getCrashDumpDirectory();

  // 列出目录中的所有崩溃文件
  Directory dir = Directory(crashDir);
  List<FileSystemEntity> files = dir.listSync();

  for (var file in files) {
    if (file is File && file.path.endsWith('.dmp')) {
      // 读取崩溃文件内容
      List<int> crashData = await file.readAsBytes();

      // 上传崩溃文件
      // 你可以使用 HTTP 请求或其他方式将 crashData 上传到服务器
      // 例如:http.post('https://your-server.com/upload', body: crashData);

      // 上传成功后删除文件
      file.delete();
    }
  }
}
回到顶部