Apple Mail crashes on launch if connection logging is enabled

This was a fun one.  Mail started crashing on launch for absolutely no apparent reason – nothing had changed to its config or similar in a long time.  The crash logs were all fingering an identical culprit – -[IMAPTaskManager secondaryIdleMailboxName] called on the wrong GCD queue:

Process: Mail [19884]
Path: /Applications/Mail.app/Contents/MacOS/Mail
Identifier: com.apple.mail
Version: 11.3 (3445.6.18)
Build Info: Mail-3445006018000000~4
Code Type: X86-64 (Native)
Parent Process: ??? [1]
Responsible: Mail [19884]
User ID: …

Date/Time: 2018-04-19 16:44:45.717 -0700
OS Version: Mac OS X 10.13.4 (17E199)
Report Version: 12
Anonymous UUID: …

Sleep/Wake UUID: …

Time Awake Since Boot: 94000 seconds
Time Since Wake: 530 seconds

System Integrity Protection: enabled

Crashed Thread: 13 Dispatch queue: Task Manager Serialization Queue (QOS: UNSPECIFIED)

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This method should only be called on the serialization queue'
terminating with uncaught exception of type NSException
abort() called

Application Specific Backtrace 1:
0 CoreFoundation 0x00007fff55da96bb __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fff7d4c1942 objc_exception_throw + 48
2 CoreFoundation 0x00007fff55daf2a2 +[NSException raise:format:arguments:] + 98
3 Foundation 0x00007fff57ee7340 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
4 IMAP 0x00007fff6fe88959 -[IMAPTaskManager secondaryIdleMailboxName] + 216
5 IMAP 0x00007fff6fe880cb -[IMAPTask mailboxIsUserVisibleUsingDataSource:] + 180
6 IMAP 0x00007fff6fe6ab68 -[IMAPMailboxSyncTask _nextNetworkPriorityAndOperation:reservedNetworkPriority:] + 164
7 IMAP 0x00007fff6fe6c4ba -[IMAPMailboxSyncTask recalculatePriorities] + 398
8 IMAP 0x00007fff6fe67dd9 -[IMAPMailboxSyncTask initWithDataSource:taskManager:imapMailbox:fromStatus:forceFullSync:] + 766
9 IMAP 0x00007fff6fe931f7 -[IMAPTaskManager _syncMailboxWithDataSource:withIMAPMailbox:fromStatus:forceFullSync:userInitiated:] + 370
10 IMAP 0x00007fff6fe92e68 -[IMAPTaskManager syncMailboxWithDataSource:withIMAPMailbox:fromStatus:forceFullSync:userInitiated:] + 240
11 IMAP 0x00007fff6fe9631a -[IMAPTaskManager didAddMessagesWithUnknownUID:toDataSource:] + 872
12 Foundation 0x00007fff57e4a5df __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
13 Foundation 0x00007fff57e4a441 -[NSBlockOperation main] + 68
14 Foundation 0x00007fff57e488ee -[__NSOperationInternal _start:] + 778
15 Foundation 0x00007fff57e44917 __NSOQSchedule_f + 369
16 libdispatch.dylib 0x00007fff7e09ee08 _dispatch_client_callout + 8
17 libdispatch.dylib 0x00007fff7e0b1ed1 _dispatch_continuation_pop + 472
18 libdispatch.dylib 0x00007fff7e0a9783 _dispatch_async_redirect_invoke + 703
19 libdispatch.dylib 0x00007fff7e0a09f9 _dispatch_root_queue_drain + 515
20 libdispatch.dylib 0x00007fff7e0a07a5 _dispatch_worker_thread3 + 101
21 libsystem_pthread.dylib 0x00007fff7e3f0169 _pthread_wqthread + 1387
22 libsystem_pthread.dylib 0x00007fff7e3efbe9 start_wqthread + 13

Long story short, the issue turns out to be having connection logging enabled.  That’d been turned on many months before in order to debug a different stupid Mail bug, and had been simply left on (deliberately IIRC, since Mail tends to bug-out quite often, so why not have logs already available when it comes time to debug it yet again?).

