* The daemontools package (or one of its drop-in replacements, like runit
or freedt; but only daemontools has been tested so far).
-* The crash dump monitor also uses "inotifywait" (part of inotify-tools [2])
-
In short, in a Debian-based system you can ensure you have the needed bits
with the following command:
- apt-get install inotify-tools daemontools-run
+ apt-get install daemontools-run
Setup
4. Edit the configuration file to suit your needs, the comments should
be self-explanatory.
-5. Drop the "buildbot", "pulseaudio" and "xvfb" directories (plus
- "crashmon", if desired) to the service control directory of
+5. Drop the "buildbot" and "pulseaudio" directories to the service control directory of
daemontools; for Debian-based setups that would be "/etc/service"
==========
[1] http://cr.yp.to/daemontools.html
-[2] http://wiki.github.com/rvoicilas/inotify-tools/
+++ /dev/null
-#! /bin/bash
-#
-# Copyright (C) 2010 Carlos Lopez <clopez@igalia.com>, Igalia S.L.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Library General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Library General Public License for more details.
-#
-# You should have received a copy of the GNU Library General Public License
-# along with this library; see the file COPYING.LIB. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-# Boston, MA 02110-1301, USA.
-
-set -e
-
-[ "${coredir}" ] || {
- echo "Env var '\${coredir}' not defined!" >&2
- exit 111
-}
-[ "${programpath}" ] || {
- echo "Env var '\${programpath}' not defined" >&2
- exit 111
-}
-[ "${arch}" ] || {
- echo "Env var '\${arch}' not defined" >&2
- exit 111
-}
-[ "${mailto}" ] || {
- echo "Env var '\${mailto}' not defined" >&2
- exit 111
-}
-
-
-inotifywait -q -m --format '%f' --exclude '.trace.html$' -e close_write "${coredir}" | \
-while read -r coredump
-do
- if grep -qE '^core-when_[[:digit:]]{10\,12}-_-who_[[:print:]]+-_-why_' <<< "${coredump}"
- then
- # Get revision number from Subversion sources
- rev=$(cd "${crashmon_src_path}" && svn info | sed -e '/^Revision:/s/Revision: //p' -e d)
-
- # Get the who from the coredump name
- programfile=$(echo "${coredump}" \
- | awk -F'-_-who_' '{ print $2 }'\
- | awk -F'-_-why_' '{ print $1 }')
-
- # Sometimes programfile gets cut when it is a long name:
- # Search using wildcards
- fullprogrampath=$(find "${programpath}" -executable -name "${programfile}"\* | head -n1)
-
- ( printf "<html><head><title>StackTrace for ${programfile} from svn"
- printf " rev ${rev}</title></head>\n<body>Core dump file: "
- printf "<a href=\"cores/${coredump}\">${coredump}</a><br/>\n"
- printf "<pre>Executable crashed: ${fullprogrampath}</pre>\n"
- printf "<br/><hr><b>Stack Trace:</b><hr><br/>\n<pre>"
-
- gdb -ex "thread apply all bt" --batch "${fullprogrampath}" "${coredump}" 2>&1 \
- | sed -e 's/\&/\&/g;s/</\</g;s/>/\>/g;s/\"/\"/g' -e "s/'/\&\#039;/g"
-
- printf "</pre></body></html>\n"
- ) > "/var/www/svn_${rev}.${coredump}.trace.html"
-
- # Make sure the web server can read it
- chmod 644 "${coredump}"
- fi
-done
-
+++ /dev/null
-#! /bin/bash
-#
-# Copyright (C) 2010 Igalia S.L. All rights reserved.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Library General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Library General Public License for more details.
-#
-# You should have received a copy of the GNU Library General Public License
-# along with this library; see the file COPYING.LIB. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-# Boston, MA 02110-1301, USA.
-
-: ${BUILDBOT_CONFIG:=/etc/daemontools-buildbot.conf}
-
-# Read configuration file
-[ -r "${BUILDBOT_CONFIG}" ] && . "${BUILDBOT_CONFIG}"
-
-: ${buildbot_user:=${HOME}}
-: ${crashmon_log_path:=/var/log/crashmon}
-
-# Expand all "env_*" environment variables
-for varname in ${!env_*} ; do
- eval "export ${varname#env_}=\${${varname}}"
-done
-
-mkdir -p "${crashmon_log_path}"
-chown "${buildbot_user}" "${crashmon_log_path}"
-
-exec /usr/bin/setuidgid "${buildbot_user}" \
- /usr/bin/multilog t "${crashmon_log_path}"
-
+++ /dev/null
-#! /bin/bash
-#
-# Copyright (C) 2010 Igalia S.L. All rights reserved.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Library General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Library General Public License for more details.
-#
-# You should have received a copy of the GNU Library General Public License
-# along with this library; see the file COPYING.LIB. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-# Boston, MA 02110-1301, USA.
-
-exec 2>&1
-
-: ${BUILDBOT_CONFIG:=/etc/daemontools-buildbot.conf}
-
-# Read configuration file
-[ -r "${BUILDBOT_CONFIG}" ] && . "${BUILDBOT_CONFIG}"
-
-: ${buildbot_user:=${USER:-${LOGNAME}}}
-: ${crashmon_output:=''}
-
-# Expand all "env_*" environment variables
-for varname in ${!env_*} ; do
- eval "export ${varname#env_}=\${${varname}}"
-done
-
-
-if [ ! -d "${crashmon_output}" ]
-then
- if ! [ "${crashmon_output}" ]
- then
- echo "Dump directory '${crashmon_output}' does not exist (sleeping)"
- fi
- sleep $(( 60 * 60 * 4 ))
- exit 111
-fi
-
-
-if ! [ "${buildbot_bits}" ]
-then
- # Guess bits (32/64) from uname -m
- machine=$(uname -m)
- case ${machine} in
- x86_64 | amd64 | ia64 | ppc64)
- buildbot_bits="64" ;;
- *)
- buildbot_bits="32" ;;
- esac
-fi
-
-: ${crashmon_bin_path:="${buildbot_path}/gtk-linux-${buildbot_bits}-debug/build/WebKitBuild/Debug/Programs"}
-
-
-cd "${crashmon_output}"
-exec /usr/bin/env - \
- PATH="${PATH}" \
- SHELL="/bin/bash" \
- USER="${buildbot_user}" \
- arch="${buildbot_bits}" \
- LOGNAME="${buildbot_user}" \
- coredir="${crashmon_output}" \
- HOME="/home/${buildbot_user}" \
- mailto="${crashmon_mailto:-''}" \
- programpath="${crashmon_bin_path}" \
- /usr/bin/setuidgid "${buildbot_user}" "$(pwd)/crashmon"
-
buildbot_log_path="/var/log/buildbot"
-# Display number under which Xvfb will run
-#
-xvfb_display=":10"
-
-# Graphical mode which Xvfb will report to applications
-#
-xvfb_mode="1024x768x24"
-
-# Path to a directory where to log Xvfb error output
-#
-xvfb_log_path="/var/log/xvfb"
-
-
-# Output directory for core dumps. Set this to an empty string to
-# disable recording them.
-#
-crashmon_output="/var/www/webkitgtk-coredumps"
-
-# Maximum size of core dumps. With the default "unlimited" setting
-# it is recommended to have ~20GB for cores in 64-bit machines.
-# For 32-bit bots, less space is needed.
-#
-crashmon_max_size="unlimited"
-
-# Path to a directory where to log crashmon output
-#
-crashmon_log_path="/var/log/crashmon"
-
-# A list of e-mail addresses where to send notifications of core dumps.
-# Leave empty to disable mail notifications.
-#
-# WARNING: E-mail addresses will be flooded with messages!
-#
-crashmon_mailto=""
-
-# Base directory where to find sources and built binaries of which
-# crash dumps are to be catched. Usually you will not need to change this.
-#
-crashmon_src_path="${buildbot_path}/gtk-linux-${buildbot_bits}-debug/build"
-crashmon_bin_path="${crashmon_src_path}/WebKitBuild/Debug/Programs"
-
-
# If you want to use ccache, set a path to where synlinks with tool
# names pointing to ccache are installed. In Debian systems this
# would be /usr/lib/ccache. Set to empty to disable.
#
env_CFLAGS="-pipe"
env_CXXFLAGS="-pipe"
-env_WebKitMakeArguments="-j3"
env_WEBKIT_TESTFONTS="/home/${buildbot_user}/testfonts"
+++ /dev/null
-#! /bin/bash
-#
-# Copyright (C) 2010 Igalia S.L. All rights reserved.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Library General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Library General Public License for more details.
-#
-# You should have received a copy of the GNU Library General Public License
-# along with this library; see the file COPYING.LIB. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-# Boston, MA 02110-1301, USA.
-
-: ${BUILDBOT_CONFIG:=/etc/daemontools-buildbot.conf}
-
-# Read configuration file
-[ -r "${BUILDBOT_CONFIG}" ] && . "${BUILDBOT_CONFIG}"
-
-: ${buildbot_user:=${HOME}}
-: ${xvfb_log_path:=/var/log/xvfb}
-
-# Expand all "env_*" environment variables
-for varname in ${!env_*} ; do
- eval "export ${varname#env_}=\${${varname}}"
-done
-
-mkdir -p "${xvfb_log_path}"
-chown "${buildbot_user}" "${xvfb_log_path}"
-
-exec /usr/bin/setuidgid "${buildbot_user}" \
- /usr/bin/multilog t "${xvfb_log_path}"
+++ /dev/null
-#! /bin/bash
-#
-# Copyright (C) 2010 Igalia S.L. All rights reserved.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Library General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Library General Public License for more details.
-#
-# You should have received a copy of the GNU Library General Public License
-# along with this library; see the file COPYING.LIB. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-# Boston, MA 02110-1301, USA.
-
-exec 2>&1
-
-: ${BUILDBOT_CONFIG:=/etc/daemontools-buildbot.conf}
-
-# Read configuration file
-[ -r "${BUILDBOT_CONFIG}" ] && . "${BUILDBOT_CONFIG}"
-
-: ${xvfb_display:=':10'}
-: ${xvfb_mode:='1024x768x24'}
-
-# Expand all "env_*" environment variables
-for varname in ${!env_*} ; do
- eval "export ${varname#env_}=\${${varname}}"
-done
-
-mkdir -p "xvfb${xvfb_display}"
-exec /usr/bin/Xvfb "${xvfb_display}" \
- -fbdir "xvfb${xvfb_display}" \
- -screen 0 "${xvfb_mode}" \
- -nolisten inet6 \
- -nolisten inet
-
+2012-04-03 Philippe Normand <pnormand@igalia.com>
+
+ [GTK] crash log reports support
+ https://bugs.webkit.org/show_bug.cgi?id=81659
+
+ Reviewed by Martin Robinson.
+
+ Removed the daemontools crashmon/xvfb scripts and implemented the crash
+ log reporting in the NRWT Gtk port. To get proper crash logs one
+ needs to set the core pattern like this:
+ echo "/path/to/cores/core-pid_%p-_-process_%e" > /proc/sys/kernel/core_pattern
+ Then enable coredumps with "ulimit -c unlimited" and set the WEBKIT_CORE_DUMPS_DIRECTORY
+ environment variable.
+
+ * BuildSlaveSupport/gtk/README:
+ * BuildSlaveSupport/gtk/crashmon/crashmon: Removed.
+ * BuildSlaveSupport/gtk/crashmon/log/run: Removed.
+ * BuildSlaveSupport/gtk/crashmon/run: Removed.
+ * BuildSlaveSupport/gtk/daemontools-buildbot.conf:
+ * BuildSlaveSupport/gtk/xvfb/log/run: Removed.
+ * BuildSlaveSupport/gtk/xvfb/run: Removed.
+ * Scripts/new-run-webkit-tests:
+ * Scripts/webkitpy/layout_tests/port/gtk.py:
+ (GtkDriver.stop):
+ (GtkPort.show_results_html_file):
+ (GtkPort):
+ (GtkPort._get_gdb_output):
+ (GtkPort._get_crash_log):
+ (GtkPort._get_crash_log.match_filename):
+ * Scripts/webkitpy/layout_tests/port/gtk_unittest.py:
+ (GtkPortTest):
+ (test_show_results_html_file):
+ (assertLinesEqual):
+ (_mock_gdb_output):
+ (test_get_crash_log):
+
2012-04-02 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
Enable and connect the WebInspectorServer with WebKit2 pages.
env['PYTHONPATH'] = script_dir
module_path = os.path.join(script_dir, 'webkitpy', 'layout_tests', 'run_webkit_tests.py')
cmd = [sys.executable, module_path] + sys.argv[1:]
+
+ # Wrap the NRWT process in the jhbuild environment so DRT or WKTR
+ # doesn't need to do it and their process id as reported by
+ # subprocess.Popen is not jhbuild's.
+ if '--gtk' in sys.argv[1:]:
+ cmd.insert(1, os.path.join(script_dir, '..', 'gtk', 'run-with-jhbuild'))
+
proc = subprocess.Popen(cmd, env=env)
try:
proc.wait()
self._xvfb_process.wait()
self._xvfb_process = None
- def cmd_line(self, pixel_tests, per_test_args):
- wrapper_path = self._port.path_from_webkit_base("Tools", "gtk", "run-with-jhbuild")
- return [wrapper_path] + WebKitDriver.cmd_line(self, pixel_tests, per_test_args)
-
class GtkPort(WebKitPort):
port_name = "gtk"
# FIXME: old-run-webkit-tests also added ["-graphicssystem", "raster", "-style", "windows"]
# FIXME: old-run-webkit-tests converted results_filename path for cygwin.
self._run_script("run-launcher", run_launcher_args)
+
+ def _get_gdb_output(self, coredump_path):
+ cmd = ['gdb', '-ex', 'thread apply all bt', '--batch', str(self._path_to_driver()), coredump_path]
+ proc = subprocess.Popen(cmd, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ proc.wait()
+ errors = [l.strip() for l in proc.stderr.readlines()]
+ return (proc.stdout.read(), errors)
+
+ def _get_crash_log(self, name, pid, stdout, stderr):
+ pid_representation = str(pid or '<unknown>')
+ log_directory = os.environ.get("WEBKIT_CORE_DUMPS_DIRECTORY")
+ errors = []
+ crash_log = ''
+ expected_crash_dump_filename = "core-pid_%s-_-process_%s" % (pid_representation, name)
+
+ def match_filename(filesystem, directory, filename):
+ if pid:
+ return filename == expected_crash_dump_filename
+ return filename.find(name) > -1
+
+ if log_directory:
+ dumps = self._filesystem.files_under(log_directory, file_filter=match_filename)
+ if dumps:
+ # Get the most recent coredump matching the pid and/or process name.
+ coredump_path = list(reversed(sorted(dumps)))[0]
+ crash_log, errors = self._get_gdb_output(coredump_path)
+
+ stderr_lines = errors + (stderr or '<empty>').decode('utf8', errors='ignore').splitlines()
+ errors_str = '\n'.join(('STDERR: ' + l) for l in stderr_lines)
+ if not crash_log:
+ if not log_directory:
+ log_directory = "/path/to/coredumps"
+ core_pattern = os.path.join(log_directory, "core-pid_%p-_-process_%e")
+ crash_log = """\
+Coredump %(expected_crash_dump_filename)s not found. To enable crash logs:
+
+- run this command as super-user: echo "%(core_pattern)s" > /proc/sys/kernel/core_pattern
+- enable core dumps: ulimit -c unlimited
+- set the WEBKIT_CORE_DUMPS_DIRECTORY environment variable: export WEBKIT_CORE_DUMPS_DIRECTORY=%(log_directory)s
+
+""" % locals()
+
+ return """\
+Crash log for %(name)s (pid %(pid_representation)s):
+
+%(crash_log)s
+%(errors_str)s""" % locals()
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import unittest
+import sys
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.layout_tests.port.gtk import GtkPort
from webkitpy.layout_tests.port import port_testcase
from webkitpy.common.system.executive_mock import MockExecutive
-
+from webkitpy.thirdparty.mock import Mock
+from webkitpy.common.system.filesystem_mock import MockFileSystem
+from webkitpy.tool.mocktool import MockOptions
class GtkPortTest(port_testcase.PortTestCase):
port_name = 'gtk'
port_maker = GtkPort
+ _mock_crash_log = """\
+Crash log for DumpRenderTree (pid 28529):
+
+Coredump core-pid_28529-_-process_DumpRenderTree not found. To enable crash logs:
+
+- run this command as super-user: echo "/path/to/coredumps/core-pid_%p-_-process_%e" > /proc/sys/kernel/core_pattern
+- enable core dumps: ulimit -c unlimited
+- set the WEBKIT_CORE_DUMPS_DIRECTORY environment variable: export WEBKIT_CORE_DUMPS_DIRECTORY=/path/to/coredumps
+
+
+STDERR: <empty>"""
def test_show_results_html_file(self):
port = self.make_port()
port._executive = MockExecutive(should_log=True)
expected_stderr = "MOCK run_command: ['Tools/Scripts/run-launcher', '--release', '--gtk', 'file://test.html'], cwd=/mock-checkout\n"
OutputCapture().assert_outputs(self, port.show_results_html_file, ["test.html"], expected_stderr=expected_stderr)
+
+ def assertLinesEqual(self, a, b):
+ if hasattr(self, 'assertMultiLineEqual'):
+ self.assertMultiLineEqual(a, b)
+ else:
+ self.assertEqual(a.splitlines(), b.splitlines())
+
+ def _mock_gdb_output(self, coredump_path):
+ return (self._mock_crash_log, [])
+
+ def test_get_crash_log(self):
+ port = self.make_port()
+ port._get_gdb_output = self._mock_gdb_output
+ log = port._get_crash_log("DumpRenderTree", 28529, "", "")
+ self.assertLinesEqual(log, self._mock_crash_log)