Bug 76662

Summary: SIGSEGV in wl_resource_post_event during wl_argument_from_va_list
Product: Wayland Reporter: Anu Reddy <anasuyax.r.nannuri>
Component: westonAssignee: Wayland bug list <wayland-bugs>
Status: VERIFIED FIXED QA Contact:
Severity: critical    
Priority: medium CC: ricardo.vieira
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: gdb_backtrace
gdb_backtrace1

Description Anu Reddy 2014-03-26 23:17:05 UTC
Created attachment 96430 [details]
gdb_backtrace

While close animation is performed, clicking on the surface causes segfault. This happens only when a client is closed via context menu. See attached gdb backtrace for more info.

Steps:
1. Launch weston
2. Launch a client : weston-flower
3. Try to close weston-flower via context menu option 'close' + mouse click.


Environment:
wayland (master) heads/master-0-g1bf13ae
drm (master) heads/master-0-g1cb5fc7
mesa (master) heads/master-0-g64278b3
libva (master) heads/master-0-ge30e29a
intel-driver (master) heads/master-0-g75a7b09
cairo (master) heads/master-0-gbb17403
libinput (master) heads/master-0-ge49a988
weston (master) heads/master-0-gfe9671e
gstreamer (master) heads/master-0-gf85ce91
Comment 1 Anu Reddy 2014-03-26 23:18:08 UTC
Created attachment 96431 [details]
gdb_backtrace1
Comment 2 Anu Reddy 2014-03-27 18:10:58 UTC
Well, I found different ways to reproduce this issue. Weston crashes while selecting any of the client context menu items (Close, Move to workspace above, Move to workspace below ). 

1. Launch any client
2. Try to select any  context menu option  +  mouse click on the workspace or toolbar
Comment 3 Ricardo Vieira 2014-04-01 22:20:33 UTC
*** Bug 76866 has been marked as a duplicate of this bug. ***
Comment 4 Ander Conselvan de Oliveira 2014-04-04 11:35:25 UTC
It seems the problem is related to the popup grab not ending at the moment the button is released after a menu item was clicked. In popup_grab_button() there's a statement

        if (/* there's focus */) {
               /* send button event */
        } else if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
                   (shseat->popup_grab.initial_up ||
                    time - shseat->seat->pointer->grab_time > 500)) {
                popup_grab_end(grab->pointer);
        }

If that was just two separate 'if' statements, the grab would end at the moment the button is released. I couldn't really figure out why the 'else if' is there looking through the git history, but I take there's something I'm not seeing.

The way it is now, the grab ends only when the destroy animation finishes or the user click somewhere else. In the latter case, if the click is in a surface that belongs to another client, the click event is swallowed.
Comment 5 Kristian Høgsberg 2014-04-07 18:34:41 UTC
Fixed in:

commit a46b946cb3842a6e6296ed7c4c7b0303096a2b00
Author: Bryan Cain <bryancain3@gmail.com>
Date:   Fri Apr 4 17:41:24 2014 -0500

    shell: Fix segfault from trying to access a destroyed popup shell surface
    
    The shell_destroy_shell_surface function only set the backing resource to
    NULL, leaving an unusable surface in the popup_grab list until the surface's
    fading animation finished and it could be freed. This caused a segfault if
    the shell tried to forcibly break the grab during that time interval due to
    the compositor losing the keyboard focus.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=77072
Comment 6 Kristian Høgsberg 2014-04-07 18:46:53 UTC
(In reply to comment #4)
> It seems the problem is related to the popup grab not ending at the moment
> the button is released after a menu item was clicked. In popup_grab_button()
> there's a statement
> 
>         if (/* there's focus */) {
>                /* send button event */
>         } else if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
>                    (shseat->popup_grab.initial_up ||
>                     time - shseat->seat->pointer->grab_time > 500)) {
>                 popup_grab_end(grab->pointer);
>         }
> 
> If that was just two separate 'if' statements, the grab would end at the
> moment the button is released. I couldn't really figure out why the 'else
> if' is there looking through the git history, but I take there's something
> I'm not seeing.

The first case handles buttons up/down in any of the grab owners surfaces.  This never ends the grab and just sends the event to the client to process.

The else branch deals with button events outside the grab owners windows, which cancels the grab if it's a release event and we've either

  1) seen the release event from the click that triggered the popup, or
  2) it's the release event from the initial click and it comes later than 500ms after the click (click-and-drag menu use case)
 
> The way it is now, the grab ends only when the destroy animation finishes or
> the user click somewhere else. In the latter case, if the click is in a
> surface that belongs to another client, the click event is swallowed.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.