My app got rejected from the app store because there is a button that causes it to crash when pressed on an iPad. I don't have an iPad, and the bug is unreproducible on any of the iPad simulators. Here's the crash report the Resolution Center sent me:
{"app_name":"xxx","timestamp":"2018-05-23 14:18:37.70 -0700","app_version":"0.4.5","slice_uuid":"f7e0571c-a2a9-313c-ab7b-9a9109670ff2","adam_id":1387669409,"build_version":"1","bundleID":"com.b.xxx","share_with_app_devs":false,"is_first_party":false,"bug_type":"109","os_version":"iPhone OS 11.3.1 (15E302)","incident_id":"D5ADA937-9FAF-479B-A925-7B127B5E0C44","name":"xxx"} Incident Identifier: D5ADA937-9FAF-479B-A925-7B127B5E0C44 CrashReporter Key: cac3035154ad4b589b77fd30cfea229fc2cfaf20 Hardware Model: xxx Process: xxx [1949] Path: /private/var/containers/Bundle/Application/FD86FF84-2DDF-4DFA-B23D-703D4A08316B/xxx.app/xxx Identifier: com.b.xxx Version: 1 (0.4.5) Code Type: ARM-64 (Native) Role: Foreground Parent Process: launchd [1] Coalition: com.b.xxx [1153] Date/Time: 2018-05-23 14:18:37.5753 -0700 Launch Time: 2018-05-23 14:18:31.9754 -0700 OS Version: iPhone OS 11.3.1 (15E302) Baseband Version: 6.55.00 Report Version: 104 Exception Type: EXC_BREAKPOINT (SIGTRAP) Exception Codes: 0x0000000000000001, 0x0000000180b03644 Termination Signal: Trace/BPT trap: 5 Termination Reason: Namespace SIGNAL, Code 0x5 Terminating Process: exc handler [0] Triggered by Thread: 0 Application Specific Information: BUG IN CLIENT OF LIBDISPATCH: trying to lock recursively Filtered syslog: None found Thread 0 name: Dispatch queue: com.apple.main-thread Thread 0 Crashed: 0 libdispatch.dylib 0x0000000180b03644 _dispatch_gate_wait_slow$VARIANT$mp + 180 1 libdispatch.dylib 0x0000000180b04334 dispatch_once_f$VARIANT$mp + 132 2 libdispatch.dylib 0x0000000180b04334 dispatch_once_f$VARIANT$mp + 132 3 xxx 0x00000001006cc6ec specialized static TextFieldFactory.manufacture(for:with:) + 2868972 (TextFieldFactory.swift:13) 4 xxx 0x00000001006535ac _T09xxx22GRADEDISPLAY_MAX_WIDTH12CoreGraphics7CGFloatVvpfiAEycfU_ + 2373036 (DimensionConstants.swift:0) 5 xxx 0x00000001006532b8 globalinit_33_D344213E1027291683078D92DF0D6E22_func214 + 2372280 (DimensionConstants.swift:220) 6 libdispatch.dylib 0x0000000180b00ae4 _dispatch_client_callout + 16 7 libdispatch.dylib 0x0000000180b042ec dispatch_once_f$VARIANT$mp + 60 8 xxx 0x00000001006cc6ec specialized static TextFieldFactory.manufacture(for:with:) + 2868972 (TextFieldFactory.swift:13) 9 xxx 0x00000001006cac10 static TextFieldFactory.manufacture(for:with:) + 2862096 (TextFieldFactory.swift:0) 10 xxx 0x0000000100614f2c _T09xxx04EditA4ViewC5titleAA9TextFieldCvgAFycfU_ + 2117420 (EditClassView.swift:26) 11 xxx 0x000000010060ff90 EditClassView.beginInit() + 2097040 (EditClassView.swift:24) 12 xxx 0x00000001006bc970 MView.init(sizeConstraint:) + 2804080 (MView.swift:0) 13 xxx 0x0000000100614934 EditClassView.init(cCreateSemester:clss:sizeConstraint:) + 2115892 (EditClassView.swift:237) 14 xxx 0x00000001007184f8 specialized CCreateSemester.createCreateCourseView(_:) + 3179768 (CCreateSemester.swift:667) 15 xxx 0x000000010071393c CCreateSemester.setupNewSemester() + 3160380 (CCreateSemester.swift:594) 16 xxx 0x000000010071030c CCreateSemester.viewDidLoad() + 3146508 (CCreateSemester.swift:0) 17 xxx 0x0000000100711674 @objc CCreateSemester.viewDidLoad+ 3151476 () + 28 18 UIKit 0x000000018adeaee0 -[UIViewController loadViewIfRequired] + 1020 19 UIKit 0x000000018ae98e98 -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 76 20 UIKit 0x000000018ae98354 -[UINavigationController _startTransition:fromViewController:toViewController:] + 172 21 UIKit 0x000000018ae97c90 -[UINavigationController _startDeferredTransitionIfNeeded:] + 1164 22 UIKit 0x000000018ae97720 -[UINavigationController __viewWillLayoutSubviews] + 164 23 UIKit 0x000000018ae8b424 -[UILayoutContainerView layoutSubviews] + 188 24 UIKit 0x000000018ade3770 -[UIView+ 309104 (CALayerDelegate) layoutSublayersOfLayer:] + 1420 25 QuartzCore 0x000000018538525c -[CALayer layoutSublayers] + 184 26 QuartzCore 0x00000001853893ec CA::Layer::layout_if_needed+ 1209324 (CA::Transaction*) + 324 27 QuartzCore 0x00000001852f5aa0 CA::Context::commit_transaction+ 604832 (CA::Transaction*) + 320 28 QuartzCore 0x000000018531d5d0 CA::Transaction::commit+ 767440 () + 580 29 QuartzCore 0x000000018531e450 CA::Transaction::observer_callback+ 771152 (__CFRunLoopObserver*, unsigned long, void*) + 92 30 CoreFoundation 0x00000001811b6910 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32 31 CoreFoundation 0x00000001811b4238 __CFRunLoopDoObservers + 412 32 CoreFoundation 0x00000001811b4884 __CFRunLoopRun + 1436 33 CoreFoundation 0x00000001810d4da8 CFRunLoopRunSpecific + 552 34 GraphicsServices 0x00000001830b7020 GSEventRunModal + 100 35 UIKit 0x000000018b0b578c UIApplicationMain + 236 36 xxx 0x00000001004179b8 main + 31160 (PercentBasedUnequalField.swift:12) 37 libdyld.dylib 0x0000000180b65fc0 start + 4 Thread 1: 0 libsystem_kernel.dylib 0x0000000180c95d84 __workq_kernreturn + 8 1 libsystem_pthread.dylib 0x0000000180e33eb4 _pthread_wqthread + 928 2 libsystem_pthread.dylib 0x0000000180e33b08 start_wqthread + 4 Thread 2: 0 libsystem_kernel.dylib 0x0000000180c95d84 __workq_kernreturn + 8 1 libsystem_pthread.dylib 0x0000000180e33eb4 _pthread_wqthread + 928 2 libsystem_pthread.dylib 0x0000000180e33b08 start_wqthread + 4 Thread 3: 0 libsystem_kernel.dylib 0x0000000180c95d84 __workq_kernreturn + 8 1 libsystem_pthread.dylib 0x0000000180e340a0 _pthread_wqthread + 1420 2 libsystem_pthread.dylib 0x0000000180e33b08 start_wqthread + 4 Thread 4: 0 libsystem_pthread.dylib 0x0000000180e33b04 start_wqthread + 0 Thread 5 name: com.apple.uikit.eventfetch-thread Thread 5: 0 libsystem_kernel.dylib 0x0000000180c73e08 mach_msg_trap + 8 1 libsystem_kernel.dylib 0x0000000180c73c80 mach_msg + 72 2 CoreFoundation 0x00000001811b6e40 __CFRunLoopServiceMachPort + 196 3 CoreFoundation 0x00000001811b4908 __CFRunLoopRun + 1568 4 CoreFoundation 0x00000001810d4da8 CFRunLoopRunSpecific + 552 5 Foundation 0x0000000181b49674 -[NSRunLoop+ 34420 (NSRunLoop) runMode:beforeDate:] + 304 6 Foundation 0x0000000181b4951c -[NSRunLoop+ 34076 (NSRunLoop) runUntilDate:] + 148 7 UIKit 0x000000018ad9a7e4 -[UIEventFetcher threadMain] + 136 8 Foundation 0x0000000181c59efc __NSThread__start__ + 1040 9 libsystem_pthread.dylib 0x0000000180e35220 _pthread_body + 272 10 libsystem_pthread.dylib 0x0000000180e35110 _pthread_body + 0 11 libsystem_pthread.dylib 0x0000000180e33b10 thread_start + 4 Thread 6: 0 libsystem_pthread.dylib 0x0000000180e33b04 start_wqthread + 0 Thread 7 name: RLMRealm notification listener Thread 7: 0 libsystem_kernel.dylib 0x0000000180c7834c kevent + 8 1 Realm 0x0000000100a05a80 realm::_impl::ExternalCommitHelper::listen() + 88704 (external_commit_helper.cpp:203) 2 Realm 0x0000000100a063ec std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0>::operator()() + 91116 (future:2323) 3 Realm 0x0000000100a06374 std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::__execute() + 90996 (future:1041) 4 Realm 0x0000000100a06524 std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::*)(), std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >*> >(void*, void*) + 91428 (thread:354) 5 libsystem_pthread.dylib 0x0000000180e35220 _pthread_body + 272 6 libsystem_pthread.dylib 0x0000000180e35110 _pthread_body + 0 7 libsystem_pthread.dylib 0x0000000180e33b10 thread_start + 4 Thread 8 name: RLMRealm notification listener Thread 8: 0 libsystem_kernel.dylib 0x0000000180c7834c kevent + 8 1 Realm 0x0000000100a05a80 realm::_impl::ExternalCommitHelper::listen() + 88704 (external_commit_helper.cpp:203) 2 Realm 0x0000000100a063ec std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0>::operator()() + 91116 (future:2323) 3 Realm 0x0000000100a06374 std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::__execute() + 90996 (future:1041) 4 Realm 0x0000000100a06524 std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::*)(), std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >*> >(void*, void*) + 91428 (thread:354) 5 libsystem_pthread.dylib 0x0000000180e35220 _pthread_body + 272 6 libsystem_pthread.dylib 0x0000000180e35110 _pthread_body + 0 7 libsystem_pthread.dylib 0x0000000180e33b10 thread_start + 4 Thread 0 crashed with ARM Thread State (64-bit): x0: 0x00000001007cdd68 x1: 0x0000000000000301 x2: 0x0000000000000000 x3: 0x0000000000000000 x4: 0x00000001007654a0 x5: 0x0000000000000011 x6: 0x0000000000000000 x7: 0x00000001c8041ce0 x8: 0x0000000000000003 x9: 0x0000000000000301 x10: 0x0000000000000000 x11: 0x0000000000000000 x12: 0x0000000000000001 x13: 0x0000000000000000 x14: 0x0000000000000000 x15: 0x0000000000000001 x16: 0x0000000180b042b0 x17: 0x0000000000000000 x18: 0x0000000000000000 x19: 0x0000000000000000 x20: 0x00000000ffffffff x21: 0x00000001007cdd68 x22: 0x0000000000000303 x23: 0x0000000000000001 x24: 0x0000000000000001 x25: 0x0000000101534280 x26: 0x0000000000000000 x27: 0x0000000000000001 x28: 0x0000000000000001 fp: 0x000000016f9eb140 lr: 0x0000000180b04334 sp: 0x000000016f9eb120 pc: 0x0000000180b03644 cpsr: 0x60000000
Moving up from Line 11 Thread 0 here is the code execution:
Line 11: EditClassView.beginInit()
class EditClassView: MStackView { // Parent implementation does nothing override func beginInit() { // First time `title` is referenced. It's lazy, so it's initialized here title.text = clss.getTitle() // Crashes before here ... } }
Line 10: Initialization of local title
property in EditClassView.title's
lazy initializer:
lazy private(set) var title: TextField = { let title = TF.manufacture(for: .allPurpose, with: TParams(textSize: 21, inputView: nil, placeholder: "Class Title")) // Crashes before here ... }()
Line 9: I think this is just referring to the TextFieldFactory.manufacture(for:with:)
reference, and not the actual execution of the function itself:
Line 8: I'm not sure what this is referring to. It appears to just be the TextFieldFactory.TextFieldParams
typealias because that's what's on TextFieldFactory.swift:13
:
typealias TParams = TextFieldFactory.TextFieldParams // Here is the definition class TextFieldParams { static let DEFAULT_TEXT: String? = nil static let DEFAULT_FONT_NAME = "poiretone-regular" static let DEFAULT_TEXT_SIZE = MEDIUM_TEXT_SIZE static let DEFAULT_TEXT_COLOR = UIColor.black static let DEFAULT_TINT_COLOR = UIColor.black static let DEFAULT_TEXT_ALIGNMENT = NSTextAlignment.center static let DEFAULT_USES_AUTORESIZING_MASK = true static let DEFAULT_INPUT_VIEW = TextFieldFactory.EMPTY_INPUT_VIEW static let DEFAULT_PLACEHOLDER: String? = nil static let DEFAULT_ADJUST_WIDTH_WITH_TEXT = false static let DEFAULT_MIN_WIDTH: CGFloat? = nil static let DEFAULT_MAX_WIDTH: CGFloat? = nil static let DEFAULT_EMPTY_WIDTH: CGFloat? = nil let text: String? let fontName: String let textSize: CGFloat let textColor: UIColor let tintColor: UIColor let textAlignment: NSTextAlignment let translatesAutoresizingMaskIntoConstraints: Bool let inputView: UIView? let placeholder: String? let adjustWidthWithText: Bool let minWidth: CGFloat? let maxWidth: CGFloat? let emptyWidth: CGFloat? var font: UIFont { return UIFont(name: fontName, size: textSize)! } init(text: String? = DEFAULT_TEXT, fontName: String = DEFAULT_FONT_NAME, textSize: CGFloat = DEFAULT_TEXT_SIZE, textColor: UIColor = DEFAULT_TEXT_COLOR, tintColor: UIColor = DEFAULT_TINT_COLOR, textAlignment: NSTextAlignment = DEFAULT_TEXT_ALIGNMENT, translatesAutoresizingMaskIntoConstraints: Bool = DEFAULT_USES_AUTORESIZING_MASK, inputView: UIView? = DEFAULT_INPUT_VIEW, placeholder: String? = DEFAULT_PLACEHOLDER, adjustWidthWithText: Bool = DEFAULT_ADJUST_WIDTH_WITH_TEXT, minWidth: CGFloat? = DEFAULT_MIN_WIDTH, maxWidth: CGFloat? = DEFAULT_MAX_WIDTH, emptyWidth: CGFloat? = DEFAULT_EMPTY_WIDTH ) { self.text = text self.fontName = fontName self.textSize = textSize self.textColor = textColor self.tintColor = tintColor self.textAlignment = textAlignment self.translatesAutoresizingMaskIntoConstraints = translatesAutoresizingMaskIntoConstraints self.inputView = inputView self.placeholder = placeholder self.adjustWidthWithText = adjustWidthWithText self.minWidth = minWidth self.maxWidth = maxWidth self.emptyWidth = emptyWidth } }
Now here's where I get lost. Line 7 and 6 don't refer to my code at all, so I'm not sure what it's doing but next thing you know one of my global constants --GRADEDISPLAY_MAX_WIDTH
-- is getting initialized on Line 5. And bear in mind that it has nothing to do with EditClassView
at all let alone EditClassView.title
.
But before I show its initialization, there is a link. GRADEDISPLAY_MAX_WIDTH
is referenced in TF.manufacture(for:with:)
, but you'll see that the function is just one big switch
block, and GRADEDISPLAY_MAX_WIDTH
is not referenced in the case we should be executing in which is odd. If you look back to Line 10, you'll see the relevant case is .allPurpose
, all the way at the end of the function:
static func manufacture(for textFieldPurpose: TextFieldPurpose, with params: TextFieldParams = TextFieldParams()) -> TextField { switch textFieldPurpose { case .notifyingTimeField: var ntf = makeNotifyingFocusableTimeField(with: params as! NotifyingFocusableTimeFieldParams) ntf.frame.size.width = CGFloat.timeFieldWidth ntf.underline() return ntf case .timeField: var ftf = makeFocusableTimeField(with: params as! FocusableTimeFieldParams) ftf.frame.size.width = CGFloat.timeFieldWidth ftf.underline() return ftf case .gradingCategoryTitle: var tf = makeUnderlineTextField(with: UnderlineTextFieldParams(edgeInsets: UIEdgeInsetsMake(0, AC_TITLE_DEFAULT_SIDE_INSET, UnderlineLabel.DEFAULT_BOTTOM_INSET, AC_TITLE_DEFAULT_SIDE_INSET), text: params.text, textSize: LARGE_TEXT_SIZE, inputView: nil, adjustWidthWithText: true, maxWidth: params.maxWidth) ) tf.underline() return tf case .whereTextField: var tf = makeUnderlineTextField(with: UnderlineTextFieldParams(inputView: nil, adjustWidthWithText: true, minWidth: WHERE_TEXTFIELD_MIN_WIDTH, maxWidth: params.maxWidth) ) tf.underline() return tf case .notifyingDateField: var ndf = makeNotifyingFocusableDateField(with: params as! ContextualFocusableParams) ndf.frame.size.width = CGFloat.timeFieldWidth ndf.underline() return ndf case .percentTotalField, .percentEachField, .percentUnequalField, .pointsTotalField, .pointsEachField, .pointsUnequalField, .percentExamTotalField, .percentEachExamField, .percentFinalField, .pointsExamTotalField, .pointsEachExamField, .pointsFinalField: guard let params = params as? ContextualFocusableParams else { fatalError("A ContextualFocusableParams must be passed in order to manufacture a FocusableWeightField") } var f = makeFocusableWeightField(for: textFieldPurpose, with: ContextualFocusableParams(context: params.context, adjustWidthWithText: true, minWidth: CGFloat.timeFieldWidth) ) f.underline() return f case .customTitleField: let edgeInsets = UIEdgeInsetsMake(0, CUSTOM_TITLE_SIDE_INSET, UnderlineLabel.DEFAULT_BOTTOM_INSET, CUSTOM_TITLE_SIDE_INSET) var tf = makeUnderlineTextField(with: UnderlineTextFieldParams(edgeInsets: edgeInsets, inputView: nil, placeholder: params.placeholder, adjustWidthWithText: true, minWidth: params.minWidth, maxWidth: params.maxWidth, emptyWidth: params.emptyWidth) ) tf.underline() return tf case .gradeField: let tf = initializedTextField(textField: PercentSuffixedTextField(), params: TParams(text: params.text, textSize: AV_GRADE_TEXT_SIZE, textColor: UIColor.defaultTextColor, inputView: nil) ) tf.frame.size = CGSize(width: GRADEDISPLAY_MAX_WIDTH, height: GV_HEIGHT) tf.isEnabled = false tf.keyboardType = .numberPad return tf case .fractionField: let tf = makeTextField(with: TParams(text: params.text, textSize: AV_GRADE_TEXT_SIZE, textColor: UIColor.defaultTextColor, inputView: nil) ) tf.frame.size.width = GRADEDISPLAY_MAX_WIDTH tf.isEnabled = false tf.keyboardType = .numberPad return tf case .assessmentTitle: let tf = makeTextField(with: TParams(text: params.text, textSize: AV_TITLE_TEXT_SIZE, textColor: UIColor.defaultTextColor, placeholder: String.classTitlePlaceholder, adjustWidthWithText: true) ) tf.isEnabled = false return tf case .weightField: let tf = initializedTextField(textField: PercentSuffixedTextField(adjustWidthWithText: true, minWidth: params.minWidth), params: TParams(text: params.text, textSize: params.textSize, textAlignment: .right, inputView: nil) ) tf.keyboardType = .decimalPad tf.performableActions = [] return tf // `GRADEDISPLAY_MAX_WIDTH` is referenced in the `.gradeField` // and `.fractionField` cases just above here case .allPurpose: return makeTextField(with: params) case .allPurposeInsetting: return makeInsetTextField(with: params as! ITParams) } }
Line 5: I think this is the initialization of GRADEDISPLAY_MAX_WIDTH
because DimensionConstants.swift:220
is where its property definition begins
let GRADEDISPLAY_MAX_WIDTH: CGFloat = { let gradeField = TF.manufacture(for: .allPurpose, with: TParams(text: "100%", textSize: 17)) // From the look of the crash report, it doesn't look // like execution makes it this far let trailingMargin: CGFloat = 4 return proportionedWidth(gradeField.frame.size.width + trailingMargin) }()
I'm not sure what Line 4 is referring to. Could it be GRADEDISPLAY_MAX_WIDTH
itself?
And finally the last reference to my code in the crash report.
Line 3: Which just appears to be the same as Line 8...
The priority here is fixing the crash, and I think it has something to do with what's going on on Lines 6 and 7 of the stack trace. I could get into my code base, but take my word for it that GRADEDISPLAY_MAX_WIDTH
is not referenced anywhere in EditClassView
or any code that is related to it, so there's no reason it should be seen anywhere remotely near EditClassView
in any stack trace.
Can anyone shed some light on what's going on on Lines 6 and 7?
This may be another clue:
On Line 36 in Thread 0 PercentBasedUnequalField
is referenced; specifically line 12 in it. PercentBasedUnequalField
is actually not used anywhere within the executing code of the app. It's part of a new feature I'm working on. I left the file in the bundle because it would have been a hassle to remove it because the current source branch branched off that incomplete feature.
The similarity here is that like GRADEDISPLAY_MAX_WIDTH
, PercentBasedUnequalField
is also referenced in an unrelated switch
case in TF.manufacture(for:with:)
.
Update
Found this similar issue where the poster indicates all the cases
of a switch
statement are being executed as a swift optimization. That would explain why GRADEDISPLAY_MAX_WIDTH
is being initialized even though the case
that accesses it isn't matched. I'll try adding the optimization disabling annotation mentioned in the link and update if it fixes the issue.
0 comments:
Post a Comment