Connection logging is enabled or disabled by opening the “Connection Doctor” (Window menu > Connection Doctor) and using the checkbox titled “Log Connection Activity”.

So how do you get to that checkbox when Mail crashes on launch?  Well, in this specific instance I was able to disable all mail accounts via System Preference’s Accounts pane, launch Mail, disable logging, quit Mail, re-enable all mail accounts via System Preferences, and then relaunch Mail to have it finally actually work.

From even just brief web searching, it’s clear that this issue has been present and well-known in Mail for a really long time.  Sigh.  Apple’s protestations that they care about software quality, or the Mac, are relentlessly undermined by their actual actions.

‘Fake error’ about immutable values when using popFirst() on Array

It’s been a while since I wrote any meaningful Swift.  How I didn’t miss the Swift compiler’s bullshit error messages.

var someArray = ["Foo", "Bar"]

if let foo = someArray.popFirst() {
    print("Who cares, we never get here anyway.")
}

That yields, on the popFirst() method:  “Cannot use mutating member on immutable value: ‘someArray’ is immutable”.

No it’s not.  It’s simply not.

For whatever reason, if you instead call popFirst() on ArraySlice – ostensibly indistinguishable from a real Array – it works just fine.

var someArray = ["Foo", "Bar"][0...]

if let foo = someArray.popFirst() {
    print("Yet this works correctly.")
}

Sigh.

I presume it’s trying to tell me something stupidly obscure about Swift’s byzantine type system.  Good luck finding out what.  Good luck even finding the definition of the popFirst() method, since Xcode claims it doesn’t exist if you Command-Control-click on it.  But Xcode can’t find most things, so that in itself says very little.

Handbrake’s H.265 ‘Preset’ setting affects ‘constant’ quality

I always consternate over what the ‘Preset’ setting should be when doing H.264 encodes with Handbrake.  It’s always tempting to slide right on over to ‘placebo’ to, in theory, ensure you’ve got the best possible encoding.  And in my experience that at least roughly works – file size decreases (marginally) as you use more time-consuming encoding Presets, for equivalent quality.

Now that I’m transitioning to H.265 instead, I thought I’d do a ‘quick’ experiment to see how it behaves in comparison.  The result is baffling.

Handbrake H.265 file size vs Preset

PresetFile size (MiB)Encode time (Hours)
Placebo32916.65
Veryslow2183.70
Slower2192.75
Slow1830.93
Medium1850.53
Fast1560.36
Faster1550.31
Veryfast1550.31
Superfast1290.23
Ultrafast830.22
Encoding from ProRes 422 of a 4000x3000 timelapse, at constant quality 22. A 270° rotation was performed in the process. No audio.

 

The outputs should all be visually essentially identical, by virtue of constant-quality encoding with the same quality factor.  However, they are not – there’s a small but quite visible difference in quality, with the slower-encoded versions having progressively more detail retained, while at the other end, the faster encodings, it looks like a strong noise reduction pass has been applied (which isn’t literally what’s happened, I assume, but rather the consequence of a lower-quality encoding).

Regardless of the specifics, this shouldn’t be happening.  ‘Constant quality’ seems quite self-explanatory.

Note also how the encoding times go up exponentially – ‘placebo’ was really gruelling, as the equivalent H.264 encode would have been an order of magnitude shorter, and that’s what I’d budgeted my time from.

So I guess the moral of the story is… leave ‘Preset’ on its default value for now, until it stops misbehaving?  Choose it based primarily on your encode time constraints, or file size concerns – whichever is highest priority?  Frustrating.

Note: I used the Handbrake Nightly build as of mid-November 2017 (version 20171113130119-17a4bb7-master), as the latest released version (1.0.7) produces H.265 files that macOS High Sierra refuses to play.  Apparently it’s using a different codec tag – ‘hev1’ instead of ‘hvc1’ – from what Apple’s expecting (see for example this thread).  I have no idea which is correct, or maybe both are in some contexts… either way it’s a concern for ongoing H.265 device compatibility.