commit a9a9ba3d6c4ddbaf1fa8cf9cba76e683df975d31
parent 779eda1adeb9a8ea6e8124d2d5de2d2eddd8acdb
Author: Kui-Feng Lee <thinker.li@gmail.com>
Date: Fri, 24 Oct 2025 19:30:43 +0000
Bug 1996093 - Separate WlLogHandler crash signatures by error pattern r=stransky
Add pattern-specific crash functions to WlLogHandler to create distinct
crash signatures for different Wayland protocol errors. This makes it
much easier to track, triage, and fix specific issues instead of having
all errors lumped under one signature (Bug 1863047).
The crash functions are marked MOZ_NEVER_INLINE to ensure they appear
in crash stacks with distinct signatures. Pattern matching is ordered
by observed frequency from crash statistics (25 recent crash reports):
- WlLogHandler_UnknownObject (32% of crashes)
- WlLogHandler_ViewportBufferBounds (20%)
- WlLogHandler_InvalidSurfaceFrame (20%)
- WlLogHandler_ColorManagerInvalidOutput (12%)
- WlLogHandler_MessageLengthExceeded (8%)
- WlLogHandler_DmabufImportFailed (4%)
- WlLogHandler_RegistryError (4%)
- WlLogHandler_CallbackInvalid (4%)
- WlLogHandler_InvalidDisplayObject (4%)
- WlLogHandler_MarshallingError (4%)
- Inline fallback for unmatched patterns
This change will help separate issues like viewport buffer bounds errors
(Bug 1991369) from dmabuf import failures (Bug 1989726) and other distinct
protocol error types.
Differential Revision: https://phabricator.services.mozilla.com/D269830
Diffstat:
1 file changed, 150 insertions(+), 0 deletions(-)
diff --git a/widget/gtk/nsWaylandDisplay.cpp b/widget/gtk/nsWaylandDisplay.cpp
@@ -877,6 +877,97 @@ void nsWaylandDisplay::WaitForAsyncRoundtrips() {
}
}
+// Separate crash functions for different Wayland protocol error patterns.
+// These functions are marked MOZ_NEVER_INLINE to ensure distinct crash
+// signatures for different error types, making them easier to track and fix.
+//
+// Pattern analysis is based on 25 recent crash reports with the
+// mozilla::widget::WlLogHandler signature. Frequencies are noted in comments
+// below.
+
+// 32% of crashes - Example: "unknown object (4278190083), message error(ous)"
+MOZ_NEVER_INLINE static void WlLogHandler_UnknownObject(const char* error) {
+ MOZ_CRASH_UNSAFE_PRINTF("(%s) %s Proxy: %s",
+ GetDesktopEnvironmentIdentifier().get(), error,
+ WaylandProxy::GetState());
+}
+
+// 20% of crashes - Example: "wp_viewport#296: error 2: source rectangle out
+// of buffer bounds"
+MOZ_NEVER_INLINE static void WlLogHandler_ViewportBufferBounds(
+ const char* error) {
+ MOZ_CRASH_UNSAFE_PRINTF("(%s) %s Proxy: %s",
+ GetDesktopEnvironmentIdentifier().get(), error,
+ WaylandProxy::GetState());
+}
+
+// 20% of crashes - Example: "wl_display#1: error 1: invalid arguments for
+// wl_surface#730.frame"
+MOZ_NEVER_INLINE static void WlLogHandler_InvalidSurfaceFrame(
+ const char* error) {
+ MOZ_CRASH_UNSAFE_PRINTF("(%s) %s Proxy: %s",
+ GetDesktopEnvironmentIdentifier().get(), error,
+ WaylandProxy::GetState());
+}
+
+// 12% of crashes - Example: "wp_color_manager_v1#44: error -1: Invalid output
+// (2)"
+MOZ_NEVER_INLINE static void WlLogHandler_ColorManagerInvalidOutput(
+ const char* error) {
+ MOZ_CRASH_UNSAFE_PRINTF("(%s) %s Proxy: %s",
+ GetDesktopEnvironmentIdentifier().get(), error,
+ WaylandProxy::GetState());
+}
+
+// 8% of crashes - Example: "Message length 22222 exceeds limit 4096"
+MOZ_NEVER_INLINE static void WlLogHandler_MessageLengthExceeded(
+ const char* error) {
+ MOZ_CRASH_UNSAFE_PRINTF("(%s) %s Proxy: %s",
+ GetDesktopEnvironmentIdentifier().get(), error,
+ WaylandProxy::GetState());
+}
+
+// 4% of crashes - Example: "wl_display#1: error 0: invalid object 61246"
+MOZ_NEVER_INLINE static void WlLogHandler_InvalidDisplayObject(
+ const char* error) {
+ MOZ_CRASH_UNSAFE_PRINTF("(%s) %s Proxy: %s",
+ GetDesktopEnvironmentIdentifier().get(), error,
+ WaylandProxy::GetState());
+}
+
+// 4% of crashes - Example: "failed to import supplied dmabufs: EGL failed to
+// allocate resources"
+MOZ_NEVER_INLINE static void WlLogHandler_DmabufImportFailed(
+ const char* error) {
+ MOZ_CRASH_UNSAFE_PRINTF("(%s) %s Proxy: %s",
+ GetDesktopEnvironmentIdentifier().get(), error,
+ WaylandProxy::GetState());
+}
+
+// 4% of crashes - Example: "wl_registry@36: error 0: invalid global
+// wl_output (55)"
+MOZ_NEVER_INLINE static void WlLogHandler_RegistryError(const char* error) {
+ MOZ_CRASH_UNSAFE_PRINTF("(%s) %s Proxy: %s",
+ GetDesktopEnvironmentIdentifier().get(), error,
+ WaylandProxy::GetState());
+}
+
+// 4% of crashes - Example: "invalid object (277), type (wl_callback), message
+// begin(3uuou)"
+MOZ_NEVER_INLINE static void WlLogHandler_CallbackInvalid(const char* error) {
+ MOZ_CRASH_UNSAFE_PRINTF("(%s) %s Proxy: %s",
+ GetDesktopEnvironmentIdentifier().get(), error,
+ WaylandProxy::GetState());
+}
+
+// 4% of crashes - Example: "error marshalling arguments for set_surface
+// (signature o): null value passed for arg 0"
+MOZ_NEVER_INLINE static void WlLogHandler_MarshallingError(const char* error) {
+ MOZ_CRASH_UNSAFE_PRINTF("(%s) %s Proxy: %s",
+ GetDesktopEnvironmentIdentifier().get(), error,
+ WaylandProxy::GetState());
+}
+
static void WlLogHandler(const char* format, va_list args) {
char error[1000];
VsprintfLiteral(error, format, args);
@@ -892,6 +983,65 @@ static void WlLogHandler(const char* format, va_list args) {
return;
}
+ // Pattern matching to dispatch to specific crash functions.
+ // Patterns ordered by frequency (most common first) for performance.
+
+ // Pattern 1: Unknown object errors (32% of crashes)
+ if (strstr(error, "unknown object") && strstr(error, "message error")) {
+ WlLogHandler_UnknownObject(error);
+ }
+
+ // Pattern 2: wp_viewport buffer bounds errors (20% of crashes)
+ if (strstr(error, "wp_viewport") &&
+ strstr(error, "source rectangle out of buffer bounds")) {
+ WlLogHandler_ViewportBufferBounds(error);
+ }
+
+ // Pattern 3: Invalid wl_surface.frame arguments (20% of crashes)
+ if (strstr(error, "wl_display") && strstr(error, "invalid arguments") &&
+ strstr(error, "wl_surface") && strstr(error, ".frame")) {
+ WlLogHandler_InvalidSurfaceFrame(error);
+ }
+
+ // Pattern 4: wp_color_manager_v1 invalid output (12% of crashes)
+ if (strstr(error, "wp_color_manager_v1") && strstr(error, "Invalid output")) {
+ WlLogHandler_ColorManagerInvalidOutput(error);
+ }
+
+ // Pattern 5: Message length exceeded (8% of crashes)
+ if ((strstr(error, "message length") || strstr(error, "Message length")) &&
+ strstr(error, "exceeds")) {
+ WlLogHandler_MessageLengthExceeded(error);
+ }
+
+ // Pattern 6: Invalid wl_display object (4% of crashes)
+ if (strstr(error, "wl_display") && strstr(error, "invalid object") &&
+ !strstr(error, "unknown object")) {
+ WlLogHandler_InvalidDisplayObject(error);
+ }
+
+ // Pattern 7: dmabuf import failures (4% of crashes)
+ if (strstr(error, "dmabuf") && strstr(error, "failed") &&
+ strstr(error, "EGL")) {
+ WlLogHandler_DmabufImportFailed(error);
+ }
+
+ // Pattern 8: wl_registry errors (4% of crashes)
+ if (strstr(error, "wl_registry") && strstr(error, "wl_output")) {
+ WlLogHandler_RegistryError(error);
+ }
+
+ // Pattern 9: wl_callback invalid (4% of crashes)
+ if (strstr(error, "wl_callback") && strstr(error, "invalid object")) {
+ WlLogHandler_CallbackInvalid(error);
+ }
+
+ // Pattern 10: Marshalling errors (4% of crashes)
+ if (strstr(error, "error marshalling arguments")) {
+ WlLogHandler_MarshallingError(error);
+ }
+
+ // Fallback for unmatched patterns - use original inline code
MOZ_CRASH_UNSAFE_PRINTF("(%s) %s Proxy: %s",
GetDesktopEnvironmentIdentifier().get(), error,
WaylandProxy::GetState());