遇到如下的崩潰
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這個(gè)地址處。使用addr2line工具將一個(gè)地址轉(zhuǎn)為一個(gè)符號(hào)。
$ addr2line -e libnrtc_engine.so -f 000d031b
_ZTv0_n12_NSt6__ndk118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev
??:?
2.使用c++filt工具將這個(gè)符號(hào)轉(zhuǎn)為一個(gè)可讀的形式!因?yàn)镃++編譯器為了支持函數(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.一般而言,針對(duì)不同CPU架構(gòu)的so庫(kù),我們需要使用對(duì)應(yīng)的工具。Android NDK就提供了這些工具,如arm-linux-androideabi-addr2line,這些工具在NDK路徑下的toolchains目錄下都可以找到。如果不使用特定版本的工具,可能會(huì)無(wú)法正常正確解析。