Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(794)

Unified Diff: ui/base/x/x11_util.cc

Issue 7889040: Change X11 error handler override to allow easy X11 error checking. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gpu/command_buffer/service/vertex_attrib_manager_unittest.cc ('k') | ui/base/x/x11_util_internal.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/base/x/x11_util.cc
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc
index 39c2cff7c6f098fd1a951ce4113924f20b23bc70..0dd6e9c618db8793cf3ef12a7e1891de81503509 100644
--- a/ui/base/x/x11_util.cc
+++ b/ui/base/x/x11_util.cc
@@ -65,6 +65,8 @@ CachedPictFormats* get_cached_pict_formats() {
const size_t kMaxCacheSize = 5;
int DefaultX11ErrorHandler(Display* d, XErrorEvent* e) {
+ DCHECK(!MessageLoop::current() ||
+ MessageLoop::current()->type() == MessageLoop::TYPE_UI);
MessageLoop::current()->PostTask(
FROM_HERE, NewRunnableFunction(LogErrorEventDescription, d, *e));
return 0;
@@ -76,6 +78,14 @@ int DefaultX11IOErrorHandler(Display* d) {
_exit(1);
}
+XErrorHandler current_error_handler = DefaultX11ErrorHandler;
+XErrorEvent last_error_event = {0, NULL, 0, 0, 0, 0, 0 };
+
+int BaseX11ErrorHandler(Display* d, XErrorEvent* e) {
+ last_error_event = *e;
+ return current_error_handler(d, e);
+}
+
Atom GetAtom(const char* name) {
#if defined(TOOLKIT_USES_GTK)
return gdk_x11_get_xatom_by_name_for_display(
@@ -105,6 +115,49 @@ bool GetProperty(XID window, const std::string& property_name, long max_length,
property);
}
+std::string BuildX11ErrorString(const XErrorEvent& error_event) {
+ char error_str[256];
+ char request_str[256];
+
+ XGetErrorText(error_event.display, error_event.error_code, error_str,
+ sizeof(error_str));
+
+ strncpy(request_str, "Unknown", sizeof(request_str));
+ if (error_event.request_code < 128) {
+ std::string num = base::UintToString(error_event.request_code);
+ XGetErrorDatabaseText(error_event.display, "XRequest", num.c_str(),
+ "Unknown", request_str, sizeof(request_str));
+ } else {
+ int num_ext;
+ char** ext_list = XListExtensions(error_event.display, &num_ext);
+
+ for (int i = 0; i < num_ext; i++) {
+ int ext_code, first_event, first_error;
+ XQueryExtension(error_event.display, ext_list[i], &ext_code, &first_event,
+ &first_error);
+ if (error_event.request_code == ext_code) {
+ std::string msg = StringPrintf(
+ "%s.%d", ext_list[i], error_event.minor_code);
+ XGetErrorDatabaseText(error_event.display, "XRequest", msg.c_str(),
+ "Unknown", request_str, sizeof(request_str));
+ break;
+ }
+ }
+ XFreeExtensionList(ext_list);
+ }
+
+ std::ostringstream error_ss;
+ error_ss << "X Error detected: "
+ << "serial " << error_event.serial << ", "
+ << "error_code " << static_cast<int>(error_event.error_code)
+ << " (" << error_str << "), "
+ << "request_code " << static_cast<int>(error_event.request_code)
+ << ", "
+ << "minor_code " << static_cast<int>(error_event.minor_code)
+ << " (" << request_str << ")";
+ return error_ss.str();
+}
+
} // namespace
bool XDisplayExists() {
@@ -695,6 +748,7 @@ bool ChangeWindowDesktop(XID window, XID destination) {
}
void SetDefaultX11ErrorHandlers() {
+ XSetErrorHandler(BaseX11ErrorHandler);
SetX11ErrorHandlers(NULL, NULL);
}
@@ -730,6 +784,15 @@ bool IsX11WindowFullScreen(XID window) {
#endif
}
+void CheckForReportedX11Error() {
+ DCHECK(!MessageLoop::current() ||
+ MessageLoop::current()->type() == MessageLoop::TYPE_UI);
+ if (!last_error_event.display)
+ return;
+ XSync(last_error_event.display, False);
+ LOG(FATAL) << BuildX11ErrorString(last_error_event);
+}
+
// ----------------------------------------------------------------------------
// These functions are declared in x11_util_internal.h because they require
// XLib.h to be included, and it conflicts with many other headers.
@@ -808,51 +871,21 @@ XRenderPictFormat* GetRenderVisualFormat(Display* dpy, Visual* visual) {
void SetX11ErrorHandlers(XErrorHandler error_handler,
XIOErrorHandler io_error_handler) {
- XSetErrorHandler(error_handler ? error_handler : DefaultX11ErrorHandler);
- XSetIOErrorHandler(
- io_error_handler ? io_error_handler : DefaultX11IOErrorHandler);
+ DCHECK(!MessageLoop::current() ||
+ MessageLoop::current()->type() == MessageLoop::TYPE_UI);
+ current_error_handler = error_handler ?
+ error_handler : DefaultX11ErrorHandler;
+ XSetIOErrorHandler(io_error_handler ?
+ io_error_handler : DefaultX11IOErrorHandler);
}
void LogErrorEventDescription(Display* dpy,
const XErrorEvent& error_event) {
- char error_str[256];
- char request_str[256];
-
- XGetErrorText(dpy, error_event.error_code, error_str, sizeof(error_str));
-
- strncpy(request_str, "Unknown", sizeof(request_str));
- if (error_event.request_code < 128) {
- std::string num = base::UintToString(error_event.request_code);
- XGetErrorDatabaseText(
- dpy, "XRequest", num.c_str(), "Unknown", request_str,
- sizeof(request_str));
- } else {
- int num_ext;
- char** ext_list = XListExtensions(dpy, &num_ext);
-
- for (int i = 0; i < num_ext; i++) {
- int ext_code, first_event, first_error;
- XQueryExtension(dpy, ext_list[i], &ext_code, &first_event, &first_error);
- if (error_event.request_code == ext_code) {
- std::string msg = StringPrintf(
- "%s.%d", ext_list[i], error_event.minor_code);
- XGetErrorDatabaseText(
- dpy, "XRequest", msg.c_str(), "Unknown", request_str,
- sizeof(request_str));
- break;
- }
- }
- XFreeExtensionList(ext_list);
- }
-
- LOG(ERROR)
- << "X Error detected: "
- << "serial " << error_event.serial << ", "
- << "error_code " << static_cast<int>(error_event.error_code)
- << " (" << error_str << "), "
- << "request_code " << static_cast<int>(error_event.request_code) << ", "
- << "minor_code " << static_cast<int>(error_event.minor_code)
- << " (" << request_str << ")";
+ DCHECK(!MessageLoop::current() ||
+ MessageLoop::current()->type() == MessageLoop::TYPE_UI);
+ DCHECK_EQ(dpy, error_event.display)
+ << "Attempt to log error for mismatching X11 display.";
+ LOG(ERROR) << BuildX11ErrorString(error_event);
}
// ----------------------------------------------------------------------------
« no previous file with comments | « gpu/command_buffer/service/vertex_attrib_manager_unittest.cc ('k') | ui/base/x/x11_util_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698