GCD dispatch_after调用导致SIGBUS信号 [英] GCD dispatch_after call causing SIGBUS signal

查看:253
本文介绍了GCD dispatch_after调用导致SIGBUS信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在加载我的应用程序以执行某些行为时,我正在使用GCD的dispatch_after方法.预期的行为是从applicationDidFinishLaunchingWithOptions末尾等待3秒以执行在后台队列中运行的选择器.

I'm using GCD's dispatch_after method when my application is being loaded to perform some behavior. The intended behavior is to wait 3 seconds from the end of applicationDidFinishLaunchingWithOptions to perform a selector that runs in a background queue.

我在测试设备上没有遇到任何崩溃,但是我有未捕获的SIGBUS信号的用户崩溃报告,原因是BUS_ADRALN异常.根据我对这段代码的了解,BUS_ADRALN错误表示地址对齐错误.

I haven't experienced any crashes on my test devices, but I have user crash reports of uncaught SIGBUS signals, the cause being a BUS_ADRALN exception. From my understanding of this code, a BUS_ADRALN error indicates an address alignment error.

这是我创建计时器的方式:

This is how I'm creating my timer:

double delayInSeconds = 3.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),
                     ^(void){
                         [self methodToPerformInBackground];
                     });

是什么原因导致此崩溃?

What could be causing this crash?

由于多线程错误可能是一种奇怪的野兽,因此我将抛出一些我一直在脑海中盘旋的想法.

Since multithreading errors can be a strange sort of beast, I'm going to throw out some ideas that I've been tossing around in my head.

  • 我正在通过对[self performSelectorOnMainThread:withObject:waitUntilDone]的调用来称呼它.在以这种方式选择的选择器中执行此操作是否有问题?
  • 由于我正在调用dispatch_get_global_queue而不是dispatch_create_queue,因此不需要保留此方法返回的队列.这个推理正确吗?
  • 在此代码中,self是应用程序委托.在应用程序进入后台或终止后尝试执行该块是否会导致崩溃?该应用程序在关闭时会自动清理所有已调度的块吗?
  • 被调用的方法内部发生问题导致崩溃,但是GCD并未为其提供堆栈跟踪.
  • I'm calling this from within a call to [self performSelectorOnMainThread:withObject:waitUntilDone]. Is there something problematic about doing this within a selector called this way?
  • Since I'm calling dispatch_get_global_queue and not dispatch_create_queue, I don't need to retain the queue returned by this method. Is this reasoning correct?
  • In this code, self is the application delegate. Could the crash be caused trying to perform the block after the application enters the background or terminates? Would the application automatically clean up any dispatched blocks upon closing?
  • Something inside the method being called is causing the crash, but GCD doesn't provide a stack trace to it.

编辑:我宁愿不要在代码块中包含被调用的代码,因为无论如何我都不认为这是主要问题.这是堆栈跟踪.线程0崩溃导致问题似乎出在GCD中,而不是块中调用的代码.

I'd rather not include the code that's called in the block, since I'm not convinced that's the main problem anyway. Here is the stack trace. The crash on thread 0 makes it seem as though the issue was in GCD, not the code called in the block.

编辑#2:在查看更多崩溃报告后,我有一个奇怪的消息要分享.仅当运行iOS 4.2.X及更低版本的用户出现此崩溃.由于iOS 4.0及更高版本支持GCD,因此我猜想在4.3中存在一个错误.

Edit #2: I have strange news to share after going through more crash reports. This crash is only appearing for users running iOS 4.2.X and below. Since GCD is supported for iOS 4.0 and later, my guess is there was a bug patched in 4.3.

Thread 0 Crashed:
0  libSystem.B.dylib                  0x35e5fb10 _dispatch_retain + 0
1  libSystem.B.dylib                  0x35e5df8c dispatch_after_f + 80
2  libSystem.B.dylib                  0x35e5e070 dispatch_after + 72
3  MyApplication                              0x0000466c -[MyApplicationDelegate applicationDidFinishLaunchingPart2:] (MyApplicationDelegate.m:366)
4  CoreFoundation                      0x37538f79 -[NSObject(NSObject) performSelector:withObject:] + 25
5  Foundation                          0x35171e6d __NSThreadPerformPerform + 273
6  CoreFoundation                      0x375518d1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
7  CoreFoundation                      0x37521ecd __CFRunLoopDoSources0 + 385
8  CoreFoundation                      0x375216f9 __CFRunLoopRun + 265
9  CoreFoundation                      0x3752150b CFRunLoopRunSpecific + 227
10  CoreFoundation                      0x37521419 CFRunLoopRunInMode + 61
11  GraphicsServices                    0x33e76d24 GSEventRunModal + 196
12  UIKit                              0x3591d57c -[UIApplication _run] + 588
13  UIKit                              0x3591a558 UIApplicationMain + 972
14  MyApplication                              0x00003024 main (main.m:113)

Thread 1:
0  libSystem.B.dylib                  0x35d8f974 kevent + 24
1  libSystem.B.dylib                  0x35e5dd70 _dispatch_queue_invoke + 104
2  libSystem.B.dylib                  0x35e5d790 _dispatch_worker_thread2 + 128
3  libSystem.B.dylib                  0x35de6978 _pthread_wqthread + 400

Thread 2:
0  libSystem.B.dylib                  0x35de72fc __workq_kernreturn + 8

Thread 3:
0  libSystem.B.dylib                  0x35d5b3b0 mach_msg_trap + 20
1  CoreFoundation                      0x37521f83 __CFRunLoopServiceMachPort + 95
2  CoreFoundation                      0x37521787 __CFRunLoopRun + 407
3  CoreFoundation                      0x3752150b CFRunLoopRunSpecific + 227
4  CoreFoundation                      0x37521419 CFRunLoopRunInMode + 61
5  WebCore                            0x3318bd1c _ZL12RunWebThreadPv + 532
6  libSystem.B.dylib                  0x35de5b4c _pthread_start + 372

Thread 4:
0  libSystem.B.dylib                  0x35d5b3b0 mach_msg_trap + 20
1  CoreFoundation                      0x37521f83 __CFRunLoopServiceMachPort + 95
2  CoreFoundation                      0x37521787 __CFRunLoopRun + 407
3  CoreFoundation                      0x3752150b CFRunLoopRunSpecific + 227
4  CoreFoundation                      0x37521419 CFRunLoopRunInMode + 61
5  Foundation                          0x3517ec55 +[NSURLConnection(NSURLConnectionReallyInternal) _resourceLoadLoop:] + 217
6  Foundation                          0x3515cb91 -[NSThread main] + 49
7  Foundation                          0x35155b97 __NSThread__main__ + 915
8  libSystem.B.dylib                  0x35de5b4c _pthread_start + 372

推荐答案

DISPATCH_QUEUE_PRIORITY_BACKGROUND是iOS 5.0及更高版本的功能.如果您尝试在iOS 4.x上使用它,则它将为NULL(当您尝试保留它时,它将崩溃,因为GCD是C库,并且使用NULL的方式使用<<目标c)中的c7>.有关更多信息,请参见此答案.解决方案是改用低优先级,或使用预处理程序指令在两者之间切换.

DISPATCH_QUEUE_PRIORITY_BACKGROUND is an iOS 5.0+ feature. If you try to use it on iOS 4.x it will be NULL (which will crash when you try to retain it, since GCD is a C-library and it is not safe to use NULL the way it is to use nil in objective-c). See this answer for more info. The solution is to use low priority instead, or use preprocessor directives to switch between the two.

这篇关于GCD dispatch_after调用导致SIGBUS信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