深度解读Android崩溃日志案例分析2:tombstone日志

779 阅读3分钟

这个案例是从tombstone入手,进行了crash日志分析,tombstone一般在开头,都会阐明崩溃的大致问题,一般来说空指针类型的崩溃是最容易通过ida、addr2line、objdump找到相关代码的。

崩溃现场

tombstone墓碑文件日志提示崩溃的地址0x835be0

pid: 3382, tid: 3821, name: dTi  >>> com.xx.xx.xx <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x835be0
    rax 00000000000000e1  rbx 00007fff6ef15d78  rcx 00000000000003d0  rdx 00007fff6ef15d80
    r8  00007fff6ef15d80  r9  00007fff50295a68  r10 00007fff6f16c940  r11 0000000000000055
    r12 000000000000004b  r13 0000000000000e10  r14 0000000000835be0  r15 0000000000836000
    rdi 0000000000835be0  rsi 00000000052a85ec
    rbp 0000000000835000  rsp 00007fff502958d0  rip 00007fff6eb8bb2d

iad加载so文件,然后打开hex dump视图

image.png

在hex dump视图下,我们跳转到0x835be0

image.png

image.png

再按下快捷键F5

image.png

此时就会生成该地址对应的C语言伪代码,提示崩溃的代码是在第11行

image.png

而add2line给出的位置是,基本正确,伪代码和源码只是写法不一样而已,逻辑都一样

image.png

这个函数对应的lua binding逻辑是

int lua_register_cocos2dx_studio_VisibleFrame(lua_State* tolua_S)
{
    tolua_usertype(tolua_S,"ccs.VisibleFrame");
    tolua_cclass(tolua_S,"VisibleFrame","ccs.VisibleFrame","ccs.Frame",nullptr);

    tolua_beginmodule(tolua_S,"VisibleFrame");
        tolua_function(tolua_S,"new",lua_cocos2dx_studio_VisibleFrame_constructor);
         // 这个函数
        tolua_function(tolua_S,"isVisible",lua_cocos2dx_studio_VisibleFrame_isVisible); 
        tolua_function(tolua_S,"setVisible",lua_cocos2dx_studio_VisibleFrame_setVisible);
        tolua_function(tolua_S,"create", lua_cocos2dx_studio_VisibleFrame_create);
    tolua_endmodule(tolua_S);
    std::string typeName = typeid(cocostudio::timeline::VisibleFrame).name();
    g_luaType[typeName] = "ccs.VisibleFrame";
    g_typeCast["VisibleFrame"] = "ccs.VisibleFrame";
    return 1;
}

对应的lua代码就是

ccs.VisibleFrame.setVisible

rdi和地址一样,那么就是第一个参数的问题

参数

如果能够得到崩溃时的堆栈参数信息,对排查这个问题也非常有帮助。

当参数少于7个时, 参数从左到右放入寄存器:

rdi, rsi, rdx, rcx, r8, r9。

当参数为7个以上时, 前 6 个与前面一样, 但后面的依次从右向左 放入中,即和32位汇编一样。

参数个数大于 7 个的时候

H(a, b, c, d, e, f, g, h);

  • a->%rdi
  • b->%rsi
  • c->%rdx
  • d->%rcx
  • e->%r8
  • f->%r9
  • h->8(%esp)
  • g->(%esp)
  • call H