xserver: Branch 'xwayland-22.1' - 5 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 1 09:04:26 UTC 2022


 hw/xwayland/xwayland-input.c   |    2 -
 hw/xwayland/xwayland-output.c  |    2 +
 hw/xwayland/xwayland-present.c |   10 ++++-
 os/backtrace.c                 |   80 ++++++++++++++++++++++++++++++++++++++---
 4 files changed, 87 insertions(+), 7 deletions(-)

New commits:
commit 5e7ba574ec11a4416f852fb674e8931dbda28c70
Author: zhoulei <zhoulei at kylinos.cn>
Date:   Mon Jan 25 19:41:16 2021 +0800

    xwayland: Change randr_output status when call xwl_output_remove()
    
    The function xwl_output_remove() is called when removing a monitor, but
    the actual status of the RandR output does not change.
    
    So, when RRTellChanged() is called from update_screen_size(), it won't
    have the output connection status up to date in the RandR event
    RROutputChangeNotifyEvent and X11 applications relying on that event
    like Qt will fail to emit their signal QGuiApplication::screenRemoved.
    
    To avoid that issue, make sure to mark the RandR output as disconnected
    prior to call xwl_output_remove().
    
    Fix commit 204f10c29 ("xwayland: Call RRTellChanged if the RandR configuration may have changed")
    
    Signed-off-by: zhoulei <zhoulei at kylinos.cn>
    Signed-off-by: Morose <chenlinxiang at kylinos.cn>
    Acked-by: Michel Dänzer <mdaenzer at redhat.com>
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 2ec7c1680a905cbf8ac3744415bc880d31f3f2fc)

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 3ad8adc8b..a351fc9f7 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -827,6 +827,8 @@ xwl_output_remove(struct xwl_output *xwl_output)
 
     xorg_list_del(&xwl_output->link);
 
+    RROutputSetConnection(xwl_output->randr_output, RR_Disconnected);
+
     xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
         output_get_new_size(it, &width, &height);
     update_screen_size(xwl_output, width, height);
commit 29d14492b136558911512042ff76959d75fc17bd
Author: Morose <chenlinxiang at kylinos.cn>
Date:   Thu Jun 23 09:52:24 2022 +0800

    xwayland: Fix check logic in sprite_check_lost_focus()
    
    When the pointer leaves an X11 window, and enters a Wayland native
    window, Xwayland has no idea about Wayland native windows and may
    generate the wrong crossing events to another X11 window instead.
    
    To avoid that issue, Xwayland implements its own XYToWindow() handler to
    compare the Wayland focused surface with the X11 window found in the
    window tree.
    
    Commit 59ad0e6a ("xwayland: Fix use after free of cursors") changed the
    logic in sprite_check_lost_focus() to use IsParent() to compare the
    windows, which works when the X11 window is reparented by the window
    manager, but fails in the case of an override redirect window.
    
    To fix the issue, also check whether last_xwindow is the window itself.
    
    Signed-off-by: Morose <chenlinxiang at kylinos.cn>
    Fixes: 59ad0e6a - xwayland: Fix use after free of cursors
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 92a00f52217b71107dcdc39cfaf56f77a41b42b1)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 672647f71..eda69a193 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -2935,7 +2935,7 @@ sprite_check_lost_focus(SpritePtr sprite, WindowPtr window)
 
     if (xwl_seat->focus_window == NULL &&
         xwl_seat->last_xwindow != NullWindow &&
-        IsParent(xwl_seat->last_xwindow, window))
+        (IsParent(xwl_seat->last_xwindow, window) || xwl_seat->last_xwindow == window))
         return TRUE;
 
     return FALSE;
commit 5c14db4b46bb8c7959ff8f5f1505a56e49a1ee98
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Jun 15 15:54:29 2022 +0200

    xwayland/present: Do not send two idle notify events for flip pixmaps
    
    Could happen if the buffer release event was already processed before
    xwl_present_flips_stop.
    
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1351
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit b9b33d88ede76f0eec5055320e1cb27b37bade15)

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index ce74482ef..99e476b2f 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -276,7 +276,15 @@ xwl_present_flips_stop(WindowPtr window)
         xwl_present_free_idle_vblank(vblank);
 
     if (xwl_present_window->flip_active) {
-        xwl_present_free_idle_vblank(xwl_present_window->flip_active);
+        struct xwl_present_event *event;
+
+        vblank = xwl_present_window->flip_active;
+        event = xwl_present_event_from_id((uintptr_t)vblank);
+        if (event->pixmap)
+            xwl_present_free_idle_vblank(vblank);
+        else
+            xwl_present_free_event(event);
+
         xwl_present_window->flip_active = NULL;
     }
 
commit 8c0fe08c6b13c30dd3332323f427272626e5ff1e
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Thu May 27 17:06:16 2021 -0700

    os: print registers in the libunwind version of xorg_backtrace()
    
    If the stack walker finds a signal frame, record the cursor at that point and
    then use unw_get_reg() to query the values of the architecture-specific
    registers at the frame that triggered the signal.
    
    Example output:
    
     (EE) Backtrace:
     (EE) 0: hw/xfree86/Xorg (OsSigHandler+0x25) [0x561458bb8195]
     (EE) 1: <signal handler called>
     (EE) 2: hw/xfree86/Xorg (dix_main+0x9c) [0x561458aead6c]
     (EE) 3: /usr/lib/libc.so.6 (__libc_start_main+0xd5) [0x7f2d23170b25]
     (EE) 4: hw/xfree86/Xorg (_start+0x2e) [0x561458aad8be]
     (EE)
     (EE) Registers at frame #2:
     (EE)   rax: 0x0
     (EE)   rbx: 0x561458c3ae60
     (EE)   rcx: 0x7f2d23328943
     (EE)   rdx: 0x0
     (EE)   rsi: 0x7ffcb6025030
     (EE)   rdi: 0xe
     (EE)   rbp: 0x0
     (EE)   rsp: 0x7ffcb6026430
     (EE)    r8: 0x0
     (EE)    r9: 0x0
     (EE)   r10: 0x8
     (EE)   r11: 0x246
     (EE)   r12: 0x561458aad890
     (EE)   r13: 0x0
     (EE)   r14: 0x0
     (EE)   r15: 0x0
     (EE)
     (EE) Segmentation fault at address 0x0
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    (cherry picked from commit dc8162d5f0552ed1ab7c21692bcabf45b48c6467)

