alex246 sent me some crash reports via email and that allowed me to better understand what’s going on here. It seems very likely that the immediate cause of this problem is that your app has run out of memory (specifically, usable address space). I’ll explain how I worked that out below, referencing the crash report that alex246 posted above [1].
First up, consider the backtrace of the crashing thread:
0 … MDPlistBufferConsume + 452 (MDPlistContainer.c:370)
1 … MDPlistBufferConsume + 440 (MDPlistContainer.c:370)
2 … _addGenericData + 268 (MDPlistContainer.c:1486)
3 … -[CSCoder encodeObject:] + 120 (CSCoder.m:408)
4 … -[NSDictionary(CSCoderAdditions) encodeKeysAndValuesWithCSCoder:filterBlock:] + 1012 (CSCoder.m:615)
5 … -[CSSearchableItemAttributeSet(CSCoderAdditions) encodeWithCSCoder:includeText:] + 548 (CSSearchableItemAttributeSet.m:3614)
6 … -[CSCoder encodeObject:] + 92 (CSCoder.m:406)
7 … __161-[CSSearchableIndex indexSearchableItems:deleteSearchableItemsWithIdentifiers:clientState:clientStateName:protectionClass:forBundleID:options:completionHandler:]_block_invoke + 1296 (CSSearchableIndex.m:796)
…
Clearly something has gone very wrong in
MDPlistBufferConsume
. I disassembled that routine to see what’s happening:
(lldb) disas -n MDPlistBufferConsume
MobileSpotlightIndex`MDPlistBufferConsume:
… <+0>: sub sp, sp, #0x80 ; =0x80
… <+4>: stp x26, x25, [sp, #0x30]
… <+8>: stp x24, x23, [sp, #0x40]
… <+12>: stp x22, x21, [sp, #0x50]
… <+16>: stp x20, x19, [sp, #0x60]
… <+20>: stp x29, x30, [sp, #0x70]
… <+24>: add x29, sp, #0x70 ; =0x70
… <+28>: mov x21, x1
…
… <+200>: str xzr, [sp, #0x28]
… <+204>: adrp x25, 146544
… <+208>: ldr x25, [x25, #0xb78]
… <+212>: ldr w0, [x25]
… <+216>: mov w3, #0x1000000
… <+220>: movk w3, #0x1
… <+224>: add x1, sp, #0x28 ; =0x28
… <+228>: mov x2, x23
… <+232>: bl 0x181ed0c70 ; vm_allocate
… <+236>: cbnz w0, 0x188d0adb8 ; <+372>
…
… <+340>: add x0, x8, x19
… <+344>: ldp x29, x30, [sp, #0x70]
… <+348>: ldp x20, x19, [sp, #0x60]
… <+352>: ldp x22, x21, [sp, #0x50]
… <+356>: ldp x24, x23, [sp, #0x40]
… <+360>: ldp x26, x25, [sp, #0x30]
… <+364>: add sp, sp, #0x80 ; =0x80
… <+368>: ret
… <+372>: bl 0x188d099e4 ; __si_assert_copy_extra.8141
… <+376>: mov x19, x0
… <+380>: adrp x8, 27
… <+384>: add x8, x8, #0x747 ; =0x747
… <+388>: cmp x19, #0x0 ; =0x0
… <+392>: csel x8, x19, x8, ne
… <+396>: adrp x9, 27
… <+400>: add x9, x9, #0xe7b ; =0xe7b
… <+404>: stp x9, x8, [sp, #0x10]
… <+408>: mov w8, #0x172
… <+412>: adrp x9, 27
… <+416>: add x9, x9, #0x748 ; =0x748
… <+420>: add x9, x9, #0x6a ; =0x6a
… <+424>: stp x9, x8, [sp]
… <+428>: bl 0x188d09a84 ; __message_assert.8145
… <+432>: mov x0, x19
… <+436>: bl 0x188d0e4a4 ; …
… <+440>: mov w8, #0xbad
… <+444>: mov w9, #-0x21530000
… <+448>: movk w9, #0xbeef
… <+452>: str w9, [x8]
… <+456>: bl 0x181e5ef30 ; abort
Note This disassembly is from 11.2.2, not from iOS 11.0 as shown by the crash report. However, one of the other crash reports that alex246 emailed me confirmed that the disassembly is basically the same on 11.2.1, and thus I’m going to presume that it hasn’t changed throughout the 11.x cycle.
The crash is reported at +452. This is clearly part of some ‘panic’ code, because the next instruction calls
abort
. And if you look at the instructions nearby (+440 through +452) you’ll see that they
specifically trigger a memory access exception by loading the address 0xbad into
x8
[2] and then writing 0xdeadbeef to it. That raises the questions of, “How did we get here?” and “What went wrong?”
If you look back through the disassembly you’ll see that the end of the main code is +368 and that this ‘panic’ code starts at +372. You can then look even further back to see that the only code that branches to +372 is +236. Here’s another copy of that code for easy reference:
… <+200>: str xzr, [sp, #0x28]
… <+204>: adrp x25, 146544
… <+208>: ldr x25, [x25, #0xb78]
… <+212>: ldr w0, [x25]
… <+216>: mov w3, #0x1000000
… <+220>: movk w3, #0x1
… <+224>: add x1, sp, #0x28 ; =0x28
… <+228>: mov x2, x23
… <+232>: bl 0x181ed0c70 ; vm_allocate
… <+236>: cbnz w0, 0x188d0adb8 ; <+372>
This calls
vm_allocate
and then branches to +372 if
vm_allocate
fails. The exact failure code goes into w0, which is lost by the ‘panic’ code. Still, there’s only one common reason for
vm_allocate
to fail, namely, that there’s not enough address space remaining for the requested allocation. And that raises the question of “How big was the allocation?” If the allocation was stupidly big, we need to work out why that’s the case. On the other hand, if the allocation is reasonably sized, we’ve just run out of address space.
It turns out that you can work this out from the crash report. The prototype for
vm_allocate
looks like this:
kern_return_t vm_allocate(vm_map_t target_task, vm_address_t * address, vm_size_t size, int flags);
so the allocation size is passed in
x2
. Fortunately,
x2
is copied from
x23
at +228 and
x23
is preserved by the panic code. Looking up
x23
in the crash report’s register dump we see that it’s 0x10000000, or 256 MiB. That’s pretty darned big, even for a 64-bit process.
Looking through the other crash reports that alex246 sent to me, the only other value I see in
x23
is 0x8000000, or 128 MiB, which is also pretty big.
[The above is all concrete analysis but here I’m heading off into the realm of speculation.]
My best guess as to what’s happening here is that you’re presenting Core Spotlight with a massive data set. Core Spotlight is trying to serialise this (hence frame 6 in the crashed thread) and that’s running out of address space.
Which brings us to frame 7:
7 … __161-[CSSearchableIndex indexSearchableItems:deleteSearchableItemsWithIdentifiers:clientState:clientStateName:protectionClass:forBundleID:options:completionHandler:]_block_invoke + 1296 (CSSearchableIndex.m:796)
My best guess is that this is a block used internally by
-indexSearchableItems:completionHandler:
, and it’s the
items
parameter that’s triggering this massive serialisation.
Given the above my recommendation is that you look at the size of the data you’re trying to index. It seems likely that you’re trying to index massive amounts of data in one go — either a huge number of small items or a small number of huge items — and that’s what’s triggering this crash.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
[1] Which is good enough for this task, once I used a ‘clean’ crash report to track down the issue.
[2] Note that in 64-bit Arm,
x8
is the full 64-bit register and
w8
is an alias for the bottom 32-bits.