バックトレースのAndroidアプリネイティブクラッシュ混乱分析

パーフェクトコードロジックは、完璧な手続きを作り出すことができるのだろうか?答えはノーです。ソフトウェアの観点からは、おそらく唯一のバイナリはあなたを欺くことはありません。

現象

最近、ビジネス側フィードバック奇妙なクラッシュではない十分な情報が解決します。

Signal: 11 (SIGSEGV), Code: 1 (SEGV_MAPERR)

r0  993ff520  r1  dc3170c4  r2  00000000  r3  dabe3e08
r4  993ff520  r5  00000005  r6  00000290  r7  000007ac
r8 e83253a0 r9 00006aba r10 bf921e39 r11 e83253a0 ip bfa3a9e0 sp 993ff494 lr bf88a71d pc bf96c31c #00 pc 001a731c /data/data/com.package.name/files/download/libmcto_media_player.so #01 pc 0020b7e5 /data/data/com.package.name/files/download/libmcto_media_player.so #00 993ff494 0000022c 993ff498 adcfd000  [anon:libc_malloc] 993ff49c bf88a71d /data/data/com.package.name/files/download/libmcto_media_player.so 993ff4a0 ffffffff 993ff4a4 ffffffff 993ff4a8 bf9d07e7 /data/data/com.package.name/files/download/libmcto_media_player.so #01 993ff4ac 00000000 993ff4b0 00000000 993ff4b4 00000000 993ff4b8 00000000 993ff4bc 00000000 993ff4c0 adcfd234  [anon:libc_malloc] 993ff4c4 00000000 993ff4c8 0000006e 993ff4cc 00000000 993ff4d0 adcfdf6c  [anon:libc_malloc] 993ff4d4 00000000 993ff4d8 00000000 993ff4dc 00000000 993ff4e0 00000000 993ff4e4 00000000 993ff4e8 00000000 

確かにダイナミックなビジネスロジックライブラリは、バグを持っている。この第一印象は、セグメンテーションフォールトにつながりました。バックトレースが不完全確かですが、どのような理由は完了していない私が見ることができない、本当に分析に役立つ必要があります。

分析

不完全なバックトレースの一般的な原因

ケースが発生したバックトレースは、一般的な理由がありますが、完全ではありません。

  • スタックメモリは、クラッシュの多くの間違った時間を記述しています。処理中の事故現場付近の外部入力ランダムロジックが大きい場合は、状況はさらに悪くなる、私たちは個別の不完全なバックトレースの大規模な数を確認する傾向があります。例えば:
#00 pc 00000ffb  <anonymous:c34fe000>
#01 pc 0009a885  /data/app/com.package.name-1/lib/arm/libjsc.so
#02 pc 0003ff93 /data/app/com.package.name-1/lib/arm/libjsc.so #03 pc 0011f60f /data/app/com.package.name-1/lib/arm/libjsc.so #04 pc fffffffb <unknown> 
#00 pc 000092fe  <anonymous:c15d0000>
#01 pc 00099ec3  /data/app/com.package.name-1/lib/arm/libjsc.so
#02 pc 00003ffe <anonymous:bf140000> 
#00 pc 00000ffb  <anonymous:ef304000>
  • コールパス上のELFファイルの一部が不完全なテーブルをおくつろぎください。例えば、クロムの一部のシステムODEX /オート麦、そこにWebViewのシステムは、このカテゴリーに入ります。例えば:
