iOS崩溃报告:atos不按预期工作

我正在查看苹果提供的崩溃报告

Hardware Model: iPhone4,1 Version: ??? (???) Code Type: ARM (Native) Parent Process: launchd [1] Date/Time: 2012-11-18 16:03:44.951 -0600 OS Version: iOS 6.0.1 (10A523) Report Version: 104 Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: KERN_INVALID_ADDRESS at 0x51fe5264 Crashed Thread: 0 Thread 0 name: Dispatch queue: com.apple.main-thread Thread 0 Crashed: 0 libobjc.A.dylib 0x352925b0 objc_msgSend + 16 1 MYAPP 0x0006573a -[MyViewController(Images) didReceiveImage:context:etag:expires:] + 42 2 MYAPP 0x0004fb26 -[MyImageTask didReceiveImage:] + 98 3 Foundation 0x361ac8e8 __NSThreadPerformPerform 4 CoreFoundation 0x3b37d680 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ 5 CoreFoundation 0x3b37cee4 __CFRunLoopDoSources0 6 CoreFoundation 0x3b37bcb2 __CFRunLoopRun 7 CoreFoundation 0x3b2eeeb8 CFRunLoopRunSpecific 8 CoreFoundation 0x3b2eed44 CFRunLoopRunInMode 9 GraphicsServices 0x396bc2e6 GSEventRunModal 10 UIKit 0x3452e2f4 UIApplicationMain 11 MYAPP 0x0004934a main + 70 12 MYAPP 0x000492fc start + 36 

有趣的是,当我使用atos查找对应于地址位置0x0006573a0x0004fb26的代码行时 ,我得到完全不同的匹配。 atos输出甚至不是来自崩溃日志(MyViewController,MyImageTask)中提到的同一个类。 相反,atos指向完全无关的类中的完全良性的代码行。 我再次validation我正在使用我提交给苹果公司的确切的dSYM和IPA。

我的atos命令

 /Applications/Xcode.app/Contents/Developer/usr/bin/atos -arch armv7 -o MYAPP.app/MYAPP 0x0004fb26 

与/ usr / bin / atos和armv7s相同的结果。

有没有人遇到过这个问题? 你能给些build议么? 谢谢。

你必须计算与atos一起使用的地址,你不能只使用stacktrace中的那个。

 symbol address = slide + stack address - load address 
  1. slide值是LC_SEGMENT cmdLC_SEGMENT cmd的值(大部分是0x1000 )。 运行以下来获取它:

     otool -arch ARCHITECTURE -l "APP_BUNDLE/APP_EXECUTABLE" | grep -B 3 -A 8 -m 2 "__TEXT" 

    ARCHITECTUREreplace为崩溃报告显示的实际架构,例如armv7 。 将APP_BUNDLE/APP_EXECUTABLEreplace为实际可执行文件的path。

  2. stack address是崩溃报告中的hex值。

  3. load address可以是在包含可执行文件的行的最前面的Binary Images部分显示的第一个地址。 (通常是第一个入口)。

由于在过去的slide价值等于load address价值,这一直工作。 但是,由于苹果引入了从iOS 4.3开始的地址空间布局随机化 (不同的版本),出于安全原因,应用程序加载地址是随机的。

一个更简单的select:你可以使用atos -l标志来为你做math。

假设你在崩溃日志中有以下代码行:

 5 MyApp 0x0044e89a 0x29000 + 4348058 

第一个hex数是堆栈地址,第二个hex数是加载地址。 你可以忽略最后一个号码。 你不需要担心幻灯片地址。

为了表示,请执行以下操作:

 atos -o MyApp.app/MyApp -arch armv7 -l 0x29000 0x0044e89a 

如果找不到MyApp.app/MyApp文件,请将“.ipa”文件重命名为“.zip”,将其解压缩,然后将其放在Payload文件夹中。

如果您不确定要使用哪种体系结构(例如,armv7或armv7s),请滚动到崩溃文件的“二进制映像”部分,然后在该文件中find它。

干杯

简单的使用dwarfdump:

 dwarfdump --arch armv7 myApp.dSYM --lookup 0xaabbccdd | grep 'Line table' 

根本不需要做任何计算。

(从地址获取符号(symbolicating binary,iOS build) )。

对于某些时间没有像Load Address这样的值的人:

 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 

我创build了一个简单的bash来帮助我debugging:

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

它只是读取应用程序的path,应用程序名称,堆栈地址和“+”信号(十进制值)后的值,然后find加载地址的值以运行atos命令。