[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#861956: X server hangs at shutdown if it's in background



Package: xserver-xorg-core
Version: 2:1.19.2-1
Tags: patch

Dear Maintainers,

When X server is in background (i.e. when its tty is not active), it 
doesn't react to SIGTERM and causes a shutdown delay.

I first noticed this after disabling Wayland in GDM by uncommenting 
`WaylandEnable=false' in /etc/gdm3/daemon.conf. In this configuration 
GDM uses X server (and doesn't shut it down when starting a user 
session, so there are two X servers running: one for user session 
(foreground), and still one for GDM (background)).

When I shut the machine down right from GDM without logging in, it went 
OK. However, if I logged in and issued reboot from inside the user 
session, shutdown was delayed for about 1 and a half minute, with the 
following message in console: `A stop job is running for Session c1 of 
user Debian-gdm'.

I enabled debug-shell.service, and here is what I got:

# loginctl session-status c1
c1 - Debian-gdm (114)
	   Since: Thu 2017-05-04 21:47:00 MSK; 10min ago
	  Leader: 502
	    Seat: seat0; vc1
	     TTY: /dev/tty1
	 Service: gdm-launch-environment; type x11; class greeter
	   State: closing
	    Unit: session-c1.scope
		  `-515 /usr/lib/xorg/Xorg vt1 -displayfd 3 -auth /run/user/114/gdm/Xauthority -background none -noreset -keeptty -verbose 3

May 04 21:49:15 debian /usr/lib/gdm3/gdm-x-session[513]: (II) systemd-logind: got pause for 13:65
May 04 21:49:15 debian /usr/lib/gdm3/gdm-x-session[513]: (II) systemd-logind: got pause for 13:67
May 04 21:49:15 debian /usr/lib/gdm3/gdm-x-session[513]: (II) systemd-logind: got pause for 13:69
May 04 21:49:15 debian /usr/lib/gdm3/gdm-x-session[513]: (II) systemd-logind: got pause for 13:71
May 04 21:49:15 debian /usr/lib/gdm3/gdm-x-session[513]: (II) systemd-logind: got pause for 13:68
May 04 21:49:15 debian /usr/lib/gdm3/gdm-x-session[513]: (II) systemd-logind: got pause for 13:64
May 04 21:49:15 debian /usr/lib/gdm3/gdm-x-session[513]: (II) systemd-logind: got pause for 226:0
May 04 21:57:08 debian gnome-session-binary[523]: WARNING: Lost name on bus: org.gnome.SessionManager
May 04 21:57:08 debian gnome-session[523]: gnome-session-binary[523]: WARNING: Lost name on bus: org.gnome.SessionManager
May 04 21:57:08 debian systemd[1]: Stopping Session c1 of user Debian-gdm.

As you see, the X server was still running. `kill -s SIGTERM 515' had 
no effect. It required SIGKILL to shut down the process.

`pstree' gave the following output:

# pstree
systemd-+-NetworkManager-+-{gdbus}
        |                `-{gmain}
        |-Xorg---{InputThread}
        |-bash-+-pstree
        |      `-shutdown
        |-dbus-daemon
        |-dhclient
        |-systemd-journal
        |-systemd-logind
        `-systemd-udevd

Looked like the InputThread thread was still running. It was confirmed 
after attaching GDB to the server process at next shutdown (hence a 
different PID):

# gdb --pid=536
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Attaching to process 536
[New LWP 542]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f3851d5e6cd in pthread_join (threadid=139879650666240, 
    thread_return=thread_return@entry=0x0) at pthread_join.c:90
(gdb) info threads
  Id   Target Id         Frame 
* 1    Thread 0x7f385408ba40 (LWP 536) "Xorg" 0x00007f3851d5e6cd in pthread_join (
    threadid=139879650666240, thread_return=thread_return@entry=0x0) at pthread_join.c:90
  2    Thread 0x7f3844e3a700 (LWP 542) "InputThread" __lll_lock_wait ()
    at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
(gdb) bt
#0  0x00007f3851d5e6cd in pthread_join (threadid=139879650666240, 
    thread_return=thread_return@entry=0x0) at pthread_join.c:90
#1  0x000055d6880e63f0 in InputThreadFini () at ../../../../os/inputthread.c:500
#2  0x000055d687f816a6 in dix_main (argc=12, argv=0x7fff890930c8, envp=<optimized out>)
    at ../../../../dix/main.c:312
#3  0x00007f38519d82b1 in __libc_start_main (main=0x55d687f6b260 <main>, argc=12, 
    argv=0x7fff890930c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
    stack_end=0x7fff890930b8) at ../csu/libc-start.c:291
#4  0x000055d687f6b29a in _start ()
(gdb) thread 2
[Switching to thread 2 (Thread 0x7f3844e3a700 (LWP 542))]
#0  __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
(gdb) bt
#0  __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1  0x00007f3851d5fc06 in __GI___pthread_mutex_lock (
    mutex=mutex@entry=0x55d68837de60 <input_mutex>) at ../nptl/pthread_mutex_lock.c:115
#2  0x000055d6880e5c80 in input_lock () at ../../../../os/inputthread.c:113
#3  0x000055d6880e5df5 in InputThreadDoWork (arg=<optimized out>)
    at ../../../../os/inputthread.c:343
#4  0x00007f3851d5d494 in start_thread (arg=0x7f3844e3a700) at pthread_create.c:333
#5  0x00007f3851aa093f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:97
(gdb) 

So, the main thread waited for the input thread to quit while the latter 
was locked in pthread_mutex_lock().

After searching a bit, I found a suspicious function xf86VTLeave() at
file hw/xfree86/common/xf86Events.c, line 411 [1], which locked input
mutex, but didn't unlock it at execution path when function
xf86VTSwitchAway() at line 450 returned true. Indeed, after adding
input_unlock() before return, I can't reproduce the issue anymore.

Patch is attached.

 [1] https://sources.debian.net/src/xorg-server/2:1.19.3-1/hw/xfree86/common/xf86Events.c/#L411


-- 
Алексей Шилин
diff -aNru xorg-server-1.19.2.orig/hw/xfree86/common/xf86Events.c xorg-server-1.19.2/hw/xfree86/common/xf86Events.c
--- xorg-server-1.19.2.orig/hw/xfree86/common/xf86Events.c	2017-03-03 02:03:58.000000000 +0300
+++ xorg-server-1.19.2/hw/xfree86/common/xf86Events.c	2017-05-06 14:57:25.184007000 +0300
@@ -468,6 +468,8 @@
 
     xf86UpdateHasVTProperty(FALSE);
 
+    input_unlock();
+
     return;
 
 switch_failed:

Reply to: