iOS 应用程序中 _class_initialize 中的 semaphore_wait_signal_trap 死锁

发布于 2024-10-29 05:54:56 字数 1548 浏览 2 评论 0原文

我的一个实体托管对象需要设置一个仅运行时的树状结构,其中节点是 NSObject 的子类(它们不是托管对象)。

我在两个地方设置了该结构(从而分配了一堆这些节点):

  • 当创建一个新的此类托管对象时:一切正常。
  • 当读回现有的托管对象时,在其 awakeFromFetch 方法中。

这就是我遇到问题的地方:对 Node *newNode = [Node alloc]; 的调用永远不会返回。我可以使用调试器中断,并且代码卡在 semaphore_wait_signal_trap 中。这是完整的调用堆栈:

#0  0x937ac0e2 in semaphore_wait_signal_trap ()
#1  0x937b1be6 in pthread_mutex_lock ()
#2  0x01881c73 in _class_initialize ()
#3  0x0188973f in prepareForMethodLookup ()
#4  0x01880069 in lookUpMethod ()
#5  0x018801d6 in _class_lookupMethodAndLoadCache ()
#6  0x018930e3 in objc_msgSend ()
#7  0x000957d8 in -[MyEntity awakeFromFetch] at MyEntity:114

所以看来我的 Node 类无法初始化。事实上,这是本次会议中第一次使用 Node 类。为了检查这一点,我在应用程序启动时插入了单个 Node 的虚假分配。即调用成功,现在上述问题消失了。

但是,我不满意,有两个原因:

1-我仍然不明白为什么在 awakeFromFetch 中第一次分配 Node 失败。如果我不明白错误发生的原因以及为什么修复是实际的修复,我不会认为错误已修复。

2- 现在,当第一次使用另一个类时,应用程序会稍晚崩溃,这次不是在任何awakeFromFetch中。

很明显,我的问题与 awakeFromFetch 或 Core Data 无关。不知何故,我的 Objective-C 运行时行为异常,我不知道为什么。

简单的问题:什么会导致 _class_initialize 导致 p 线程死锁?

事实上,谷歌搜索 semaphore_wait_signal_trap 会产生很多结果,全部与 pthreads 相关,很少与 iOS/Objective-C/Cocoa 相关。

请注意,我在这里根本不使用线程。

我很困惑。知道如何调试这个吗?

编辑:永远不会返回的源代码行是:

Node *newNode = [[Node alloc] init];

为了找出发生了什么,我将其分成两部分:

Node *newNode = [Node alloc];
newNode = [newNode init];

问题发生在这两行中的第一行。

One of my entity managed objects need to setup a runtime-only tree-like structure where nodes are subclasses of NSObject (they are not managed object).

I setup that structure (and thus allocates a bunch of those nodes) in two places:

  • when creating a new such managed object: everything is working fine.
  • when reading back an existing managed object, in its awakeFromFetch method.

That's where I have my problem: the call to Node *newNode = [Node alloc]; never returns. I can break using the debugger, and the code is stuck in semaphore_wait_signal_trap. Here is the full call stack:

#0  0x937ac0e2 in semaphore_wait_signal_trap ()
#1  0x937b1be6 in pthread_mutex_lock ()
#2  0x01881c73 in _class_initialize ()
#3  0x0188973f in prepareForMethodLookup ()
#4  0x01880069 in lookUpMethod ()
#5  0x018801d6 in _class_lookupMethodAndLoadCache ()
#6  0x018930e3 in objc_msgSend ()
#7  0x000957d8 in -[MyEntity awakeFromFetch] at MyEntity:114

So it seems my Node class fails to initialize. Indeed, this is the very first use of the Node class in this session. To check that, I inserted a spurious allocation of a single Node at application startup time. That calls succeeds, and now the above problem disappears.

However, I am not satisfied, for two reasons:

1- I still don't understand why allocating a Node for the first time in awakeFromFetch fails. And I don't consider a bug fixed if I don't understand why it occurred and why the fix is an actual fix.

2- The application now crashes slightly later when using another class for the first time, this time not in any awakeFromFetch.

So clearly my problem is not related to awakeFromFetch nor Core Data. Somehow, my Objective-C runtime is misbehaving, I don't know why.

Simple question: what could lead _class_initialize to p-thread deadlock?

Indeed googling for semaphore_wait_signal_trap yields many hits, all related to pthreads, few related to iOS/Objective-C/Cocoa.

Note that I don't use threads at all here.

I'm puzzled. Any idea how to debug this?

Edit: the source line that never returns was:

Node *newNode = [[Node alloc] init];

To find out what's going on, I split it in two:

Node *newNode = [Node alloc];
newNode = [newNode init];

The problems occurs on the first of those two lines.

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

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

发布评论

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

评论(2

≈。彩虹 2024-11-05 05:54:56

Apple关于-[NSManagedObject awakeFromFetch] 说:

重要:子类必须在执行自己的初始化之前调用父类的实现。

你这样做了吗?

然而,即使这解决了你的问题,我也不知道为什么;)

Apple's document about -[NSManagedObject awakeFromFetch] said that:

Important: Subclasses must invoke super’s implementation before performing their own initialization.

Did you do that?

However, even if this solve your problem, I don't know why ;)

甜是你 2024-11-05 05:54:56

好吧,我清理了所有目标,然后重建了。没有任何改善。
然后我删除了 Xcode 的 Derived Data 目录,你瞧,问题就消失了。

合理的结论是假设 Xcode 4 中存在一些故障。

我什至不会尝试解释所有损失的时间。

Well, I cleaned all my targets, and rebuilt. No improvement.
Then I deleted Xcode's Derived Data directory, and lo and behold, the problem went away.

The reasonable conclusion is to assume some glitch/but in Xcode 4.

I will not even try to account for all the lost hours.

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