From 3505e1faadddeeec85a0d3f823c877ea33f86e00 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Fri, 17 Feb 2012 13:15:12 -0800 Subject: [PATCH] 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 --- hw/xquartz/X11Application.h | 3 ++ hw/xquartz/X11Application.m | 45 ++++++++++++++++++ .../English.lproj/Localizable.strings | Bin 4410 -> 5454 bytes hw/xquartz/darwin.c | 4 +- 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/hw/xquartz/X11Application.h b/hw/xquartz/X11Application.h index 56806867e..a20c13e64 100644 --- a/hw/xquartz/X11Application.h +++ b/hw/xquartz/X11Application.h @@ -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" diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index e1d35abbf..6f55bcd65 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -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) { diff --git a/hw/xquartz/bundle/Resources/English.lproj/Localizable.strings b/hw/xquartz/bundle/Resources/English.lproj/Localizable.strings index bf2089ca1399c895dc701dfc23fa9bd44a1d8b8f..36ae0ffb3d2ed207a1a73be03bdc898c3306466f 100644 GIT binary patch delta 934 zcmd6m%}N4M7=|B421JNj77~4o=t59&TS!RI##MjN!j0*alFba`*zdw?sJVjfpm5i& z8|acM&Zp+juH3|MW)A0tci!)LXWpETy!G`NKUn$K!iH^=&8%mJHT%dKZR47KKio_{ zClll(eqXzbZ>>Vr#iNN&ACCx^kPaRf2n~dD8bmbcBC3V>ga~;`q;NQ<{j{3i6;3Hr zM#ffMS_mFK5yBZRf=_^XnM;cz4nhU_u_*o0A`YyrxROW>mdjtoTbRtJNs~Syp+*&M zXw#vqL-dqJNHn3ePefa#34xx1y4L$PLLG-JJ$=^kbnVflLz7E{1Nw9xU($mjGAA73 z5-4v2F~UdG+`zojbF*vVY9^Dgri%wMn0-b7H#z5Ox8pxk{to$n= fJETrXQ6i7bHBr=S`UlLmG}5M@_Ny;!R@%Wy2@U{+9Ln0!E>5&&!Y B4M6|^ diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c index 3dd41cba8..f9acf906c 100644 --- a/hw/xquartz/darwin.c +++ b/hw/xquartz/darwin.c @@ -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); } /*