#00 pc 00d12bcc  /system/lib/libwebviewchromium.so
#00 pc 01a0cf72  /system/app/WebViewGoogle/WebViewGoogle.apk!libwebviewchromium.so (offset 0x46da000)
#00 pc 00006fde  /data/app/com.package.name-1/lib/arm/libcros.so
#01 pc 00007007  /data/app/com.package.name-1/lib/arm/libcros.so
#02 pc 00007023 /data/app/com.package.name-1/lib/arm/libcros.so #03 pc 00007037 /data/app/com.package.name-1/lib/arm/libcros.so #04 pc 000070d1 /data/app/com.package.name-1/lib/arm/libcros.so #05 pc 000049bf /data/app/com.package.name-1/lib/arm/libcros.so #06 pc 000092e3 /data/app/com.package.name-1/oat/arm/base.odex 
#00 pc 00013792  /system/lib/libc.so (__futex_wait_ex+49)
#01 pc 00013b21  /system/lib/libc.so (pthread_mutex_lock+310)
#02 pc 00028351 /system/lib/libc.so (dlfree+48) #03 pc 0000ef33 /system/lib/libc.so (free+10) #04 pc 0000a367 /system/lib/libjavacrypto.so #05 pc 0000bc4d /system/lib/libjavacrypto.so #06 pc 022fd081 /system/framework/arm/boot.oat 
  • いくつかは、パス自体が破損、または削除された上でELFファイルを呼び出します。さらに、衝突ダメージELFポイント自体が受信信号にある場合SIGBUSであってもよいです。例えば:
#00 pc 5d9840f2  <unknown>
#01 pc 4008ab6c  <unknown>
#00 pc 00392fd0  /system/lib/egl/libGLES_mali.so
#01 pc 0002ab7b  /system/lib/libgui.so (_ZN7android10GLConsumer22bindTextureImageLockedEv+182)
#02 pc 0002b3a9 /system/lib/libgui.so (_ZN7android10GLConsumer14updateTexImageEv+208) #03 pc b3317c6c <unknown> 
  • 読み取りELFコンテンツは通常、アクティブ終端アンワインドを選択し、誤解を招く避けるために、信頼できない可能性があり、その場合に位置実行共有メモリ命令、。例えば:
#00 pc 0007a010 /dev/ashmem/dalvik-jit-code-cache (deleted)
#00 pc 00019e64  /system/lib/libssl.so (SSL_clear+19)
#01 pc 000103b5  /system/lib/libjavacrypto.so (_ZL25NativeCrypto_SSL_shutdownP7_JNIEnvP7_jclassxP8_jobjectS4_+156)
#02 pc 00027a7d /system/framework/arm/boot-conscrypt.oat (com.android.org.conscrypt.NativeCrypto.SSL_shutdown+156) #03 pc 00032a03 /system/framework/arm/boot-conscrypt.oat (com.android.org.conscrypt.OpenSSLSocketImpl.shutdownAndFreeSslNative+138) #04 pc 0003330b /system/framework/arm/boot-conscrypt.oat (com.android.org.conscrypt.OpenSSLSocketImpl.close+434) #05 pc 003e0931 /system/lib/libart.so (art_quick_invoke_stub_internal+64) #06 pc 003e4ea3 /system/lib/libart.so (art_quick_invoke_stub+226) #07 pc 000ac2d9 /system/lib/libart.so (_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+140) #08 pc 001f27fb /system/lib/libart.so (_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPKNS_7DexFile8CodeItemEPNS_11ShadowFrameEPNS_6JValueE+238) #09 pc 001edd71 /system/lib/libart.so (_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+576) #10 pc 003cce3d /system/lib/libart.so (MterpInvokeVirtualQuick+504) #11 pc 003d6994 /system/lib/libart.so (ExecuteMterpImpl+29972) #12 pc 001d5351 /system/lib/libart.so (www.qilinchengdl.cn_ZN3art11interpreterL7ExecuteEPNS_6ThreadEPKNS_7DexFile8CodeItemERNS_11ShadowFrameENS_6JValueEb+340) #13 pc 001da6a3 /system/lib/libart.so (_ZN3art11interpreter33ArtInterpreterToInterpreterBridgeEPNS_6ThreadEPKNS_7DexFile8CodeItemEPNS_11ShadowFrameEPNS_6JValueE+142) #14 pc 001edd5b /system/lib/libart.so (_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+554) #15 pc 003cb927 /system/lib/libart.so (MterpInvokeStatic+322) #16 pc 003d2d94 /system/lib/libart.so (ExecuteMterpImpl+14612) #17 pc 001d5351 /system/lib/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadEPKNS_7DexFile8CodeItemERNS_11ShadowFrameENS_6JValueEb+340) #18 pc 001da6a3 /system/lib/libart.so (_ZN3art11interpreter33ArtInterpreterToInterpreterBridgeEPNS_6ThreadEPKNS_7DexFile8CodeItemEPNS_11ShadowFrameEPNS_6JValueE+142) #19 pc 001ee931 /system/lib/libart.so (_ZN3art11interpreter6DoCallILb1ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+420) #20 pc 003cc9eb /system/lib/libart.so (MterpInvokeDirectRange+294) #21 pc 003d3014 /system/lib/libart.so (ExecuteMterpImpl+15252) #22 pc 001d5351 /system/lib/libart.so (www.frgjyL.cn_ZN3art11interpreterL7ExecuteEPNS_6ThreadEPKNS_7DexFile8CodeItemERNS_11ShadowFrameENS_6JValueEb+340) #23 pc 001da6a3 /system/lib/libart.so (_ZN3art11interpreter33ArtInterpreterToInterpreterBridgeEPNS_6ThreadEPKNS_7DexFile8CodeItemEPNS_11ShadowFrameEPNS_6JValueE+142) #24 pc 001ee931 /system/lib/libart.so (_ZN3art11interpreter6DoCallILb1ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+420) #25 pc 003cc9eb /system/lib/libart.so (MterpInvokeDirectRange+294) #26 pc 003d3014 /system/lib/libart.so (ExecuteMterpImpl+15252) #27 pc 001d5351 /system/lib/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadEPKNS_7DexFile8CodeItemERNS_11ShadowFrameENS_6JValueEb+340) #28 pc 001da6a3 /system/lib/libart.so (_ZN3art11interpreter33ArtInterpreterToInterpreterBridgeEPNS_6ThreadEPKNS_7DexFile8CodeItemEPNS_11ShadowFrameEPNS_6JValueE+142) #29 pc 001edd5b /system/lib/libart.so (www.xinhezaixia.cn_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+554) #30 pc 003cce3d /system/lib/libart.so (MterpInvokeVirtualQuick+504) #31 pc 003d6994 /system/lib/libart.so (ExecuteMterpImpl+29972) #32 pc 001d5351 /system/lib/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadEPKNS_7DexFile8CodeItemERNS_11ShadowFrameENS_6JValueEb+340) #33 pc 001da5f1 /system/lib/libart.so (_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadEPKNS_7DexFile8CodeItemEPNS_11ShadowFrameE+92) #34 pc 003c0fbd /system/lib/libart.so (www.huishenggw.cn artQuickToInterpreterBridge+944) #35 pc 003e46f1 /system/lib/libart.so (art_quick_to_interpreter_bridge+32) #36 pc 000a5511 /dev/ashmem/dalvik-jit-code-cache (deleted) 

クラッシュの場所の予備的分析

戻る質問自体に。クラッシュの場所を見てください  001a731c