diff --git a/os/backtrace.c b/os/backtrace.c
index bf7ee68e2..8025bffae 100644
--- a/os/backtrace.c
+++ b/os/backtrace.c
@@ -40,15 +40,73 @@
 #endif
 #include <dlfcn.h>
 
+static void
+print_registers(int frame, unw_cursor_t cursor)
+{
+    const struct {
+        const char *name;
+        int regnum;
+    } regs[] = {
+#if UNW_TARGET_X86_64
+        { "rax", UNW_X86_64_RAX },
+        { "rbx", UNW_X86_64_RBX },
+        { "rcx", UNW_X86_64_RCX },
+        { "rdx", UNW_X86_64_RDX },
+        { "rsi", UNW_X86_64_RSI },
+        { "rdi", UNW_X86_64_RDI },
+        { "rbp", UNW_X86_64_RBP },
+        { "rsp", UNW_X86_64_RSP },
+        { " r8", UNW_X86_64_R8  },
+        { " r9", UNW_X86_64_R9  },
+        { "r10", UNW_X86_64_R10 },
+        { "r11", UNW_X86_64_R11 },
+        { "r12", UNW_X86_64_R12 },
+        { "r13", UNW_X86_64_R13 },
+        { "r14", UNW_X86_64_R14 },
+        { "r15", UNW_X86_64_R15 },
+#endif
+    };
+    const int num_regs = sizeof(regs) / sizeof(*regs);
+    int ret, i;
+
+    if (num_regs == 0)
+        return;
+
+    /*
+     * Advance the cursor from the signal frame to the one that triggered the
+     * signal.
+     */
+    frame++;
+    ret = unw_step(&cursor);
+    if (ret < 0) {
+        ErrorFSigSafe("unw_step failed: %s [%d]\n", unw_strerror(ret), ret);
+        return;
+    }
+
+    ErrorFSigSafe("\n");
+    ErrorFSigSafe("Registers at frame #%d:\n", frame);
+
+    for (i = 0; i < num_regs; i++) {
+        uint64_t val;
+        ret = unw_get_reg(&cursor, regs[i].regnum, &val);
+        if (ret < 0) {
+            ErrorFSigSafe("unw_get_reg(%s) failed: %s [%d]\n",
+                          regs[i].name, unw_strerror(ret), ret);
+        } else {
+            ErrorFSigSafe("  %s: 0x%" PRIx64 "\n", regs[i].name, val);
+        }
+    }
+}
+
 void
 xorg_backtrace(void)
 {
-    unw_cursor_t cursor;
+    unw_cursor_t cursor, signal_cursor;
     unw_context_t context;
     unw_word_t ip;
     unw_word_t off;
     unw_proc_info_t pip;
-    int ret, i = 0;
+    int ret, i = 0, signal_frame = -1;
     char procname[256];
     const char *filename;
     Dl_info dlinfo;
@@ -99,6 +157,9 @@ xorg_backtrace(void)
 
 
         if (unw_is_signal_frame(&cursor)) {
+            signal_cursor = cursor;
+            signal_frame = i;
+
             ErrorFSigSafe("%u: <signal handler called>\n", i++);
         } else {
             ErrorFSigSafe("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
@@ -110,6 +171,10 @@ xorg_backtrace(void)
         if (ret < 0)
             ErrorFSigSafe("unw_step failed: %s [%d]\n", unw_strerror(ret), ret);
     }
+
+    if (signal_frame >= 0)
+        print_registers(signal_frame, signal_cursor);
+
     ErrorFSigSafe("\n");
 }
 #else /* HAVE_LIBUNWIND */
commit 891ea8f74d2bfae4e1edc082544fedee3220d3da
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Thu May 27 16:58:56 2021 -0700

    os: print <signal handler called> if unw_is_signal_frame()
    
    libunwind has a function to query whether the cursor points to a signal frame.
    Use this to print
    
     1: <signal handler called>
    
    like GDB does, rather than printing something less useful such as
    
     1: /usr/lib/libpthread.so.0 (funlockfile+0x60) [0x7f679838b870]
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    (cherry picked from commit a73641937a9e0df3a5d32f0dac7114d971abcd21)

diff --git a/os/backtrace.c b/os/backtrace.c
index 99d776950..bf7ee68e2 100644
--- a/os/backtrace.c
+++ b/os/backtrace.c
@@ -97,9 +97,14 @@ xorg_backtrace(void)
         else
             filename = "?";
 
-        ErrorFSigSafe("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
-            ret == -UNW_ENOMEM ? "..." : "", (int)off,
-            (void *)(uintptr_t)(ip));
+
+        if (unw_is_signal_frame(&cursor)) {
+            ErrorFSigSafe("%u: <signal handler called>\n", i++);
+        } else {
+            ErrorFSigSafe("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
+                ret == -UNW_ENOMEM ? "..." : "", (int)off,
+                (void *)(uintptr_t)(ip));
+        }
 
         ret = unw_step(&cursor);
         if (ret < 0)


More information about the xorg-commit mailing list