Launch a DBus session in xvfb.py
This CL ensures DBUS_SESSION_BUS_ADDRESS is set when running tests. This is
necessary because otherwise the dbus daemon will be autolaunched on attempted
first use. This is problematic because glib allocates memory between fork() and
exec() for the daemon, causing deadlock if the global malloc lock is held. This
is fixed by glib commit [1], but this workaround will be necessary until the fix
rolls into Chromium's CI.
[1] https://gitlab.gnome.org/GNOME/glib/commit/f2917459f745bebf931bccd5cc2c33aa81ef4d12
BUG=1027852
R=dpranke
NOPRESUBMIT=true
Change-Id: Iea6d702d4d4c724ad44d0aa82522175f6b3a78e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1937507
Commit-Queue: Thomas Anderson <[email protected]>
Auto-Submit: Thomas Anderson <[email protected]>
Reviewed-by: Dirk Pranke <[email protected]>
Cr-Commit-Position: refs/heads/master@{#720698}
diff --git a/testing/xvfb.py b/testing/xvfb.py
index bb9d3975..bbdc113 100755
--- a/testing/xvfb.py
+++ b/testing/xvfb.py
@@ -8,6 +8,7 @@
import os
import os.path
import random
+import re
import signal
import subprocess
import sys
@@ -41,6 +42,37 @@
'%s running after SIGTERM and SIGKILL; good luck!' % name
+def launch_dbus(env):
+ """Starts a DBus session.
+
+ Works around a bug in GLib where it performs operations which aren't
+ async-signal-safe (in particular, memory allocations) between fork and exec
+ when it spawns subprocesses. This causes threads inside Chrome's browser and
+ utility processes to get stuck, and this harness to hang waiting for those
+ processes, which will never terminate. This doesn't happen on users'
+ machines, because they have an active desktop session and the
+ DBUS_SESSION_BUS_ADDRESS environment variable set, but it can happen on
+ headless environments. This is fixed by glib commit [1], but this workaround
+ will be necessary until the fix rolls into Chromium's CI.
+
+ [1] https://gitlab.gnome.org/GNOME/glib/commit/f2917459f745bebf931bccd5cc2c33aa81ef4d12
+
+ Modifies the passed in environment with at least DBUS_SESSION_BUS_ADDRESS and
+ DBUS_SESSION_BUS_PID set.
+ """
+ if 'DBUS_SESSION_BUS_ADDRESS' in os.environ:
+ return
+ try:
+ dbus_output = subprocess.check_output(
+ ['dbus-launch', '--exit-with-x11'], env=env).split('\n')
+ for line in dbus_output:
+ m = re.match(r'([^=]+)\=(.+)', line)
+ if m:
+ env[m.group(1)] = m.group(2)
+ except (subprocess.CalledProcessError, OSError) as e:
+ print 'Exception while running dbus_launch: %s' % e
+
+
# TODO(crbug.com/949194): Encourage setting flags to False.
def run_executable(
cmd, env, stdoutfile=None, use_openbox=True, use_xcompmgr=True):
@@ -131,6 +163,8 @@
env['DISPLAY'] = display
+ launch_dbus(env)
+
if use_openbox:
openbox_proc = subprocess.Popen(
'openbox', stderr=subprocess.STDOUT, env=env)