Linux: Catch X errors and force a crash.

BUG=45020
TEST=See http://crosbug.com/3487
Review URL: http://codereview.chromium.org/2716007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49488 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/app/x11_util.cc b/app/x11_util.cc
index 78e09fc9..934e8240 100644
--- a/app/x11_util.cc
+++ b/app/x11_util.cc
@@ -52,8 +52,26 @@
 // Maximum number of CachedPictFormats we keep around.
 const size_t kMaxCacheSize = 5;
 
+int X11ErrorHandler(Display* d, XErrorEvent* e) {
+  LOG(FATAL) << "X Error detected: serial " << e->serial
+             << " error_code " << static_cast<unsigned int>(e->error_code)
+             << " request_code " << static_cast<unsigned int>(e->request_code)
+             << " minor_code " << static_cast<unsigned int>(e->minor_code);
+  return 0;
+}
+
+int X11IOErrorHandler(Display* d) {
+  LOG(FATAL) << "X IO Error detected";
+  return 0;
+}
+
 }  // namespace
 
+void SetX11ErrorHandlers() {
+  XSetErrorHandler(X11ErrorHandler);
+  XSetIOErrorHandler(X11IOErrorHandler);
+}
+
 bool XDisplayExists() {
   return (gdk_display_get_default() != NULL);
 }
diff --git a/app/x11_util.h b/app/x11_util.h
index 5c202f3..b85061c 100644
--- a/app/x11_util.h
+++ b/app/x11_util.h
@@ -170,6 +170,9 @@
 // Change desktop for |window| to the desktop of |destination| window.
 bool ChangeWindowDesktop(XID window, XID destination);
 
+// Sets the X Error Handlers so we can catch X errors and crash.
+void SetX11ErrorHandlers();
+
 }  // namespace x11_util
 
 #endif  // APP_X11_UTIL_H_
diff --git a/chrome/app/chrome_dll_main.cc b/chrome/app/chrome_dll_main.cc
index 530d1850..d6eda18 100644
--- a/chrome/app/chrome_dll_main.cc
+++ b/chrome/app/chrome_dll_main.cc
@@ -23,7 +23,7 @@
 #include <unistd.h>
 #endif
 
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
+#if defined(USE_X11)
 #include <gdk/gdk.h>
 #include <glib.h>
 #include <gtk/gtk.h>
@@ -66,6 +66,10 @@
 #include "base/nss_util.h"
 #endif
 
+#if defined(USE_X11)
+#include "app/x11_util.h"
+#endif
+
 #if defined(OS_LINUX)
 #include "chrome/browser/renderer_host/render_sandbox_host_linux.h"
 #include "chrome/browser/zygote_host_linux.h"
@@ -204,9 +208,9 @@
   return (pos != std::wstring::npos);
 }
 
-#endif  // OS_WIN
+#endif  // defined(OS_WIN)
 
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
+#if defined(USE_X11)
 static void GLibLogHandler(const gchar* log_domain,
                            GLogLevelFlags log_level,
                            const gchar* message,
@@ -261,7 +265,9 @@
                       NULL);
   }
 }
+#endif  // defined(USE_X11)
 
+#if defined(OS_LINUX)
 static void AdjustLinuxOOMScore(const std::string& process_type) {
   const int kMiscScore = 7;
   const int kPluginScore = 10;
@@ -295,7 +301,7 @@
   if (score > -1)
     base::AdjustOOMScore(base::GetCurrentProcId(), score);
 }
-#endif  // defined(OS_POSIX) && !defined(OS_MACOSX)
+#endif  // defined(OS_LINUX)
 
 // Register the invalid param handler and pure call handler to be able to
 // notify breakpad when it happens.
@@ -717,8 +723,7 @@
     // Update the process name (need resources to get the strings, so
     // only do this when ResourcesBundle has been initialized).
     SetMacProcessName(process_type);
-#endif // defined(OS_MACOSX)
-
+#endif  // defined(OS_MACOSX)
   }
 
   if (!process_type.empty())
@@ -849,6 +854,8 @@
     // gtk_init() can change |argc| and |argv|.
     gtk_init(&argc, &argv);
     SetUpGLibLogHandler();
+
+    x11_util::SetX11ErrorHandlers();
 #endif  // defined(OS_LINUX)
 
     rv = BrowserMain(main_params);
diff --git a/chrome/gpu/gpu_thread.cc b/chrome/gpu/gpu_thread.cc
index dcb16e96..d73fc92 100644
--- a/chrome/gpu/gpu_thread.cc
+++ b/chrome/gpu/gpu_thread.cc
@@ -4,12 +4,12 @@
 
 #include "chrome/gpu/gpu_thread.h"
 
-#include "build/build_config.h"
+#include <string>
+#include <vector>
 
 #include "base/command_line.h"
 #include "chrome/common/child_process.h"
 #include "chrome/common/gpu_messages.h"
-#include "chrome/gpu/gpu_config.h"
 
 #if defined(OS_WIN)
 #include "chrome/gpu/gpu_view_win.h"
@@ -52,6 +52,7 @@
     for (size_t i = 0; i < args.size(); ++i) {
       free(argv[i]);
     }
+    x11_util::SetX11ErrorHandlers();
   }
 #endif
 }
diff --git a/chrome/plugin/plugin_thread.cc b/chrome/plugin/plugin_thread.cc
index e4fd235..774780c 100644
--- a/chrome/plugin/plugin_thread.cc
+++ b/chrome/plugin/plugin_thread.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -6,10 +6,15 @@
 
 #include "build/build_config.h"
 
-#if defined(OS_LINUX)
+#if defined(USE_X11)
 #include <gtk/gtk.h>
+#elif defined(OS_MACOSX)
+#include <CoreFoundation/CoreFoundation.h>
 #endif
 
+#include <string>
+#include <vector>
+
 #include "base/command_line.h"
 #include "base/lazy_instance.h"
 #include "base/process_util.h"
@@ -27,8 +32,9 @@
 #include "webkit/glue/webkit_glue.h"
 #include "webkit/glue/plugins/webplugin_delegate_impl.h"
 
-#if defined(OS_MACOSX)
-#include <CoreFoundation/CoreFoundation.h>
+#if defined(USE_X11)
+#include "app/x11_util.h"
+#elif defined(OS_MACOSX)
 #include "app/l10n_util.h"
 #include "base/mac_util.h"
 #include "base/scoped_cftyperef.h"
@@ -79,6 +85,8 @@
       free(argv[i]);
     }
   }
+
+  x11_util::SetX11ErrorHandlers();
 #endif
 
   PatchNPNFunctions();
@@ -232,4 +240,4 @@
   return true;
 }
 
-} // namespace webkit_glue
+}  // namespace webkit_glue