XQuartz: Detect FatalErrors on startup to prevent tight crash loops
If a FatalError occurs before the server finishes launching, it will not have drained the launchd-owned DISPLAY socket, so launchd will just relaunch it. This can cause the server to crash in a tight loop which will spam the user with CrashReporter windows that claim focus on appearance. This allows users stuck in this loop to "deal" with the problem without popping up a crash report every 10 seconds. Signed-off-by: Jeremy Huddleston <jeremyhu@apple.com>
This commit is contained in:
parent
a818b30598
commit
3505e1faad
|
@ -108,6 +108,9 @@ X11ApplicationCanEnterRandR(void);
|
|||
void
|
||||
X11ApplicationMain(int argc, char **argv, char **envp);
|
||||
|
||||
void
|
||||
X11ApplicationFatalError(const char *f, va_list args) __printflike(1, 0);
|
||||
|
||||
#define PREFS_APPSMENU "apps_menu"
|
||||
#define PREFS_FAKEBUTTONS "enable_fake_buttons"
|
||||
#define PREFS_KEYEQUIVS "enable_key_equivalents"
|
||||
|
|
|
@ -70,6 +70,7 @@ static dispatch_queue_t eventTranslationQueue;
|
|||
|
||||
extern Bool noTestExtensions;
|
||||
extern Bool noRenderExtension;
|
||||
extern BOOL serverRunning;
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
|
||||
static TISInputSourceRef last_key_layout;
|
||||
|
@ -1067,6 +1068,50 @@ NO] || XQuartzShieldingWindowLevel != 0)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
X11ApplicationFatalError(const char *f, va_list args)
|
||||
{
|
||||
#ifdef HAVE_LIBDISPATCH
|
||||
NSString *title, *msg;
|
||||
char *error_msg;
|
||||
|
||||
/* This is called by FatalError() in the server thread just before
|
||||
* we would abort. If the server never got off the ground, We should
|
||||
* inform the user of the error rather than letting the ever-so-friendly
|
||||
* CrashReporter do it for us.
|
||||
*
|
||||
* This also has the benefit of forcing user interaction rather than
|
||||
* allowing an infinite throttled-restart if the crash occurs before
|
||||
* we can drain the launchd socket.
|
||||
*/
|
||||
|
||||
if (serverRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
title = NSLocalizedString(@"The application X11 could not be opened.",
|
||||
@"Dialog title when encountering a fatal error");
|
||||
msg = NSLocalizedString(@"An error occurred while starting the X11 server: \"%s\"\n\nClick Quit to quit X11. Click Report to see more details or send a report to Apple.",
|
||||
@"Dialog when encountering a fatal error");
|
||||
|
||||
vasprintf(&error_msg, f, args);
|
||||
msg = [NSString stringWithFormat:msg, error_msg];
|
||||
|
||||
/* We want the AppKit thread to actually service the alert or we will race [NSApp run] and create an
|
||||
* 'NSInternalInconsistencyException', reason: 'NSApp with wrong _running count'
|
||||
*/
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
if (NSAlertDefaultReturn == NSRunAlertPanel(title, msg, NSLocalizedString(@"Quit", @""),
|
||||
NSLocalizedString (@"Report...", @""), nil)) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
});
|
||||
|
||||
/* fall back to caller to do the abort() in the DIX */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
check_xinitrc(void)
|
||||
{
|
||||
|
|
Binary file not shown.
|
@ -78,6 +78,8 @@
|
|||
#include "quartzKeyboard.h"
|
||||
#include "quartz.h"
|
||||
|
||||
#include "X11Application.h"
|
||||
|
||||
aslclient aslc;
|
||||
|
||||
void
|
||||
|
@ -636,7 +638,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
|
|||
void
|
||||
OsVendorFatalError(const char *f, va_list args)
|
||||
{
|
||||
ErrorF(" OsVendorFatalError\n");
|
||||
X11ApplicationFatalError(f, args);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue