I added Touch Bar support to my app when the latest MacBook Pro launched. Later I made various minor improvements, including custom escape keys where it made sense. After releasing that update, I started getting crash reports when the app tries to update the escape key.
Here's one example:
Exception Type: SIGBUS
Exception Codes: BUS_ADRERR at 0x7fff54a05ff8
Crashed Thread: 0
Application Specific Information:
Selector name found in current argument registers: objectForKey:
Thread 0 Crashed:
0 Foundation 0x00007fffacbaea98 -[NSConcreteMapTable objectForKey:] + 21
1 Foundation 0x00007fffacbfc019 -[NSISEngine outgoingRowHeadForRemovingConstraintWithMarker:] + 214
2 Foundation 0x00007fffacbfbb4c -[NSISEngine removeConstraintWithMarker:] + 479
3 Foundation 0x00007fffacbf76a6 -[NSISEngine _flushPendingRemovals] + 615
4 Foundation 0x00007fffacbf4b06 -[NSISEngine withBehaviors:performModifications:] + 197
5 AppKit 0x00007fffa8c83760 -[NSView(NSConstraintBasedLayout) _withAutomaticEngineOptimizationDisabled:] + 69
6 AppKit 0x00007fffa8d129dd -[NSView(NSConstraintBasedLayout) removeConstraints:] + 276
7 AppKit 0x00007fffa8c88f9e -[NSView(NSConstraintBasedLayout) _constraints_snipDangliesWithForce:] + 595
8 AppKit 0x00007fffa8c82d9e -[NSView _setSuperview:] + 1076
9 AppKit 0x00007fffa8c88945 -[NSView removeFromSuperview] + 446
10 AppKit 0x00007fffa9593eef -[NSTouchBarEscapeKeyViewController setTouchBarItem:] + 145
11 AppKit 0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438
12 AppKit 0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438
13 AppKit 0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438
…
509 AppKit 0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438
510 AppKit 0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438
511 AppKit 0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438
I've removed about 500 lines for brevity—all of them are calls to [NSApplicationFunctionRowController _updateEscapeKeyItem] + 438
Here's another abbreviated report. This one is my most common crash. It actually calls my own code, though I suspect the code it's calling is not the actual problem:
Exception Type: SIGBUS
Exception Codes: BUS_ADRERR at 0x7fff5b8c2f74
Crashed Thread: 0
Thread 0 Crashed:
0 CoreText 0x00007fffc87d2e8d _ZNK3OTL7GCommon9NthLookupEj + 41
1 CoreText 0x00007fffc87d658b _ZNK3OTL4GPOS12ApplyLookupsER8TRunGlueiRNS_12GlyphLookupsE + 155
2 CoreText 0x00007fffc87d5f53 _ZN26TOpenTypePositioningEngine12PositionRunsER9SyncStateR13KerningStatus + 839
3 CoreText 0x00007fffc8823920 _ZN14TKerningEngine14PositionGlyphsER8TRunGlue11ShapingTypePK10__CFString + 168
4 CoreText 0x00007fffc87ddcf7 CTFontTransformGlyphs + 463
5 UIFoundation 0x00007fffd9d2a795 __NSStringDrawingEngine + 7348
6 UIFoundation 0x00007fffd9d315ea -[NSAttributedString(NSExtendedStringDrawing) boundingRectWithSize:options:context:] + 605
7 UIFoundation 0x00007fffd9d31efd -[NSAttributedString(NSExtendedStringDrawing) boundingRectWithSize:options:] + 32
8 AppKit 0x00007fffc4e711cb -[NSAttributedString(NSStringDrawingExtension) _sizeWithSize:] + 55
9 AppKit 0x00007fffc4e710ff -[NSButtonCell(NSButtonCellPrivate) _titleSizeWithSize:] + 97
10 AppKit 0x00007fffc4e70eab -[NSButtonCell(NSButtonCellPrivate) _alignedTitleRectWithRect:] + 235
11 AppKit 0x00007fffc4e25162 -[NSButtonCell cellSizeForBounds:] + 918
12 AppKit 0x00007fffc4da2a21 -[NSCell cellSize] + 68
13 AppKit 0x00007fffc4da295a -[NSControl sizeToFit] + 53
14 AppKit 0x00007fffc520392c +[NSButton(NSButtonConvenience) _buttonWithTitle:image:target:action:] + 421
15 AppKit 0x00007fffc5203a05 +[NSButton(NSButtonConvenience) buttonWithTitle:target:action:] + 199
16 Deliveries 0x0000000103b4c655 +[JUNTouchBar cancelButtonItemWithIdentifier:] (JUNTouchBar.m:75)
17 Deliveries 0x0000000103b67e9b -[JUNEditWindowController touchBar:makeItemForIdentifier:] (JUNEditWindowController.m:183)
18 AppKit 0x00007fffc57d7d2a __32-[NSTouchBar itemForIdentifier:]_block_invoke + 34
19 AppKit 0x00007fffc4e71bd0 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 79
20 AppKit 0x00007fffc57d7b9b -[NSTouchBar itemForIdentifier:] + 1158
21 AppKit 0x00007fffc57d868e -[NSTouchBar(NSEscapeKeyReplacementOld) escapeKeyReplacementItem] + 51
22 AppKit 0x00007fffc5250e80 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 238
23 AppKit 0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439
24 AppKit 0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439
25 AppKit 0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439
…
509 AppKit 0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439
510 AppKit 0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439
511 AppKit 0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439
My touchBar:makeItemForIdentifier:
method is just this:
- (nullable NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier {
if ([identifier isEqualToString:JUNTouchBarItemIdentifierCancel]) {
NSCustomTouchBarItem *item = [JUNTouchBar cancelButtonItemWithIdentifier:identifier];
return item;
}
return nil;
}
And here's cancelButtonItemWithIdentifier:
, also pretty simple:
+ (NSCustomTouchBarItem *)cancelButtonItemWithIdentifier:(NSString *)identifier {
NSString *title = NSLocalizedString(@"Cancel", nil);
NSButton *button = [NSButton buttonWithTitle:title target:nil action:@selector(cancelOperation:)];
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:80.0];
constraint.priority = 950;
constraint.active = YES;
NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
item.view = button;
return item;
}
Of course I can't reproduce this crash myself. It happens in macOS 10.12.2 through beta versions of 10.12.5. Many of the reports are from the same 13" model I'm testing on myself. The few people that include a comment with their crash report mostly say it's happening immediately after an action that would open a new window (thus changing the escape key)—one said it happened after an action that would close a window. One person mentioned in hanging for 10 seconds before crashing—which makes sense given the 500 calls to the same method. A couple of people have mentioned it happening more than once, but of course they didn't leave any contact information so I have no way to follow up with them.
I know I could work around the crash by removing my custom escape keys, but I'd prefer not to. Any other ideas on how I can deal with this?
Update: Since originally posting this, I've updated the app to remove the constraint, so my code for creating the button is about as simple as it can get now:
+ (NSCustomTouchBarItem *)cancelButtonItemWithIdentifier:(NSString *)identifier {
NSString *title = JUNLocalizedString(@"Cancel", nil);
NSButton *button = [NSButton buttonWithTitle:title target:nil action:@selector(cancelOperation:)];
NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
item.view = button;
return item;
}
Unfortunately I'm still getting crash reports from the new version, with identical stack traces. So I don't think the issue is with the button I'm supplying.