14

シンボル化されていないクラッシュレポートをAirBrake.io経由で受け取りました。クラッシュレポートはAppleのクラッシュログとまったく同じ形式ではないため、通常どおりXCodeにドロップすることはできません。そのため、XCodeアーカイブからまったく同じビルドを取得して、コマンドラインでそれを象徴しようとしました。次の結果が得られます。

$ atos -o kidsapp.app/kidsapp 0x0002fc4c
0x0002fc4c (in kidsapp)

クラッシュレポートと同じビルドを使用していると確信しています。だから私もdwarfdumpで試しました:

$ dwarfdump --lookup 0x0002fc4c --arch armv7 kidsapp.app.dSYM
----------------------------------------------------------------------
 File: kidsapp.app.dSYM/Contents/Resources/DWARF/kidsapp (armv7)
----------------------------------------------------------------------
Looking up address: 0x000000000002fc4c in .debug_info... not found.
Looking up address: 0x000000000002fc4c in .debug_frame... not found.

また、結果はありません。間違ったdSYMファイルを使用する以外に、間違っている可能性のあるものはありますか?これはAirBrakeのクラッシュレポートで参照されているバージョンであり、XCodeアーカイブにあるため、これが正しいバージョンであることがわかります。

どんなアイデア/ヒントも大歓迎です!

4

6 に答える 6

29

私はそれを理解するために次の算術を使用しました:

slide+ stack address- load address=symbol address

stack addressは、スタックダンプクラッシュレポートから取得した16進値です(.crashファイルではなく、スタックダンプのみ)。

slide実行時のLC_SEGMENTコマンドのvmaddrですotool -arch armv7 -l APP_BINARY_PATH。鉱山は通常0x00001000になります。

load address複雑な作品です。これは、実際には、メインスレッドの最下位のスタックアドレスと、実行時にシンボルを含むバイナリの部分の最初のアドレスとの違いdwarfdump --arch armv7 --all DSYM_BINARY_PATHです。これは単にmain関数のシンボリックアドレスです。したがって、最下位のクラッシュアドレスが0x8000で、メイン関数のシンボリックアドレスが0x2000の場合、load addressは0x6000になります。

これらすべての要素を使用して、シンボルアドレスを計算し、それをatosまたはdwarfdumpに入れることができますdwarfdump --lookup SYM_ADDR --arch armv7 APP_BINARY_PATH

ダンプの例(load address0x00003af4であることがわかります):

----------------------------------------------------------------------

ファイル:/Users/user/Desktop/MyApp.xcarchive/dSYMs/MyApp.app.dSYM/Contents/Resources/DWARF/MyApp(armv7)

----------------------------------------------------------------------

0x00000024:[0x00003af4-0x00003b4e)メイン

0x00000098:[0x00003b50-0x00003d8c)-[MyAppDelegateアプリケーション:didFinishLaunchingWithOptions:]

...残りのダンプ

最も難しかったのは、私が含めた2つの静的ライブラリの1つで、アプリのバイナリにリンクする前にシンボルが削除されていることに気づいたことです。そのため、シンボルアドレスに大きなギャップが生じたため、dSYMで必要なシンボルの3分の2しか使用できませんでした。

静的ライブラリのxcodeプロジェクトで次のフラグをNOに設定してください。これにより、静的ライブラリに対してリンクするときに、シンボルをアプリのバイナリ(後で削除できます)にプルできます:COPY_PHASE_STRIP、、、。DEAD_CODE_STRIPPINGSTRIP_INSTALLED_PRODUCT

ここで、「スタックダンプにメイン関数が含まれていないためにメインスレッドにないため、メイン関数のスタックアドレスを取得できない場合はどうすればよいですか?」と質問することができます。それに対して、私は「私は気まぐれな手がかりを持っていません!」と答えます。指を交差させるだけで、シンボルアドレスを含むスタックトレースを取得できるか、PLCrashReporterなどのAppleのクラッシュログを模倣したクラッシュレポートシステムを使用できることを願っています。

