You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Crashlytics NDK接自定义崩溃处理后部分设备不上报崩溃如何解决

问题根因

出现跨设备上报异常的核心原因有两个:

  • 信号处理器注册顺序和设备上Crashlytics初始化时机不匹配:信号处理器是进程全局覆盖的,如果你在Crashlytics初始化前注册自己的处理器,Crashlytics后续初始化时会覆盖你的注册逻辑,且你存储的old_handlers并不是Crashlytics的处理函数,执行自定义逻辑后无法跳转到Crashlytics的上报流程。不同设备ROM的组件初始化速度不同,就会出现部分设备正常、部分设备异常的情况。
  • 现有自定义崩溃处理器只恢复了旧处理器,没有主动执行旧处理器的逻辑,当前崩溃信号无法传递到Crashlytics完成上报。

解决方案

1. 调整注册时机

确保你的信号处理器注册逻辑在Crashlytics Java层初始化完成之后再执行,不要放在静态初始化块、Application.attachBaseContext等过早执行的生命周期节点,建议在主Activity的onCreate回调中触发JNI调用执行注册逻辑。

2. 完善崩溃处理器逻辑

修改自定义崩溃处理器,在自定义逻辑执行完成后链式调用前序(Crashlytics)注册的信号处理器:

static const int SIGNALS_TO_CATCH[] =
{
    SIGABRT,
    SIGBUS,
    SIGFPE,
    SIGSEGV,
    SIGILL,
    SIGSTKFLT,
    SIGTRAP,
};
static struct sigaction old_handlers[NSIG];

void crash_handler(int signal, siginfo* info, void* ctxvoid)
{
    // 自定义崩溃处理逻辑,注意此处仅可使用异步安全的系统调用
    // 避免使用带锁、内存分配的日志库,防止二次崩溃
    android_fatal() << "CRASH OCCURED!!" << signal;

    // 链式调用前序注册的信号处理器
    if (old_handlers[signal].sa_flags & SA_SIGINFO) {
        old_handlers[signal].sa_sigaction(signal, info, ctxvoid);
    } else {
        if (old_handlers[signal].sa_handler == SIG_DFL) {
            // 无自定义前序处理器,走系统默认处理逻辑
            sigaction(signal, &old_handlers[signal], nullptr);
            raise(signal);
        } else if (old_handlers[signal].sa_handler != SIG_IGN) {
            old_handlers[signal].sa_handler(signal);
        }
    }
}

3. 额外注意事项

  • 信号处理器是进程全局生效的,不需要在单独线程重复注册,避免覆盖存储的old_handlers。
  • 信号处理函数内禁止执行异步不安全操作:包括malloc/free、加解锁、调用Android日志库之外的大部分框架接口,防止二次崩溃导致上报流程中断。
  • 如果项目内有其他第三方SDK也注册了同类信号处理器,需要保证所有自定义处理器都按注册顺序链式调用前序处理器,避免出现流程截断。

内容的提问来源于stack exchange,提问作者Голубев Антон

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 05:45:10