Getting this weird crash after updating to Mojave.
Not doing anything special, just creating an NSWindow and calling orderFrontRegardless
Always worked fine before.
1 libsystem_platform.dylib 0x00007fff6610ab5d _sigtramp + 29
2 ??? 0x0000000000000000 0x0 + 0
3 CoreFoundation 0x00007fff39b00bb6 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
4 CoreFoundation 0x00007fff39b00b30 ___CFXRegistrationPost_block_invoke + 63
5 CoreFoundation 0x00007fff39b00a9a _CFXRegistrationPost + 404
6 CoreFoundation 0x00007fff39b08f48 ___CFXNotificationPost_block_invoke + 87
7 CoreFoundation 0x00007fff39a71994 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1642
8 CoreFoundation 0x00007fff39a70d47 _CFXNotificationPost + 732
9 Foundation 0x00007fff3bdab217 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
10 AppKit 0x00007fff3720538b -[NSWindow _setFrameCommon:display:stashSize:] + 3090
11 AppKit 0x00007fff37204766 -[NSWindow _setFrame:display:allowImplicitAnimation:stashSize:] + 192
12 AppKit 0x00007fff3720469f -[NSWindow setFrame:display:] + 51
13 AppKit 0x00007fff3727aca9 -[NSWindow _reallyDoOrderWindowAboveOrBelow:relativeTo:findKey:forCounter:force:isModal:] + 1336
14 AppKit 0x00007fff372792a0 -[NSWindow _doOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 283
15 AppKit 0x00007fff37a0dce9 -[NSWindow orderFrontRegardless] + 40
Code (it's a console app):
NSWindow *window = [[NSWindow alloc] initWithContentRect:windowRect
styleMask:windowStyle
backing:NSBackingStoreBuffered
defer:NO];
// Since Snow Leopard, programs without application bundles and Info.plist
// files don't get a menubar and can't be brought to the front unless the
// presentation option is changed
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp activateIgnoringOtherApps:YES];
[window makeKeyAndOrderFront:nil];
How do you initialize the app? Do you have NSApplication
initialized before using AppKit
?
Something like these steps should be necessary in main.m:
@autoreleasepool {
NSApplication* application = NSApplication.sharedApplication;
AppDelegate* delegate = [[AppDelegate alloc] init];
application.delegate = delegate;
[application run];
}
Also your delegate might be getting deallocated, since NSApp
holds a weak reference to it.
You indicated that you were dereferencing an uninitialized pointer. But, I don't have enough information from the report you posted to know if this was (perhaps by luck) null, or just garbage memory. I'll assume that at some point you crashed with an EXC_BAD_ACCESS
(signal equivalent is SIGBUS
or SIGSEGV
, depending).
The critical bit of information here was that you had a signal handler installed.
Signal handlers generally (but not always) run on the crashing thread using the same stack. The kernel injects the handler using that _sigtramp
function. Upon signal delivery, current stack state contained the information you needed to track down the bad memory access. But, your signal handler was invoked instead. So it ran, mutating the stack as it did.
Then, your signal handler completed somehow. It is possible to configure a signal handler using sigaction
such that the process state is restored to the moment just before the crashing event. I'm not sure how your signal handler was configured. But, ultimately, I'm going to assume that the process was allowed to exit.
At this point, Apple's ReportCrash would have been triggered, and would capture backtraces for all threads in whatever state your signal handler left them. This is critical, because that's not necessarily the crashing state.
Adding complexity, backtrace_symbols_fd
is not at all safe to use from a signal handler. Async safety is challenging, and running code from a signal handler is highly difficult to get right. There are very few things you can do safely. I'm pretty sure, additionally, that backtrace_symbols_fd
allocates memory. So, if your crash was in the memory allocator somewhere, and it sounds like it was, you were definitely at risk for a deadlock. Judging by the backtrace, it seems like that's exactly what might have happened. Check out man sigaction
for some details.
Worse, unwinding the stack over a signal handler frame is particularly challenging because of the magic the kernel does to run your handler. That's why that ???
frame is in there.
A summary:
Without a signal handler installed, Apple's ReportCrash would have produced a correct (and likely helpful) backtrace for the crashing thread.
The stack trace you've included isn't great, but it's hard to know exactly why.
It appears that backtrace_symbols_fd
didn't do a good job of unwinding, possibly due to it being inappropriate to use from a signal handler, possibly because it isn't backed by a good-enough stack unwinding mechanism for this situation. But, without more information, it's difficult for me to know. I am surprised the the top frame was _sigtramp
, though. That doesn't make a lot of sense. It makes me think something might have been going wrong in the signal handler itself. It is possible to crash a second time in your handler.
Apple's backtraces (generated by ReportCrash, backtrace_symbols_fd
, or NSThread's callStackReturnAddresses
, for example) can definitely be trusted, provided you're careful to use them in safe contexts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With