3

NDKを使用してAndroidアプリに取り組んでいます。残念ながら、最近書いたコードでセグメンテーション違反が発生しています。ndk-gdb を長い間動作させようとしましたが、まったく動作しません (segfault が発生し、プログラムのまったく無関係な部分で壊れます。スタックも完全に壊れています。壊れません)私が設定したブレークポイントで...)。そこで、プログラムがセグメンテーション違反を起こしたときに得られる奇妙な出力を調べることにしました。

Linux で一般的な C++ プログラムを書いているときに見たことがありますが、それが何と呼ばれているのか、またはそれを建設的に使用する方法がわかりません。

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/nakasi/grouper:4.2.2/JDQ39/573038:user/release-keys'
Revision: '0'
pid: 23369, tid: 23369, name: xxx.xxx  >>> com.xxx.xxx <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 22e1ee54
    r0 beddee50  r1 00003e99  r2 00003e99  r3 22e1ee54
    r4 620b1e78  r5 4007e010  r6 00000004  r7 40099de4
    r8 beddf658  r9 40099ddc  sl 4007e020  fp beddeda4
    ip beddee50  sp bedded88  lr 653c7c64  pc 653c8e64  cpsr 80000010

...

backtrace:
     #00  pc 00006e64  /data/app-lib/com.xxx.xxx-1/libxxx.so (void anotherFunction<int>(int*, int, int, int&, int)+196)
     #01  pc 00005c60  /data/app-lib/com.xxx.xxx-1/libxxx.so (aFunction(AStruct*, int&, int*, int&, unsigned short const*, int)+856)
     #02  pc 000060c4  /data/app-lib/com.xxx.xxx-1/libxxx.so (Java_com_xxx_xxx_ClassName_f66+1072)
     #03  pc 0001e290  /system/lib/libdvm.so (dvmPlatformInvoke+112)
     #04  pc 0004d411  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+396)
     #05  pc 0004f56f  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+174)
     #06  pc 000276a0  /system/lib/libdvm.so
     #07  pc 0002b57c  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
     #08  pc 0005ff07  /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+374)
     #09  pc 000677e1  /system/lib/libdvm.so   

...

stack:
         bedded48  c0000000  
         bedded4c  beddf508  [stack]
         bedded50  00000003  
         bedded54  00000100 

...さまざまなレジスタの近くのメモリが続きます

これはコアダンプと呼ばれますか?

プログラムがクラッシュした状況には特に興味はありません。どこでクラッシュしたかだけです。バックトレースからの関数名と命令オフセットを使用できる行番号に変換するにはどうすればよいですか? そこから、デバッグを出力できます。これまで、私は基本的に、printf に相当する Android を使用してコードをバイナリ検索してきました...そして、それは本当に、本当に、本当に遅いです...

乾杯

4

1 に答える 1

1

ビルドするときは、それを使用するndk-build NDK_DEBUG=1と、バックトレースに関する詳細情報が得られる場合があります。

それが魔法のように役に立たない場合は、使用できますaddr2line(シンボルを使用して構築する必要があります)。

addr2line <addr> -e <filename>

あなたの場合、次のようなものを取得する必要があります

$addr2line 0x6e64 -e libxxx.so
XXX.c:406

libxxx.soにマップされていない場合に考えられる問題の 1 つは0x0、すべてのアドレスが他のベース値にオフセットされることです。ただし、アドレスは十分に小さいように見えるため、機能するか、カーネルが正しい値を直接出力する可能性があります (ポインター値からマップされたアドレスを減算し、ログにアドレスを正しく出力します)。

于 2013-06-26T08:28:36.613 に答える