遇到如下的崩潰
03-07 16:15:31.993 7501-7501/com.netease.nrtc.demo A/libc: invalid address or address of corrupt block 0xb87bccd0 passed to dlfree
03-07 16:15:31.994 7501-7501/com.netease.nrtc.demo A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdeadbaad in tid 7501 (tease.nrtc.demo)
03-07 16:15:32.172 3746-3746/? A/DEBUG: pid: 7501, tid: 7501, name: tease.nrtc.demo >>> com.netease.nrtc.demo <<<
03-07 16:15:32.245 3746-3746/? A/DEBUG: #01 pc 000d031b /data/app/com.netease.nrtc.demo-1/lib/arm/libnrtc_engine.so
03-07 16:15:32.245 3746-3746/? A/DEBUG: #02 pc 000d03bb /data/app/com.netease.nrtc.demo-1/lib/arm/libnrtc_engine.so
03-07 16:15:32.245 3746-3746/? A/DEBUG: #03 pc 000d0415 /data/app/com.netease.nrtc.demo-1/lib/arm/libnrtc_engine.so
03-07 16:15:32.245 3746-3746/? A/DEBUG: #04 pc 008f6017 /data/app/com.netease.nrtc.demo-1/oat/arm/base.odex (offset 0x4d1000) (void com.netease.nrtc.rec.impl.RecEngine.dispose(long)+82)
03-07 16:15:32.245 3746-3746/? A/DEBUG: #05 pc 008f43bb /data/app/com.netease.nrtc.demo-1/oat/arm/base.odex (offset 0x4d1000) (void com.netease.nrtc.rec.impl.RecEngine.a()+462)
03-07 16:15:32.246 3746-3746/? A/DEBUG: #06 pc 008eaef9 /data/app/com.netease.nrtc.demo-1/oat/arm/base.odex (offset 0x4d1000) (void com.netease.nrtc.engine.a.c.leaveChannel()+964)
03-07 16:15:32.246 3746-3746/? A/DEBUG: #07 pc 008c398f /data/app/com.netease.nrtc.demo-1/oat/arm/base.odex (offset 0x4d1000) (int com.netease.nrtc.b.leaveChannel()+178)
03-07 16:15:32.246 3746-3746/? A/DEBUG: #08 pc 009acbf9 /data/app/com.netease.nrtc.demo-1/oat/arm/base.odex (offset 0x4d1000) (void com.netease.nrtc.demo.ChatActivity.leave()+60)
03-07 16:15:32.246 3746-3746/? A/DEBUG: #09 pc 009afa47 /data/app/com.netease.nrtc.demo-1/oat/arm/base.odex (offset 0x4d1000) (void com.netease.nrtc.demo.ChatActivity.onBackPressed()+90)
1.可知崩潰發(fā)生在000d031b
這個地址處。使用addr2line
工具將一個地址轉(zhuǎn)為一個符號。
$ addr2line -e libnrtc_engine.so -f 000d031b
_ZTv0_n12_NSt6__ndk118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev
??:?
2.使用c++filt
工具將這個符號轉(zhuǎn)為一個可讀的形式斜纪!因為C++編譯器為了支持函數(shù)的重載有一系列的規(guī)則用于生成唯一的函數(shù)名边涕。具體不同的編譯器生成的規(guī)則各不相同缩功。命令如下:
$ c++filt _ZTv0_n12_NSt6__ndk118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev
virtual thunk to std::__ndk1::basic_stringstream<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >::~basic_stringstream()
3.通過上面的分析夕膀,我們得知當(dāng)前程序是在std::stringstream類的析構(gòu)方法中執(zhí)行果善。
4.一般而言诊笤,針對不同CPU架構(gòu)的so庫,我們需要使用對應(yīng)的工具巾陕。Android NDK就提供了這些工具讨跟,如arm-linux-androideabi-addr2line,這些工具在NDK路徑下的toolchains目錄下都可以找到鄙煤。如果不使用特定版本的工具晾匠,可能會無法正常正確解析。