Crash in internalInfoCallback
Closed this issue · 5 comments
I've got this crash more than a couple of times in an app, Shifty, using AXSwift
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [576]
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libswiftCore.dylib 0x00000001093e14e1 swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1> >::incrementSlow(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 33
1 libswiftCore.dylib 0x00000001093c9984 _swift_retain_(swift::HeapObject*) + 68
2 org.cocoapods.AXSwift 0x0000000108f04078 specialized internalInfoCallback(_:axElement:notification:cfInfo:userData:) + 552
3 org.cocoapods.AXSwift 0x0000000108f034ee @objc internalInfoCallback(_:axElement:notification:cfInfo:userData:) + 78
4 com.apple.HIServices 0x00007fff4b190672 _XXMIGPostNotification + 821
5 com.apple.HIServices 0x00007fff4b19ddac _XPostNotification + 351
6 com.apple.HIServices 0x00007fff4b172abe mshMIGPerform + 212
7 com.apple.CoreFoundation 0x00007fff4c9cc6a9 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
8 com.apple.CoreFoundation 0x00007fff4c9cc607 __CFRunLoopDoSource1 + 527
9 com.apple.CoreFoundation 0x00007fff4c9b4689 __CFRunLoopRun + 2574
10 com.apple.CoreFoundation 0x00007fff4c9b3a28 CFRunLoopRunSpecific + 463
11 com.apple.HIToolbox 0x00007fff4bc4cb35 RunCurrentEventLoopInMode + 293
12 com.apple.HIToolbox 0x00007fff4bc4c774 ReceiveNextEventCommon + 371
13 com.apple.HIToolbox 0x00007fff4bc4c5e8 _BlockUntilNextEventMatchingListInModeWithFilter + 64
14 com.apple.AppKit 0x00007fff49f08eb7 _DPSNextEvent + 997
15 com.apple.AppKit 0x00007fff49f07c56 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1362
16 com.apple.AppKit 0x00007fff49f01cb9 -[NSApplication run] + 699
17 com.apple.AppKit 0x00007fff49ef13f7 NSApplicationMain + 780
18 io.natethompson.Shifty 0x0000000108e022a9 0x108e00000 + 8873
19 libdyld.dylib 0x00007fff79b9608d start + 1
It doesn't always has the same backtrace, but internalInfoCallback
seems to be the cause for all of them.
Looking at the disassembly the crash seems to be caused by the line
observer.callbackWithInfo!(observer, element, notif, info)
The observer, or the callback aren't valid I think.
This is probably because I'm not using it correctly in the app Shifty (I would actually ask you what is the correct way to stop an observer), but we should probably not crash either way, and probably check if the observer or the callback are valid?
The offending code in Shifty is in this file https://github.com/thompsonate/Shifty/blob/5d58e021827b77fb00b850eb522fa6b73c158626/Shifty/BrowserManager.swift in the stopBrowserWatcher
. I wonder if I should remove the notifications instead of calling stop
.
Hmm, we should have called stop()
on Observer deinit. Merging a fix soon. Thanks for your report!
I'm still getting this issue in Shifty with AXSwift 0.2.3.
Looks like the offending line is still Observer.swift:162: observer.callbackWithInfo!(observer, element, notif, info)
in Observer.swift. Not sure if it's the root cause, but is there any reason to be force unwrapping there?
Here's BrowserManager.swift:171 referenced in my crash report.
Here's the stack trace from my crash reporter:
Shifty closure #1 (AXSwift.Observer, AXSwift.UIElement, AXSwift.AXNotification, [Swift.String : Swift.AnyObject]?) -> () in static Shifty.BrowserManager.(startBrowserWatcher in _BCA98A1A69929549465A957C57870AC7)(_: Swift.Int32, callback: () -> ()) throws -> () BrowserManager.swift:171
Shifty partial apply forwarder for closure #1 (AXSwift.Observer, AXSwift.UIElement, AXSwift.AXNotification, [Swift.String : Swift.AnyObject]?) -> () in static Shifty.BrowserManager.(startBrowserWatcher in _BCA98A1A69929549465A957C57870AC7)(_: Swift.Int32, callback: () -> ()) throws -> () <compiler-generated>:0
AXSwift function signature specialization <Arg[0] = Dead> of AXSwift.(internalInfoCallback in _1C4E6C7EFC73FEB542EA8C20A2603D9E)(_: __C.AXObserverRef, axElement: __C.AXUIElementRef, notification: __C.CFStringRef, cfInfo: __C.CFDictionaryRef, userData: Swift.UnsafeMutableRawPointer?) -> () Observer.swift:162
AXSwift @objc AXSwift.(internalInfoCallback in _1C4E6C7EFC73FEB542EA8C20A2603D9E)(_: __C.AXObserverRef, axElement: __C.AXUIElementRef, notification: __C.CFStringRef, cfInfo: __C.CFDictionaryRef, userData: Swift.UnsafeMutableRawPointer?) -> () <compiler-generated>:0
HIServices 0x7fff2cbe7000 + 145281
HIServices 0x7fff2cbe7000 + 200325
HIServices 0x7fff2cbe7000 + 23777
CoreFoundation 0x7fff2e34b000 + 338679
CoreFoundation 0x7fff2e34b000 + 338517
CoreFoundation 0x7fff2e34b000 + 240188
CoreFoundation 0x7fff2e34b000 + 237070
HIToolbox 0x7fff2d667000 + 43483
HIToolbox 0x7fff2d667000 + 42773
HIToolbox 0x7fff2d667000 + 42150
AppKit 0x7fff2b9f1000 + 110587
AppKit 0x7fff2b9f1000 + 105875
AppKit 0x7fff2b9f1000 + 81584
AppKit 0x7fff2b9f1000 + 13296
Shifty main AppDelegate.swift:21
libdyld.dylib 0x7fff5a7cc000 + 91093
The issue isn't Observer.swift:162; from the backtrace, it's within your handler. Possibly one of the force casts or unwraps in attribute()
is failing. These aren't supposed to fail (obviously).
In UIElement.swift in AXSwift, try replacing this line:
AXSwift/Sources/UIElement.swift
Line 181 in 1e2fa1f
with:
guard let unwrapped = value else {
fatalError("attribute \(attribute) of \(self) was nil")
}
let unpacked = unpackAXValue(unwrapped)
guard let casted = unpacked as? T else {
fatalError("attribute \(attribute) of \(self) was unexpected type: \(String(describing: value))")
}
return casted
That way if you hit it again, you'll get more useful errors. Or you'll rule out that as the source of the crash.
To answer your question, the reason the code force-unwraps in Observer.swift is because if we are receiving events, the observer
must still be valid. If it's not, checking one of its fields isn't going to help. Checking whether a field on it has gone nil
that should NEVER go nil means we just noticed we were reading invalid memory, and quietly ignored it, instead of failing loudly which we should be doing.
If you do get anything from the code I pasted above, please open a new issue and report all the output you get. That would definitely be a bug in AXSwift and we should be handling these cases more gracefully if they do happen.
Re-closing for now because I think the original issue here is fixed.