cek*_*rek 140 xcode debug-symbols ios
我在iOS 5模拟器/设备中调试Xcode 4.2时遇到问题.正如预期的那样,以下代码崩溃:
NSArray *arr=[NSArray array];
[arr objectAtIndex:100];
Run Code Online (Sandbox Code Playgroud)
在iOS 4中,我获得了十六进制数的有用堆栈跟踪.但是在iOS 5中,它只是给了我:
*** First throw call stack:
(0x16b4052 0x1845d0a 0x16a0674 0x294c 0x6f89d6 0x6f98a6 0x708743 0x7091f8 0x7fcaa9 0x2257fa9 0x16881c5 0x15ed022 0x15eb90a 0x15eadb4 0x15eaccb 0x6f02a7 0x6faa93 0x2889 0x2805)
Run Code Online (Sandbox Code Playgroud)
谢谢.
Zan*_*aes 256
我没有尝试过会解决这个问题(尝试了两个编译器,两个调试器等).升级XCode以进行iOS 5更新后,没有任何堆栈跟踪似乎有效.
但是,我找到了一个有效的解决方法 - 创建我自己的异常处理程序(由于其他原因也很有用).首先,创建一个处理错误并将其输出到控制台的函数(以及您想要用它做的任何其他事情):
void uncaughtExceptionHandler(NSException *exception) {
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
// Internal error reporting
}
Run Code Online (Sandbox Code Playgroud)
接下来,将异常处理程序添加到您的应用程序委托:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
// Normal launch stuff
}
Run Code Online (Sandbox Code Playgroud)
而已!
如果这不起作用,那么只有两个可能的原因:
NSSetUncaughtExceptionHandler电话(你的整个应用只能有一个处理程序).例如,某些第三方库设置了自己的uncaughtExceptionHandler.因此,尝试在didFinishLaunchingWithOptions功能的END处设置它(或选择性地禁用第三方库).或者更好的是,设置一个符号断点NSSetUncaughtExceptionHandler,快速查看谁在调用它.您可能想要做的是修改当前的而不是添加另一个.EXC_BAD_ACCESS是不是一个例外;信贷@Erik B的评论,下同)Wis*_*uck 109
添加异常断点(使用断点导航器底部的+)有一个有用的选项.这将在任何异常中中断(或者您可以设置条件).我不知道这个选择是4.2中的新选择,还是我最终注意到它试图解决丢失的符号问题.
一旦达到此断点,就可以像往常一样使用Debug Navigator导航调用堆栈,检查变量等.
如果你想要一个适合复制/粘贴的符号化调用堆栈,gdb backtrace可以从那里正常工作:
(gdb) bt
#0 0x01f84cf0 in objc_exception_throw ()
#1 0x019efced in -[NSObject doesNotRecognizeSelector:] ()
Run Code Online (Sandbox Code Playgroud)
(等等)
Ped*_*dro 46
调试器上有一个新功能.您可以在抛出异常时设置断点并在此处停止执行,就像以前在4.0上发生的那样.
在"断点导航器"上,添加"异常断点",然后在选项弹出窗口中按"完成".
就这样!
PS:在某些情况下,最好只针对Objective-C异常进行破解.
Ale*_*der 21
这是另一个解决方案,不像以前那么优雅,但如果你没有添加异常断点或处理程序,它只能是一种方法.
当应用程序崩溃,并且您获得原始的第一个抛出调用堆栈(以十六进制数字表示)时,键入Xcode控制台info line *hex(不要忘记星号和0x十六进制说明符),例如:
(gdb) info line *0x2658
Line 15 of "path/to/file/main.m" starts at address 0x25f2 <main+50>
and ends at 0x267e <main+190>.
Run Code Online (Sandbox Code Playgroud)
如果您使用的是lldb,则可以键入image lookup -a hex(在这种情况下没有星号),并获得类似的输出.
使用此方法,您可以从throw堆栈的顶部(将有大约5-7个系统异常传播器)遍历到您的函数,这会导致崩溃,并确定准确的文件和代码行.
此外,为了类似的效果,您可以在终端中使用atos实用程序,只需键入:
atos -o path/to/AplicationBundle.app/Executable 0xAdress1 0xAdress2 0xAdress3 ...
Run Code Online (Sandbox Code Playgroud)
并且您获得符号化的堆栈跟踪(至少对于具有调试符号的函数).这种方法更为可取,因为您没有每个地址调用info line,只需从控制台输出中复制地址并将其粘贴到终端中.
您可以添加一个异常断点(使用+在断点导航器的底部),然后将操作添加 bt到它(点击添加动作按钮,选择Debugger命令,输入在文本字段"BT").一旦抛出异常,这将显示堆栈跟踪.
这是一个常见问题,而不是4.2中的堆栈跟踪.您可以尝试在LLDB和GDB之间进行交换,看看您是否获得了更好的结果.
在此处提交错误报告.
http://developer.apple.com/bugreporter/
编辑:
我相信如果你换回LLVM GCC 4.2,你就不会发现这种情况.您可能会丢失所需的功能.
小智 6
在主函数中使用此代码:
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal;
@try {
retVal = UIApplicationMain(argc, argv, nil, nil);
}
@catch (NSException *exception) {
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
}
@finally {
[pool release];
}
return retVal;
}
Run Code Online (Sandbox Code Playgroud)
在Xcode的调试控制台提示符下键入:
image lookup -a 0x1234
它会告诉你类似的东西:
Address: MyApp[0x00018eb0] (MyApp.__TEXT.__text + 91088)
Summary: MyApp`-[MyViewController viewDidAppear:] + 192 at MyViewController.m:202
Run Code Online (Sandbox Code Playgroud)