[2013年5月26日編集]-

これがload address実際にはmach-oバイナリのアドレスであることに気づきました。私が上で説明したことはしばしばうまくいくかもしれませんが、それは実際には正しくありません。これはクラッシュレポートから取得できますが、この回答のポイントは、クラッシュレポートがない場合にクラッシュのシンボルを提供することでした。load address象徴したいときを理解するために私が来た最良の方法は、を使用しload addressてログに記録することを確認することstack addressesです。

クラッシュをログに記録し(クラッシュレポートではなく)、後でデバッグのために取得できるS3バケットに送信するためのシステムを個人的に作成しました。アプリケーションを起動すると、アプリがクラッシュした場合に使用するために、、およびをキャッシュし、を送信しslideます。load addressmain function addressstack addresses

注:dyld関数は#include <mach-o/dyld.h>

slide=によって返されるアドレス_dyld_get_image_vmaddr_slide(0)

load address=によって返されるアドレス_dyld_get_image_header(0)

main function address[NSThread callStackReturnAddresses]=メインスレッドで呼び出されたときの最後のアドレス

クラッシュ時には、次のメソッドを使用して取得できるアーキテクチャだけでなく、ログ[NSThread callStackReturnAddresses]にも記録する必要があります。[NSThread callStackSymbols]

- (NSString*) arch
{
    NSString* arch =
#ifdef _ARM_ARCH_7
        @"armv7";
#elif defined (_ARM_ARCH_6)
        @"armv6";
#else
        nil;
#endif

    return arch;
}

ただし、armv7とarmv7sを区別する方法はまだわかりません。

したがって、これは将来役立つ可能性があります。私は学んだことをすべて取り入れて、これを単純なクラッシュツールに変えることを計画しています-natosツール(おそらくnatosv2)よりも優れています。

load address手動での供給をサポートするようにnatosを更新しました: https ://github.com/NSProgrammer/natos

于 2012-09-17T17:55:03.140 に答える
9

まず、dSYMが本当にそのアプリに適しているかどうかを確認します。

dwarfdump --uuid kidsapp.app/kidsapp
dwarfdump --uuid kidsapp.app.dSYM

どちらも同じ結果を返すはずです。

次に、dSYMに有効なコンテンツがあるかどうかを確認します

dwarfdump --all kidsapp.app.dSYM

これにより、以外の少なくともいくつかの情報が得られるはずですnot found

dSYMが壊れていると思います。一般に、すべてのスレッドと最後の例外バックトレース情報を含む完全なクラッシュレポートを提供するクラッシュレポーターを使用することをお勧めします。PLCrashReporterに基づくものを使用することをお勧めします。たとえば、QuincyKit(オープンソースSDK+サーバー+Mac上の記号)またはHockeyApp(オープンソースSDK +有料サービス+サーバー側記号)(注:私は両方の開発者の1人です!)

于 2012-04-23T12:07:44.203 に答える
4

その特定の時間に次のようなロードアドレスの値がない場合:

Jan 14 11:02:39 Dennins-iPhone AppName[584] <Critical>: Stack Trace: (
    0   CoreFoundation                      0x2c3084b7 <redacted> + 150
    1   libobjc.A.dylib                     0x39abec8b objc_exception_throw + 38
    2   CoreFoundation                      0x2c21cc35 CFRunLoopRemoveTimer + 0
    3   AppName                             0x0005a7db AppName + 272347  

デバッグに役立つ簡単なbashを作成しました。

#! /bin/bash
read -p "[Path] [App Name] [Stack Address] [Relative Address] " path appName runtimeAddress relativeAddress
loadAddress=`echo "obase=16;ibase=10;$((runtimeAddress-relativeAddress))" | bc`
atos -o $path/Payload/$appName.app/$appName -l $loadAddress $runtimeAddress -arch armv7

アプリのパス、アプリ名、ランタイムアドレス、「+」信号の後の値(10進値)を読み取り、ロードアドレスの値を見つけてatosコマンドを実行するだけです。

于 2015-01-14T16:36:17.713 に答える
2

だから私の場合:NSException.callStackSymbolsからクラッシュ文字列を受け取っています。

クラッシュスタックトレースは次のようになります。

2   AppName                               0x00000001006c75b4 AppName + 2356660\r3   AppName                               0x00000001004f5cfc AppName + 449788\r4   UIKit                               0x000000018c0a8968 \u003credacted\u003e + 108\r5   UIKit      0x000000018c0a9328 \u003credacted\u003e + 28\r6   UIKit                               0x000000018beea250 \u003credacted\u003e + 1320\r7   UIKit                               0x000000018beede98 \u003credacted\u003e + 188\r8   UIKit                               0x000000018bcb5820 \u003credacted\u003e + 116\r9   UIKit                               0x000000018bbdec88 \u003credacted\u003e + 760\r10  UIKit                               0x000000018bbde610 \u003credacted\u003e + 312\r11  UIKit                               0x000000018bbde31c \u003credacted\u003e + 296\r12  UIKit                               0x000000018bbde3bc \u003credacted\u003e + 456\r13  QuartzCore                          0x0000000185b93b7c \u003credacted\u003e + 284\r14  libdispatch.dylib                   0x00000001811a8a2c \u003credacted\u003e + 16\r15  libdispatch.dylib                   0x00000001811b5654 \u003credacted\u003e + 1012\r16  CoreFoundation                      0x0000000181851650 \u003credacted\u003e + 12\r17  CoreFoundation                      0x000000018184f1a8 \u003credacted\u003e + 2272\r18  CoreFoundation                      0x000000018176f488 CFRunLoopRunSpecific + 552\r19  GraphicsServices                    0x0000000183735020 GSEventRunModal + 100\r20  UIKit         0x000000018bc09cc0 UIApplicationMain + 236\r21  AppName                               0x000000010048f714 AppName + 30484\r22  libdyld.dylib 0x000000018120dfc0 \u003credacted\u003e + 4

Appleはコードを再コンパイルでき、Organizerのアーカイブからのdsymファイルは一致しないため、ビットコードを含めないでください。 ここに画像の説明を入力してください

このようなbashスクリプトを実行します。

#!/bin/bash
appName=AppName
runtimeAddress=0x00000001006c75b4
relativeAddress=2356660
loadAddress=`echo "obase=16;ibase=10;$((runtimeAddress-relativeAddress))" | bc`
atos -o $appName.app/$appName -l $loadAddress $runtimeAddress -arch arm64

test.sh(touch test.sh)を作成したと仮定します。アクセス許可の問題が原因でsctipt(./test.sh)を実行できない場合は、chmod +xtest.shを呼び出します。これで./test.shが機能するはずです。そして、結果を生成します。

ここに画像の説明を入力してください

また、AppName.app.dSYMファイルを使用してクラッシュファイルをシンボリック化することもできます。

#!/bin/bash
appName=AppName
runtimeAddress=0x00000001006c75b4
relativeAddress=2356660
loadAddress=`echo "obase=16;ibase=10;$((runtimeAddress-relativeAddress))" | bc`
atos -o $appName.app.dSYM/Contents/Resources/DWARF/$appName -l $loadAddress $runtimeAddress -arch arm64
于 2018-04-11T12:35:38.690 に答える
1

私はこの投稿があなたを助けるかもしれないと思います、https://stackoverflow.com/a/12559150/1773317。ジョーのコミットは私の問題を解決しました。

その理由は、私の.appファイルと.dSYMファイルをスポットライトでインデックス付けできないため、XCodeがクラッシュ情報を正しく表すことができないためです。

于 2013-03-10T08:15:51.927 に答える
1

atosコマンドを使用してシンボリック化するために作成したスクリプトを試して使用できます。

https://github.com/IdoTene/MacosSymbolicateCrash

于 2018-02-11T09:04:57.290 に答える