为什么此代码会导致“EXC_BAD_INSTRUCTION”? [英] Why does this code cause "EXC_BAD_INSTRUCTION"?

查看:181
本文介绍了为什么此代码会导致“EXC_BAD_INSTRUCTION”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

When the program runs to dispatch_release(aSemaphore), it will cause "EXC_BAD_INSTRUCTION", and then crash. Why?

推荐答案

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

I tried this code and it does indeed die with illegal instruction. So I did some digging and found that it's dying in _dispatch_semaphore_dispose. So let's look at what that is (ARMv7 here, because it's easy to understand!):

__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 没有使它崩溃我们分支跳过它。

It dies at 0x40ae, which is a duff instruction put there so that it crashes if the bge.n doesn't make us branch to jump over it.

它失败的原因是因为 r0 必须小于 R1 r0 r1 从内存加载 r4 + 32 已经回到堆栈中来弄清楚我认为 r4 aSemaphore 在示例代码中,即传递到 dispatch_semaphore_release 的东西。 + 32 表示它正在读取 aSemaphore 指向的结构中的32个字节(它是指向<的指针code> dispatch_semaphore_s struct)。总的来说它正在从 aSemaphore + 32 读取4个字节并将它们放入 r0 并从<读取4个字节code> aSemaphore + 36 并将它们放入 r1

The reason it's failing is because r0 must be less than r1. r0 and r1 are loaded from the memory at r4 + 32 which having gone back up the stack to figure it out I think r4 is aSemaphore in the example code, i.e. the thing passed into dispatch_semaphore_release. The + 32 signifies it is reading 32 bytes into the struct that aSemaphore is pointing to (it's a pointer to a dispatch_semaphore_s struct). So overall what it's doing it reading 4 bytes from aSemaphore + 32 and putting them into r0 and reading 4 bytes from aSemaphore + 36 and putting them into r1.

比较然后有效地比较 aSemaphore + 32 aSemaphore + 36 的值。读取 dispatch_semaphore_create 我能看到它存储传递给 aSemaphore + 32 和<$ c $的值c> aSemaphore + 36 。我还发现 dispatch_semaphore_wait dispatch_semaphore_signal 触摸 aSemaphore + 32 ,增加和减少它。这意味着它破坏的原因是因为信号量的当前值小于传递给 dispatch_semaphore_create 的值。所以当当前值小于它创建的值时,你不能处理信号量。

The compare is then effectively comparing the value of aSemaphore + 32 and aSemaphore + 36. Reading what dispatch_semaphore_create does I can see that it stores the value passed in to both aSemaphore + 32 and aSemaphore + 36. I also found that dispatch_semaphore_wait and dispatch_semaphore_signal touch the value at aSemaphore + 32, to increment and decrement it. This means that the reason it's breaking is because the current value of the semaphore is less than the value passed into dispatch_semaphore_create. So you can't dispose of a semaphore when the current value is less than the value it was created with.

如果你读到这里并理解我的乱码那么做得好!希望它有所帮助!

If you've read to here and understood my ramblings then well done! Hope it helps!

更新:

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

It's probably better to look at the source (pointed out by JustSid) here - http://opensource.apple.com/source/libdispatch/libdispatch-187.7/src/semaphore.c - looking at the _dispatch_semaphore_dispose function we see:

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

所以,是的,你去了,这就是崩溃的原因!

So, yes, there you go, that's why it crashes!

这篇关于为什么此代码会导致“EXC_BAD_INSTRUCTION”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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