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

CoffeeCatch触发信号后如何跳转回COFFEE_CATCH子句?

CoffeeCatch 原生崩溃捕获原理答疑

基础说明

CoffeeCatch是适配Android平台的C/C++原生崩溃捕获组件,核心逻辑是拦截SIGSEGV等系统异常信号,支持开发者插入自定义处理逻辑,可满足崩溃发生时保存栈轨迹信息的需求。
它的典型使用方式如下:

COFFEE_TRY_JNI(env, *retcode = call_dangerous_function(env, object));

其中call_dangerous_function()代表可能触发崩溃、产生异常信号的风险函数。
COFFEE_TRY_JNI的宏定义如下:

#define COFFEE_TRY_JNI(ENV, CODE)       \
  do {                                  \
    COFFEE_TRY() {                      \
      CODE;                             \
    } COFFEE_CATCH() {                  \
      coffeecatch_throw_exception(ENV); \
    } COFFEE_END();                     \
  } while(0)

宏完全展开后的逻辑结构如下:

do {                                  
    if (coffeecatch_inside() || 
    (coffeecatch_setup() == 0 
     && sigsetjmp(*coffeecatch_get_ctx(), 1) == 0)) {                      
      call_dangerous_function(env, object);                             
    } else {                  
      coffeecatch_throw_exception(ENV); 
    } 
    coffeecatch_cleanup();                     
} while(0)

核心疑问解答

siglongjmp的跳转目标与分支走向

首先明确sigsetjmp/siglongjmp的标准行为:

  • 第一次执行到sigsetjmp时,会将当前线程的寄存器状态、栈上下文、信号掩码保存到传入的上下文结构中,此时sigsetjmp返回值为0,整个if条件判定为真,进入if分支执行风险代码。
  • 异常信号触发后,信号处理函数调用siglongjmp跳转时,不会回到if语句的开头重新判定所有条件,而是直接跳转到sigsetjmp的调用点,此时sigsetjmp会返回传给siglongjmp的非0值,sigsetjmp(...) == 0表达式判定为假,整个if条件不成立,直接进入else分支执行异常处理逻辑,不会出现无限循环的问题。
    这里的关键细节是逻辑与&&的短路求值规则:第一次执行if条件判定时,coffeecatch_setup() == 0已经求值为真,siglongjmp跳回后仅需要继续完成sigsetjmp(...) == 0的求值,不会重复执行coffeecatch_setup(),也不会回头重新判定coffeecatch_inside()的状态。

测试时siglongjmp触发二次SIGSEGV、无法进入else分支的原因

出现这个问题基本是以下两个原因导致的:

  • 未配置备用信号栈:大部分SIGSEGV崩溃伴随栈溢出问题,默认情况下信号处理函数运行在当前线程栈上,如果栈已经损坏溢出,信号处理函数本身就会触发二次段错误,根本执行不到siglongjmp的逻辑。CoffeeCatch本身不会自动给所有线程配置备用信号栈,需要接入方手动调用sigaltstack为每个需要捕获崩溃的线程配置独立的备用信号栈空间。
  • 上下文被破坏:如果编译时开了O2及以上的优化等级,或者风险函数存在栈内存越界写入,会导致sigsetjmp保存的上下文结构被踩坏,siglongjmp跳转到非法地址,直接触发二次崩溃。

内容的提问来源于stack exchange,提问作者JonasVautherin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:51:26