.text:001A7310  STMFD   SP!, {R4,R5,LR}
.text:001A7314  LDR     R5, [R1]
.text:001A7318  MOV     R4, R0
.text:001A731C  LDR     R3, [R5,#-4] ;崩溃发生在这里
.text:001A7320 SUB SP, SP, #0xC .text:001A7324 CMP R3, #0 .text:001A7328 SUB R0, R5, #0xC .text:001A732C BLT loc_1A7350 .text:001A7330 LDR R3, =(dword_2759D4 - 0x1A733C) .text:001A7334 ADD R3, PC, R3 ; dword_2759D4 .text:001A7338 CMP R0, R3 .text:001A733C BNE loc_1A7364 .text:001A7340 loc_1A7340 .text:001A7340 STR R5, [R4] .text:001A7344 MOV R0, R4 .text:001A7348 ADD SP, SP, #0xC .text:001A734C LDMFD SP!, {R4,R5,PC} .text:001A7350 ADD R1, SP, #0x18+var_14 .text:001A7354 MOV R2, #0 .text:001A7358 BL sub_1A6EA8 .text:001A735C MOV R5, R0 .text:001A7360 B loc_1A7340 .text:001A7364 MOV R1, #1 .text:001A7368 ADD R0, R0, #8 .text:001A736C BL sub_1C2CAC .text:001A7370 B loc_1A7340 

これは、完全な呼処理の比較的短い期間です。まず押し  R4R5LR、、実行を開始します。実行するには  R3, [R5,#-4] ミスが発生したとき、R5 現在の値がある  0x5にもマップを見なくても知っていることはほぼできである、  0x1 (0x5 - 0x4 = 0x1仮想メモリアドレスが不正でなければならない)、ミスの発生は正常です。信号コード市は  SEGV_MAPERR、予想に沿ったものでもあります。

バックトレースの2つだけのライン以来、私たちはラインで見し続けます  0020b7e5

............
.rodata:0020B795              DCB "try_count_=%d",0
.rodata:0020B7E3 asc_20B7E3   DCB "://",0 .rodata:0020B7E7 aCdn DCB "CDN",0 ............ 

驚くべきことに  0020b7e5 、それは位置  .rodata で、それはまた、(バックトレースが不完全である)アンワインド処理が中断理由を説明するのに役立ちます。

疑わしいです

再び崩壊の近くに指令位置を振り返る、それは疑わしい見つけました:

.text:001A7310  STMFD   SP!, {R4,R5,LR}
............
.text:001A731C  LDR     R3, [R5,#-4] ;崩溃发生在这里
.text:001A7320  SUB     SP, SP, #0xC
............
.text:001A7348  ADD     SP, SP, #0xC
.text:001A734C LDMFD SP!, {R4,R5,PC} 

コールのこの比較的短い期間で、スタックメモリ空間のわずか24バイトの合計を使用して、しかし  SP 実際には非常にまれである位置、に一回移動はありません。

テーブルをほどきます

アンワインドテーブルを見てください:

$ arm-linux-androideabi-readelf -u ./libmcto_media_player.so

............

0x1a7268: 0x80b108ab
  Compact model index: 0
  0xb1 0x08 pop {r3} 0xab pop {r4, r5, r6, r7, r14} 0x1a7310: 0x8002a9b0 Compact model index: 0 0x02 vsp = vsp + 12 0xa9 pop {r4, r5, r14} 0xb0 finish 0x1a7424: 0x8001a8b0 Compact model index: 0 0x01 vsp = vsp + 8 0xa8 pop {r4, r14} 0xb0 finish ............ 

クラッシュ位置  001a731c のための開始オフセットマッチング  1a7310 アンワインド情報コード  0x8002a9b0、時間がリラックスここで提示された情報によると、  SP 24バイト(データスタック24バイト)の合計を増加させるために必要な値を。クラッシュが発生した場合、それは、前述のアセンブリ命令から分かる(実行する  001a731c)、SP 値はわずか12バイト(減少するSTMFD SP!, {R4,R5,LR}問題です)。

スタックを見て

データのスタック:

#00  993ff494  0000022c
     993ff498  adcfd000  [www.cmyLgw.cn  anon:libc_malloc]
     993ff49c  bf88a71d  /data/data/com.package.name/files/download/libmcto_media_player.so
     993ff4a0  ffffffff
     993ff4a4  ffffffff
     993ff4a8  bf9d07e7  /data/data/com.package.name/files/download/libmcto_media_player.so
#01  993ff4ac  00000000
     993ff4b0  00000000
     993ff4b4  00000000
............

実際には、我々はアンワインドプロセスがテーブルをほどく情報に基づいて厳密に参照が行われるので、彼は誤解された、SP マルチの実際のニーズは、12のバイトを移動するよりも、実際の  LR メモリアドレスに格納され  993ff49c 、その値ではある  bf88a71dマップによると、情報は、我々は現在のELFへの絶対アドレスに対して計算オフセットされていますが、残念ながら起因する論理的なビジネス側に動的ライブラリを呼び出すレベルが比較的深く、より複雑であり、プロセスは、単独で既存のレジスタをほどくスタックとメモリ途中で終了されます情報は、ビジネス側位置決め問題を手助けするのに十分なされています。

正確には何001a731c?

このような状況「アンワインドテーブル情報」と「に対応するアセンブラ命令のシーケンスは」珍しい矛盾します。001a731c 何の機能では?なぜ命令のようなシーケンスはありますか?

ビジネス側からは、どこデバッグシンボルを持つダイナミックライブラリファイルを取得するには:

$arm-linux-androideabi-addr2line -f -e ./libmcto_media_player.so 001a731c
_ZNSsC1ERKSs
libgcc2.c:?

$arm-linux-androideabi-c++filt -n _ZNSsC1ERKSs
std::basic_string<char, std:www.chengmyuLegw.cn:char_traits<www.chengmingdl.com>, std::allocator<char> >::basic_string(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) 

それはあることが判明  std::basic_string コンストラクタ。

この問題は、おそらくバグNDKによって引き起こされます。ビジネス面から学んだ、NDKバージョン彼らがr9dを使用しています。

あなたはNDKを知るために使用されます

開発とクロスプラットフォームクロスコンパイラツールを維持することは容易ではありません。C言語に関しては、コンパイラはC ++の様々な文法的機能は、実行時に期待どおりに動作するだけでなく、C ++標準ライブラリの状況の異なるバージョンの長期共存を持っていることを。確認するために余分な労力の多くを支払う必要があります 根本的にAndroidの変化の新しいバージョンをサポートするために、だけでなく、下位互換性を維持するために。私たちが予想していたとして、実際には信頼できないNDK。NDKは、現状を調べるために、公式githubの問題に行くことができます。

R11からのNDKは明らかに変更履歴の重要な既知の問題に記載されているのみで開始します。

私たちは、印象的な既知の問題R11での変更履歴に書いて参照してください。

Cを使用するときに例外処理は、多くの場合、失敗します++ _ ARM32上で共有します。根本的な原因は、ARM32のためのlibc ++ ABIとのlibgccで使用されるアンワインダーLLVMの間の非互換性です。これはr10eからの回帰ではありません。

既知の問題ではR12の変更ログは書きました:

Cと巻き戻し例外++ _はまだジンジャーブレッドのARMやアイスクリームサンドイッチのために動作しません共有しました。

私たちは、実行時にC ++の例外処理は、アンワインドに依存していることを知っています。問題はここにあるはずです。

結論

ビジネス当事者がNDKの新しいバージョンのDLLを再コンパイルを使用して、我々は検討し  std::basic_string 、対応するアセンブリ命令をし、これを見つけた  SP 場所で一時間移動の初めに機能で。それは問題になりません。

動的ライブラリの再コンパイルのビジネスパーティライン、バックトレースの完全な崩壊を得る見つけ、バグ問題自体に起因するミスを修正します。

したがって、この問題の原因は、バックトレースにある不完全です:NDKのバグの低いバージョン、動的ライブラリの世代で結果が適切にいくつかのケースでアンワインドを実行することはできません。

上記の説明では既知の問題、バックトレース後の崩壊だけでなく、時にはC ++例外機構の代わりに使用する彼らのビジネスロジックも影響を受ける可能性が高い影響を受けます、具体的には、これは次のようになります。例外がスローされた後、コードはようではないかもしれませんロジックは、異常なキャプチャロジックのステップの実装によってステップに行くことを期待していました。実際に、このような隠れた問題がある場合、私はこのNDKのバージョンアップが一緒にそれらを修正することができます願っています。

クラッシュキャプチャツールについて

そして最後に、当社の広告時間に。

オンライン上でのクラッシュ情報のすべては、xCrashキャプチャ当社独自の先進のAndroid APP崩壊キャプチャツールを使用しています。

おすすめ

転載: www.cnblogs.com/qwangxiao/p/10962305.html