/src/mozilla-central/toolkit/xre/nsGDKErrorHandler.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #include "nsGDKErrorHandler.h" |
7 | | |
8 | | #include <gtk/gtk.h> |
9 | | #include <gdk/gdkx.h> |
10 | | #include <errno.h> |
11 | | #include <stdlib.h> |
12 | | #include <string.h> |
13 | | |
14 | | #include "nsDebug.h" |
15 | | #include "nsString.h" |
16 | | #include "nsX11ErrorHandler.h" |
17 | | |
18 | | #include "prenv.h" |
19 | | |
20 | | |
21 | | /* See https://bugzilla.gnome.org/show_bug.cgi?id=629608#c8 |
22 | | * |
23 | | * GDK implements X11 error traps to ignore X11 errors. |
24 | | * Unfortunatelly We don't know which X11 events can be ignored |
25 | | * so we have to utilize the Gdk error handler to avoid |
26 | | * false alarms in Gtk3. |
27 | | */ |
28 | | static void |
29 | | GdkErrorHandler(const gchar *log_domain, GLogLevelFlags log_level, |
30 | | const gchar *message, gpointer user_data) |
31 | 0 | { |
32 | 0 | if (strstr(message, "X Window System error")) { |
33 | 0 | XErrorEvent event; |
34 | 0 | nsDependentCString buffer(message); |
35 | 0 | char *endptr; |
36 | 0 |
|
37 | 0 | /* Parse Gdk X Window error message which has this format: |
38 | 0 | * (Details: serial XXXX error_code XXXX request_code XXXX (XXXX) minor_code XXXX) |
39 | 0 | */ |
40 | 0 | NS_NAMED_LITERAL_CSTRING(serialString, "(Details: serial "); |
41 | 0 | int32_t start = buffer.Find(serialString); |
42 | 0 | if (start == kNotFound) |
43 | 0 | MOZ_CRASH_UNSAFE_OOL(message); |
44 | 0 |
|
45 | 0 | start += serialString.Length(); |
46 | 0 | errno = 0; |
47 | 0 | event.serial = strtol(buffer.BeginReading() + start, &endptr, 10); |
48 | 0 | if (errno) |
49 | 0 | MOZ_CRASH_UNSAFE_OOL(message); |
50 | 0 |
|
51 | 0 | NS_NAMED_LITERAL_CSTRING(errorCodeString, " error_code "); |
52 | 0 | if (!StringBeginsWith(Substring(endptr, buffer.EndReading()), errorCodeString)) |
53 | 0 | MOZ_CRASH_UNSAFE_OOL(message); |
54 | 0 |
|
55 | 0 | errno = 0; |
56 | 0 | event.error_code = strtol(endptr + errorCodeString.Length(), &endptr, 10); |
57 | 0 | if (errno) |
58 | 0 | MOZ_CRASH_UNSAFE_OOL(message); |
59 | 0 |
|
60 | 0 | NS_NAMED_LITERAL_CSTRING(requestCodeString, " request_code "); |
61 | 0 | if (!StringBeginsWith(Substring(endptr, buffer.EndReading()), requestCodeString)) |
62 | 0 | MOZ_CRASH_UNSAFE_OOL(message); |
63 | 0 |
|
64 | 0 | errno = 0; |
65 | 0 | event.request_code = strtol(endptr + requestCodeString.Length(), &endptr, 10); |
66 | 0 | if (errno) |
67 | 0 | MOZ_CRASH_UNSAFE_OOL(message); |
68 | 0 |
|
69 | 0 | NS_NAMED_LITERAL_CSTRING(minorCodeString, " minor_code "); |
70 | 0 | start = buffer.Find(minorCodeString, /* aIgnoreCase = */ false, |
71 | 0 | endptr - buffer.BeginReading()); |
72 | 0 | if (!start) |
73 | 0 | MOZ_CRASH_UNSAFE_OOL(message); |
74 | 0 |
|
75 | 0 | errno = 0; |
76 | 0 | event.minor_code = strtol(buffer.BeginReading() + start + minorCodeString.Length(), nullptr, 10); |
77 | 0 | if (errno) |
78 | 0 | MOZ_CRASH_UNSAFE_OOL(message); |
79 | 0 |
|
80 | 0 | event.display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); |
81 | 0 | // Gdk does not provide resource ID |
82 | 0 | event.resourceid = 0; |
83 | 0 |
|
84 | 0 | X11Error(event.display, &event); |
85 | 0 | } else { |
86 | 0 | g_log_default_handler(log_domain, log_level, message, user_data); |
87 | 0 | MOZ_CRASH_UNSAFE_OOL(message); |
88 | 0 | } |
89 | 0 | } |
90 | | |
91 | | void |
92 | | InstallGdkErrorHandler() |
93 | 0 | { |
94 | 0 | g_log_set_handler("Gdk", |
95 | 0 | (GLogLevelFlags)(G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), |
96 | 0 | GdkErrorHandler, |
97 | 0 | nullptr); |
98 | 0 | if (PR_GetEnv("MOZ_X_SYNC")) { |
99 | 0 | XSynchronize(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), True); |
100 | 0 | } |
101 | 0 | } |