ios Xcode 4.2 调试不象征堆栈调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7841610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Xcode 4.2 debug doesn't symbolicate stack call
提问by cekisakurek
I have a problem with Xcode 4.2 debugging in an iOS 5 simulator/device. The following code crashes, as expected:
我在 iOS 5 模拟器/设备中调试 Xcode 4.2 时遇到问题。正如预期的那样,以下代码崩溃了:
NSArray *arr=[NSArray array];
[arr objectAtIndex:100];
In iOS 4, I get a useful stack trace of hex numbers. But in iOS 5, it just gives me:
在 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)
Thanks.
谢谢。
回答by Zane Claes
Nothing I tried would fix this (tried both compilers, both debuggers, etc.) After upgrading XCode for the iOS 5 update, no stack traces seemed to work.
我尝试过的任何方法都无法解决此问题(尝试了两种编译器、两种调试器等)。在为 iOS 5 更新升级 XCode 后,似乎没有堆栈跟踪起作用。
However, I have found an effective work-around - creating my own exception handler (which is also useful for other reasons). First, create a function that will handle the error and output it to the console (as well as whatever else you want to do with it):
但是,我找到了一个有效的解决方法 - 创建我自己的异常处理程序(这对于其他原因也很有用)。首先,创建一个函数来处理错误并将其输出到控制台(以及您想用它做的任何其他事情):
void uncaughtExceptionHandler(NSException *exception) {
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
// Internal error reporting
}
Next, add the exception handler to your app delegate:
接下来,将异常处理程序添加到您的应用程序委托:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
// Normal launch stuff
}
That's it!
就是这样!
If this doesn't work, then there are only two possible reasons:
如果这不起作用,那么只有两个可能的原因:
- Something is overwriting your
NSSetUncaughtExceptionHandler
call (there can be only one handler for your entire app). For example, some 3rd party libraries set their own uncaughtExceptionHandler. So, try setting it at the END of yourdidFinishLaunchingWithOptions
function (or selectively disabling 3rd party libraries). Or better yet, set a symbolic break point onNSSetUncaughtExceptionHandler
to quickly see who is calling it. What you may want to do is to modify your current one rather than adding another one. - You're not actually encountering an exception (for example,
EXC_BAD_ACCESS
is notan exception; credit to @Erik B's comments, below)
- 有些东西正在覆盖您的
NSSetUncaughtExceptionHandler
调用(整个应用程序只能有一个处理程序)。例如,一些 3rd 方库设置了自己的 uncaughtExceptionHandler。因此,请尝试在didFinishLaunchingWithOptions
函数的末尾设置它(或有选择地禁用 3rd 方库)。或者更好的是,设置一个符号断点NSSetUncaughtExceptionHandler
以快速查看谁在调用它。您可能想要做的是修改当前的一个,而不是添加另一个。 - 你没有真正遇到异常(例如,
EXC_BAD_ACCESS
是不是一个例外;信贷@Erik B的评论,下同)
回答by WiseOldDuck
There is a useful option of adding an Exception Breakpoint (using the + at the bottom of the Breakpoint Navigator). This will break on any Exception (or you can set conditions). I don't know if this choice is new in 4.2 or if I only finally noticed it trying to workaround the missing symbols problem.
有一个添加异常断点的有用选项(使用断点导航器底部的 +)。这将在任何异常时中断(或者您可以设置条件)。我不知道这个选择是否是 4.2 中的新选择,或者我是否只是最终注意到它试图解决丢失符号的问题。
Once you hit this breakpoint you can use the Debug Navigator to navigate the call stack, examine variables, etc as usual.
一旦你遇到这个断点,你就可以像往常一样使用调试导航器来导航调用堆栈、检查变量等。
If you do want a symbolicated call stack suitable for copy/pasting or the like, gdb backtrace will work fine from there:
如果您确实想要一个适合复制/粘贴等的符号化调用堆栈,gdb 回溯将从那里正常工作:
(gdb) bt
#0 0x01f84cf0 in objc_exception_throw ()
#1 0x019efced in -[NSObject doesNotRecognizeSelector:] ()
(etc)
(等等)
回答by Pedro
There is a new feature on the debugger. You can set a break point whenever a exception is thrown and stop the execution right there, just as it used to happen on 4.0.
调试器中有一项新功能。您可以在抛出异常时设置断点并立即停止执行,就像在 4.0 上发生的那样。
On the "Breakpoint Navigator", add a "Exception Breakpoint" and just press "Done" on the options popup.
在“断点导航器”上,添加一个“异常断点”,然后在选项弹出窗口中按“完成”。
That's all!
就这样!
PS: In some cases would be better to break only for Objective-C exceptions.
PS:在某些情况下,仅针对 Objective-C 异常中断会更好。
回答by Alexander
Here is one more solution, not so elegant as previous, but if you didn't add exception breakpoints or handlers, it can be only one way to go.
When app crashes, and you get your raw first throw call stack(in hex numbers), type into Xcode console info line *hex
(don't forget star and 0x
hex specifier), for example:
这里还有一个解决方案,不像以前那么优雅,但如果你没有添加异常断点或处理程序,它可能只是一种方法。
当应用程序崩溃,并且您获得原始的第一个 throw 调用堆栈(以十六进制数表示)时,请在 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>.
If you are using lldb, you can type image lookup -a hex
(without star in this situation), and you get similar output.
如果您使用的是lldb,您可以输入image lookup -a hex
(在这种情况下不带星号),您会得到类似的输出。
With this method, you can traverse from top of the throw stack (there will be about 5-7 system exception propagators) to your function which caused a crash, and determine exact file and line of code.
使用此方法,您可以从抛出堆栈的顶部(将有大约 5-7 个系统异常传播器)遍历导致崩溃的函数,并确定确切的文件和代码行。
Also, for similar effect you can use atos utility in terminal, just type:
此外,为了获得类似的效果,您可以在终端中使用 atos 实用程序,只需键入:
atos -o path/to/AplicationBundle.app/Executable 0xAdress1 0xAdress2 0xAdress3 ...
and you get symbolicated stack trace (at least for functions you have debug symbols).
This method is more preferable, because you don't have for each adress call info line
, just copy adresses from console output and paste them into terminal.
你会得到符号化的堆栈跟踪(至少对于你有调试符号的函数)。这种方法更可取,因为您不需要为每个地址调用info line
,只需从控制台输出复制地址并将它们粘贴到终端中。
回答by MonsieurDart
You can add an Exception Breakpoint(using the + at the bottom of the Breakpoint Navigator) and add the actionbt
to it (click the Add Action button, select Debugger Command, enter "bt" in the text field). This will display the stack trace as soon as an exception is thrown.
您可以添加一个异常断点(使用在断点导航器底部的+),并添加动作bt
给它(点击添加操作按钮,选择调试器命令,输入“BT”在文本字段)。一旦抛出异常,这将显示堆栈跟踪。
回答by Matt Connolly
At Xcode's debug console prompt type:
在 Xcode 的调试控制台提示符下键入:
image lookup -a 0x1234
image lookup -a 0x1234
And it will show you something like:
它会向你展示类似的东西:
Address: MyApp[0x00018eb0] (MyApp.__TEXT.__text + 91088)
Summary: MyApp`-[MyViewController viewDidAppear:] + 192 at MyViewController.m:202
回答by logancautrell
This is a common problem, not getting stack traces in 4.2. You can try swapping between LLDB and GDB to see if you get better results.
这是一个常见问题,在 4.2 中没有获取堆栈跟踪。您可以尝试在 LLDB 和 GDB 之间进行交换,看看是否能获得更好的结果。
File a bug report here.
在此处提交错误报告。
http://developer.apple.com/bugreporter/
http://developer.apple.com/bugreporter/
EDIT:
编辑:
I believe that if you swap back to LLVM GCC 4.2 you'll not see this happen. You may lose features you need though.
我相信如果你换回 LLVM GCC 4.2 你不会看到这种情况发生。但是,您可能会丢失所需的功能。
回答by wilson lin
Use this code in your main function:
在您的主函数中使用此代码:
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;
}
回答by Bradweiser86
Turning 'Compile for Thumb' back on (debug configuration) worked for me.
重新打开“为 Thumb 编译”(调试配置)对我有用。