bugly崩溃排查1:lj_meta_cache

342 阅读2分钟

bugly反馈的崩溃信息

# GLThread 1244(26758)
SIGSEGV(SEGV_MAPERR)
#00 pc 0000000000aa3f58 /data/app/~~WpLbOJpUH515iuTdzLuwtA==/com.yddm.haiwai.game-WSEzvXvmgpQhb_dCQmuisg==/split_config.arm64_v8a.apk
#01 pc 0000000000aafb84 /data/app/~~WpLbOJpUH515iuTdzLuwtA==/com.yddm.haiwai.game-WSEzvXvmgpQhb_dCQmuisg==/split_config.arm64_v8a.apk
  • 0xaa3f58 addr2line结果: lj_meta_cache
  • 0xaafb84addr2line结果: rec_call_setup lj_record.c:?

信息很少,只能从这个函数下手,bugly的系统日志也看了并没有看到任何有用的信息

尝试 ida 反汇编排查问题

定位崩溃代码的源码位置

iad的0xaa3f58view如下

image.png

反汇编代码

image.png

源码lj_meta.c

/* Negative caching of a few fast metamethods. See the lj_meta_fast() macro. */
cTValue *lj_meta_cache(GCtab *mt, MMS mm, GCstr *name)
{
  cTValue *mo = lj_tab_getstr(mt, name);
  lj_assertX(mm <= MM_FAST, "bad metamethod %d", mm);
  if (!mo || tvisnil(mo)) {  /* No metamethod? */
    // 根据反汇编的源码推断,大概率是运行到这里的代码出现了崩溃
    // 请注意这个位置,在后续的排查过程中,我们会对这个位置下个钩子
    mt->nomm |= (uint8_t)(1u<<mm);  /* Set negative cache flag. */
    return NULL;
  }
  return mo;
}

调用lj_meta_cache的地方

image.png

从ida的引用结果来看,我们并没有发现rec_call_setup,所以很可能是bugly给出的堆栈不够精细,rec_call_setup很可能间接的调用

不过严谨起见,我们还是从源码验证下ida给出的引用。

这里因为lj_meta_cache的调用被宏lj_meta_fastglj_meta_fast替代

#define lj_meta_fastg(g, mt, mm) \
  ((mt) == NULL ? NULL : ((mt)->nomm & (1u<<(mm))) ? NULL : \
   lj_meta_cache(mt, mm, mmname_str(g, mm)))
#define lj_meta_fast(L, mt, mm)	lj_meta_fastg(G(L), mt, mm)

所以需要搜下源码里面调用 lj_meta_fastglj_meta_fast的地方

  • lj_gc_separateudata image.png

  • gc_finalize image.png

  • lj_cf_ffi_new:注意这个ffi image.png

  • lj_meta_tget image.png

  • lj_meta_tset image.png

  • lj_meta_equal image.png

  • propagatemark image.png

和源码全部对上了,太强了,特别是这个propagatemark的引用

可能的猜测

我看到都是和gc有关的函数,之前对lua gc并不是非常的熟悉,甚至都不知道lua还有gc。

尝试搜索这些函数,google给出了一个可能的原因,有反馈是死循环、或者超大循环导致的崩溃,我也尝试了编写对应的测试例,这种只会导致ANR(Application Not responding),也就是应用程序未响应,最终会被系统主动kill掉,崩溃日志给出的sign是abort,和我要排查的并不是一回事。

下一步排查思路

至此,我还是不能确定这个崩溃到底是怎么回事,即使知道了相关的调用关系,但是对于这样一个非常基础的函数,如果我们无法稳定复现bug,我们还是没有办法去修复它。

下一步我会转向从luajit入手排查这个bug。