iphone - 为什么此代码会导致 "EXC_BAD_INSTRUCTION"?

标签 iphone ios grand-central-dispatch

dispatch_semaphore_t aSemaphore = dispatch_semaphore_create(1);        
dispatch_semaphore_wait(aSemaphore, DISPATCH_TIME_FOREVER);
dispatch_release(aSemaphore);

当程序运行到dispatch_release(aSemaphore)时,会导致“EXC_BAD_INSTRUCTION”,然后崩溃。为什么?

最佳答案

我试过这段代码,它确实死于非法指令。所以我做了一些挖掘,发现它在 _dispatch_semaphore_dispose 中消失了。那么让我们看看那是什么(这里是 ARMv7,因为它很容易理解!):

__dispatch_semaphore_dispose:
000040a0            b590        push    {r4, r7, lr}
000040a2            4604        mov     r4, r0
000040a4            af01        add     r7, sp, #4
000040a6        e9d40108        ldrd    r0, r1, [r4, #32]
000040aa            4288        cmp     r0, r1
000040ac            da00        bge.n   0x40b0
000040ae            defe        trap
...

它死于 0x40ae,这是一个 duff 指令放在那里,如果 bge.n 没有让我们跳转跳过它,它就会崩溃。

失败的原因是 r0 必须小于 r1r0r1 是从 r4 + 32 的内存中加载的,我 r4 是示例代码中的 aSemaphore,即传递给 dispatch_semaphore_release 的东西。 + 32 表示它正在将 32 个字节读入 aSemaphore 指向的结构(它是指向 dispatch_semaphore_s 结构的指针)。所以总的来说它在做什么它从 aSemaphore + 32 读取 4 个字节并将它们放入 r0 并从 aSemaphore + 36 读取 4 个字节并将它们放入进入 r1

然后比较有效地比较 aSemaphore + 32aSemaphore + 36 的值。阅读 dispatch_semaphore_create 的作用,我可以看到它存储了传递给 aSemaphore + 32aSemaphore + 36 的值。我还发现 dispatch_semaphore_waitdispatch_semaphore_signal 触及 aSemaphore + 32 处的值,以增加和减少它。这意味着它中断的原因是信号量的当前值小于传递给 dispatch_semaphore_create 的值。因此,当当前值小于创建时所用的值时,您无法处理信号量。

如果你读到这里并理解了我的胡言乱语,那就太好了!希望对您有所帮助!

更新:

最好在此处查看源代码(由 JustSid 指出)- http://opensource.apple.com/source/libdispatch/libdispatch-187.7/src/semaphore.c - 查看我们看到的 _dispatch_semaphore_dispose 函数:

if (dsema->dsema_value < dsema->dsema_orig) {
    DISPATCH_CLIENT_CRASH("Semaphore/group object deallocated while in use");
}

所以,是的,就是这样,这就是它崩溃的原因!

关于iphone - 为什么此代码会导致 "EXC_BAD_INSTRUCTION"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8287621/

相关文章:

ios - 无法将 'gym info' 值分配给 ' strings' 类型的值,这是什么问题?

ios - swift3 CoreData 获取返回 nil

ios - @synchronized block 与 GCD dispatch_async()

ios - 为什么 tableview 单元格在要重复使用时开始闪烁?

iphone - 如何用项目构建ZBar SDK而不是使用静态库?

iphone - 从终端 (Bash) 将应用程序内购买的 xcodeproj 转换为 pkg 文件,或者如何将 xcarchive 文件转换为 pkg 文件?

ios - dispatch_barrier_async 不等待 CoreImage 完成处理

ios - 对方法进行排队,以便在 iOS 应用程序中更快地加载 View

iphone - 内购恢复

html - iPhone 邮件 : table doesn't stretch to 100% because of an anchor tag?