Xcode 4.2 调试不表示堆栈调用

发布于 2024-12-11 11:26:42 字数 437 浏览 0 评论 0原文

我在 iOS 5 模拟器/设备中进行 Xcode 4.2 调试时遇到问题。正如预期的那样,以下代码崩溃了:

NSArray *arr=[NSArray array];
[arr objectAtIndex:100];

在 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)

谢谢。

I have a problem with Xcode 4.2 debugging in an iOS 5 simulator/device. The following code crashes, as expected:

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:

*** First throw call stack:
(0x16b4052 0x1845d0a 0x16a0674 0x294c 0x6f89d6 0x6f98a6 0x708743 0x7091f8 0x7fcaa9 0x2257fa9 0x16881c5 0x15ed022 0x15eb90a 0x15eadb4 0x15eaccb 0x6f02a7 0x6faa93 0x2889 0x2805)

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

朦胧时间 2024-12-18 11:26:42

我尝试过的任何方法都无法解决此问题(尝试了两个编译器、两个调试器等)
为 iOS 5 更新升级 XCode 后,堆栈跟踪似乎不起作用。

然而,我找到了一个有效的解决方法 - 创建我自己的异常处理程序(由于其他原因这也很有用)。首先,创建一个函数来处理错误并将其输出到控制台(以及您想要用它执行的任何其他操作):

void uncaughtExceptionHandler(NSException *exception) {
    NSLog(@"CRASH: %@", exception);
    NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
    // Internal error reporting
}

接下来,将异常处理程序添加到您的应用程序委托:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{   
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
    // Normal launch stuff
}

就是这样!

如果这不起作用,则只有两个可能的原因

  1. 某些内容正在覆盖您的 NSSetUncaughtExceptionHandler 调用(整个应用程序只能有一个处理程序)。例如,一些第三方库设置自己的uncaughtExceptionHandler。因此,请尝试在 didFinishLaunchingWithOptions 函数的末尾设置它(或有选择地禁用第 3 方库)。或者更好的是,在 NSSetUncaughtExceptionHandler 上设置一个符号断点,以快速查看是谁在调用它。您可能想要做的是修改当前的而不是添加另一个。
  2. 您实际上并没有遇到异常(例如,EXC_BAD_ACCESS不是异常;归功于下面@Erik B 的评论)

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.

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:

  1. 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 your didFinishLaunchingWithOptions function (or selectively disabling 3rd party libraries). Or better yet, set a symbolic break point on NSSetUncaughtExceptionHandler to quickly see who is calling it. What you may want to do is to modify your current one rather than adding another one.
  2. You're not actually encountering an exception (for example, EXC_BAD_ACCESS is not an exception; credit to @Erik B's comments, below)
北音执念 2024-12-18 11:26:42

有一个有用的选项可以添加异常断点(使用断点导航器底部的 +)。这将在任何异常时中断(或者您可以设置条件)。我不知道这个选择是 4.2 中的新选择还是我最后才注意到它试图解决丢失符号的问题。

一旦到达此断点,您就可以像往常一样使用调试导航器导航调用堆栈、检查变量等。

如果您确实想要一个适合复制/粘贴等的符号调用堆栈,gdb 回溯将从那里正常工作:(

(gdb) bt
#0  0x01f84cf0 in objc_exception_throw ()
#1  0x019efced in -[NSObject doesNotRecognizeSelector:] ()

等)

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.

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) bt
#0  0x01f84cf0 in objc_exception_throw ()
#1  0x019efced in -[NSObject doesNotRecognizeSelector:] ()

(etc)

一向肩并 2024-12-18 11:26:42

调试器有一个新功能。每当抛出异常时,您都可以设置一个断点并立即停止执行,就像在 4.0 上发生的那样。

在“断点导航器”上,添加一个“异常断点”,然后在弹出的选项中按“完成”。

就这样!

PS:在某些情况下,最好只针对 Objective-C 异常进行中断。

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.

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.

很糊涂小朋友 2024-12-18 11:26:42

这是另一种解决方案,不像以前那么优雅,但如果您没有添加异常断点或处理程序,它可能只是一种方法。
当应用程序崩溃时,您会得到原始的第一次抛出调用堆栈(以十六进制数字表示),在 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>.

如果您使用 lldb,则可以键入 image Lookup -a hex (在这种情况下不带星号),然后你会得到类似的输出。

使用此方法,您可以从抛出堆栈的顶部(大约有 5-7 个系统异常传播器)遍历导致崩溃的函数,并确定确切的文件和代码行。

另外,为了获得类似的效果,您可以在终端中使用 atos 实用程序,只需键入:

atos -o path/to/AplicationBundle.app/Executable 0xAdress1 0xAdress2 0xAdress3 ...

即可获得符号化堆栈跟踪(至少对于具有调试符号的函数)。
这种方法更可取,因为您不必为每个地址调用 info line,只需从控制台输出复制地址并将其粘贴到终端中即可。

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:

(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.

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.

Also, for similar effect you can use atos utility in terminal, just type:

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.

时光病人 2024-12-18 11:26:42

您可以添加异常断点(使用断点导航器底部的+)并向其添加操作 bt(单击添加操作按钮,选择调试器命令,在文本字段中输入“bt”)。一旦抛出异常,就会显示堆栈跟踪。

You can add an Exception Breakpoint (using the + at the bottom of the Breakpoint Navigator) and add the action bt 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.

戏舞 2024-12-18 11:26:42

这是一个常见问题,在 4.2 中无法获取堆栈跟踪。您可以尝试在 LLDB 和 GDB 之间交换,看看是否能获得更好的结果。

在此提交错误报告。

http://developer.apple.com/bugreporter/

编辑:

我相信如果你换回LLVM GCC 4.2 你不会看到这种情况发生。但您可能会失去所需的功能。

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.

File a bug report here.

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.

彡翼 2024-12-18 11:26:42

在您的 main 函数中使用此代码:

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;
}

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;
}
后eg是否自 2024-12-18 11:26:42

在 Xcode 的调试控制台提示符处输入:

图像查找-a 0x1234

它会向您显示类似以下内容:

  Address: MyApp[0x00018eb0] (MyApp.__TEXT.__text + 91088)
  Summary: MyApp`-[MyViewController viewDidAppear:] + 192 at MyViewController.m:202

At Xcode's debug console prompt type:

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
烂柯人 2024-12-18 11:26:42

重新打开“Compile for Thumb”(调试配置)对我有用。

Turning 'Compile for Thumb' back on (debug configuration) worked for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文