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
|
void
|
||||||
X11ApplicationMain(int argc, char **argv, char **envp);
|
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_APPSMENU "apps_menu"
|
||||||
#define PREFS_FAKEBUTTONS "enable_fake_buttons"
|
#define PREFS_FAKEBUTTONS "enable_fake_buttons"
|
||||||
#define PREFS_KEYEQUIVS "enable_key_equivalents"
|
#define PREFS_KEYEQUIVS "enable_key_equivalents"
|
||||||
|
|
|
@ -70,6 +70,7 @@ static dispatch_queue_t eventTranslationQueue;
|
||||||
|
|
||||||
extern Bool noTestExtensions;
|
extern Bool noTestExtensions;
|
||||||
extern Bool noRenderExtension;
|
extern Bool noRenderExtension;
|
||||||
|
extern BOOL serverRunning;
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
|
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
|
||||||
static TISInputSourceRef last_key_layout;
|
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
|
static void
|
||||||
check_xinitrc(void)
|
check_xinitrc(void)
|
||||||
{
|
{
|
||||||
|
|
Binary file not shown.
|
@ -78,6 +78,8 @@
|
||||||
#include "quartzKeyboard.h"
|
#include "quartzKeyboard.h"
|
||||||
#include "quartz.h"
|
#include "quartz.h"
|
||||||
|
|
||||||
|
#include "X11Application.h"
|
||||||
|
|
||||||
aslclient aslc;
|
aslclient aslc;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -636,7 +638,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
|
||||||
void
|
void
|
||||||
OsVendorFatalError(const char *f, va_list args)
|
OsVendorFatalError(const char *f, va_list args)
|
||||||
{
|
{
|
||||||
ErrorF(" OsVendorFatalError\n");
|
X11ApplicationFatalError(f, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue