迁移后,奇怪的核心数据因 _Unwind_SjLj_Resume 崩溃
我的一些 Beta 测试人员发生了奇怪的崩溃,我遇到了麻烦。符号化的崩溃报告表明崩溃发生在 init 调用时将控制器作为单例进行简单分配时,但根据堆栈跟踪,我在 init
中的代码似乎是实际上并不是崩溃的地方。这是相关代码:
1534| + (UA[REDACTED]PlayerController*)sharedInstance
1535| {
1536| @synchronized(self)
1537| {
1538| if (sharedInstance == nil)
1539| sharedInstance = [[UA[REDACTED]PlayerController alloc] init];
1540| }
1541| return sharedInstance;
1542| }
这之前从未崩溃过,并且代码最近没有更改过。这是引发的堆栈跟踪:
Thread 5:
0 libSystem.B.dylib 0x33bd52d4 __kill + 8
1 libSystem.B.dylib 0x33bd52c4 kill + 4
2 libSystem.B.dylib 0x33bd52b6 raise + 10
3 libSystem.B.dylib 0x33be9d26 __abort + 62
4 libSystem.B.dylib 0x33be9d7e abort + 62
5 libSystem.B.dylib 0x33bd7980 __assert_rtn + 152
6 libgcc_s.1.dylib 0x32acab4e _Unwind_SjLj_Resume + 26
7 [REDACTED] 0x00060b64 +[UA[REDACTED]PlayerController sharedInstance] (UA[REDACTED]PlayerController.m:1540)
8 [REDACTED] 0x00063e6c -[UA[REDACTED]PlayerViewController setupControlViews] (UA[REDACTED]PlayerViewController.m:224)
9 [REDACTED] 0x00062ce0 -[UA[REDACTED]PlayerViewController viewDidLoad] (UA[REDACTED]PlayerViewController.m:268)
10 UIKit 0x320a0270 -[UIViewController view] + 104
…
关于这个神秘的崩溃是什么以及它可能来自哪里,有什么想法吗?
UPDATE 1
It appears it has to do with core data and migrations. I was able to duplicate it, but the root cause is still unknown. I have some automatic migrations that are in this version, and it appears that while some of the NSManagedObjects can be read, others are throwing this exception, particularly on a NSManagedObjects relationship. It might not be related to the
PlayerController
at all. Any Core-Data experts have some insight?UPDATE 2
Here is the call stack of the crash after I have found a way to reproduce it
and the relevant code:
if (resultArray && [resultArray count]) {
for (MixAudio *ma in resultArray) {
Audio *audio = [ma valueForKey:LOCAL_MIX_AUDIO_AUDIO_KEY];
if (audio) {
[returnArray addObject:audio];
}
}
为了帮助解释我做了什么来重现它,我必须解释一下数据结构。我有 Mix
和 Audio
项目。 Mixes 有很多 Audio,Audio 又属于很多 Mixes。这是对 MixAudio 对象的简单关系调用以获取音频。现在,只有在我将数据库恢复到新版本之后才发生崩溃。
我的设置中的数据库备份意味着压缩数据库以保存数据,然后在恢复时解压缩。此崩溃仅在恢复过程之后发生。让事情变得更复杂的是,有 3 个带有映射模型的数据库版本。因为这个过程在版本控制之前对我来说是有效的,所以我觉得我的版本中的某些东西导致了这次崩溃。
所有其他数据都很好,可以访问,甚至可以保存。不知何故,这个单一的提取引起了问题。设置持久存储或托管对象模型时不会出现错误或警告。此外,可以很好地创建和访问新的 Mix 对象,只有旧的提取(恢复之前位于数据库中)会失败。
如果我没有发现错误,控制台会打印:
Assertion failed: (_Unwind_SjLj_Resume() can't return), function _Unwind_SjLj_Resume, file /SourceCache/libunwind/libunwind-24.1/src/Unwind-sjlj.c, line 326.
在崩溃行周围放置一个 try/catch
可以让我检查根本崩溃原因:
Error: NSRangeException: *** -[NSMutableArray objectAtIndex:]: index 4294967295 beyond bounds [0 .. 16]
但这没有任何意义(至少对我来说)一个简单的 valueForKey
调用。 4294967295 = 2^32-1 这意味着索引 var 可能设置为 -1(如果有帮助的话)。我在这里迷路了。
[SOLVED] UPDATE 3
I was right about it being in the versioning :) I reread the section on versioning in Zarra's book and had a major DOH moment. This is the first time I have ever had an app with 3 database versions. I am using Mapping Models in my app and I naively assumed that core data would be able to map from 1-2 using one model, then 2-3 using the next. I literally hit my head when I realized I did not have a 1-3 mapping model. to test it out, I added one quickly and everything is as smooth as butter. Now I just have to go back and use his
Progressive Data Migration
samples to make my life easier as I go on with more version of this DB.我希望扎拉开车经过这里并回答一些问题……任何问题……这样我就可以为此给他加分:)
I am getting a strange crash from some of my beta testers that I am having trouble with. The symbolicated crash reports indicate that the crash is occurring in the simple allocation of a controller as a singleton, at the init call, but according to the stack trace, it appears that the code I have in init
is not actually where the crash is. Here is the relevant code:
1534| + (UA[REDACTED]PlayerController*)sharedInstance
1535| {
1536| @synchronized(self)
1537| {
1538| if (sharedInstance == nil)
1539| sharedInstance = [[UA[REDACTED]PlayerController alloc] init];
1540| }
1541| return sharedInstance;
1542| }
This has never crashed before, and the code has not changed anytime recently. Here is the raised stack trace:
Thread 5:
0 libSystem.B.dylib 0x33bd52d4 __kill + 8
1 libSystem.B.dylib 0x33bd52c4 kill + 4
2 libSystem.B.dylib 0x33bd52b6 raise + 10
3 libSystem.B.dylib 0x33be9d26 __abort + 62
4 libSystem.B.dylib 0x33be9d7e abort + 62
5 libSystem.B.dylib 0x33bd7980 __assert_rtn + 152
6 libgcc_s.1.dylib 0x32acab4e _Unwind_SjLj_Resume + 26
7 [REDACTED] 0x00060b64 +[UA[REDACTED]PlayerController sharedInstance] (UA[REDACTED]PlayerController.m:1540)
8 [REDACTED] 0x00063e6c -[UA[REDACTED]PlayerViewController setupControlViews] (UA[REDACTED]PlayerViewController.m:224)
9 [REDACTED] 0x00062ce0 -[UA[REDACTED]PlayerViewController viewDidLoad] (UA[REDACTED]PlayerViewController.m:268)
10 UIKit 0x320a0270 -[UIViewController view] + 104
…
Any ideas as to what this cryptic crash is and where it might be coming from?
UPDATE 1
It appears it has to do with core data and migrations. I was able to duplicate it, but the root cause is still unknown. I have some automatic migrations that are in this version, and it appears that while some of the NSManagedObjects can be read, others are throwing this exception, particularly on a NSManagedObjects relationship. It might not be related to the
PlayerController
at all. Any Core-Data experts have some insight?UPDATE 2
Here is the call stack of the crash after I have found a way to reproduce it
and the relevant code:
if (resultArray && [resultArray count]) {
for (MixAudio *ma in resultArray) {
Audio *audio = [ma valueForKey:LOCAL_MIX_AUDIO_AUDIO_KEY];
if (audio) {
[returnArray addObject:audio];
}
}
To help explain what I did to reproduce it, I have to explain the data structure a little. I have Mix
and Audio
items. Mixes have many Audio, Audio belongs to many Mixes. This is a simple relationship call on the MixAudio objects to get the Audio. Now, this has only been crashing here after I do a database restore to the new version.
Database backups in my setup means zipping up the database to save the data, then unzipping on restore. This crash only happens after the restore process. To make things more complicated, there are 3 database versions with mapping models. Because this process worked for me before the versioning, I feel that something in my versions is causing this crash.
All other data is fine and can be accessed, even saved. Somehow, this single fetch is causing issues. There are no errors or warnings when setting up the persistent store or managed object model. Furthermore, new Mix objects can be created and accessed fine, only older fetches (that were in the DB before the restore) are failing.
If I don't catch the error, the console prints:
Assertion failed: (_Unwind_SjLj_Resume() can't return), function _Unwind_SjLj_Resume, file /SourceCache/libunwind/libunwind-24.1/src/Unwind-sjlj.c, line 326.
Putting a try/catch
around the crashing line allows me to inspect the root crash cause:
Error: NSRangeException: *** -[NSMutableArray objectAtIndex:]: index 4294967295 beyond bounds [0 .. 16]
but this makes no sense (to me at least) for a simple valueForKey
call. 4294967295 = 2^32-1 which means the index var was probably set to −1 if that helps. I am lost here.
[SOLVED] UPDATE 3
I was right about it being in the versioning :) I reread the section on versioning in Zarra's book and had a major DOH moment. This is the first time I have ever had an app with 3 database versions. I am using Mapping Models in my app and I naively assumed that core data would be able to map from 1-2 using one model, then 2-3 using the next. I literally hit my head when I realized I did not have a 1-3 mapping model. to test it out, I added one quickly and everything is as smooth as butter. Now I just have to go back and use his
Progressive Data Migration
samples to make my life easier as I go on with more version of this DB.I am hoping Zarra drives by here and answers something… anything… so I can give him the points for this :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
虽然OP能够解决他自己的问题,但对迁移有一个清晰的了解是有帮助的。
当您创建数据模型的第二个版本时,您需要一个从版本一到版本二的映射模型。
当您创建第三个模型时,您需要一个从一到二的映射模型和一个从一到三的映射。
当您添加第四个模型时,您需要以下模型:
从那里开始会取得更多进展。
While the OP was able to solve his own question, it is helpful to have a clear understanding of migrations.
When you create a second version of your data model, you need a mapping model from version one to version two.
When you create a third model you need a mapping model from one to two AND a map from one to three.
When you add a fourth model you need the following models:
And it gets more progress from there.