
Add support for interactively debugging WPTs with upstream's `wpt run`. `run_wpt_tests.py --verbose` ensures browser logs are dumped to stdout so that `debug_renderer` can find the PID to attach to. Bug: 1440021 Test: ./debug_renderer ./run_wpt_tests.py -t Default Test: external/wpt/badging/badge-success.https.html Change-Id: I58323aea67f6232bc28b198b8f18d3d7bb7d8a7b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4893148 Reviewed-by: Weizhong Xia <weizhong@google.com> Commit-Queue: Jonathan Lee <jonathanjlee@google.com> Reviewed-by: Robert Flack <flackr@chromium.org> Cr-Commit-Position: refs/heads/main@{#1201810}
142 lines
3.9 KiB
Bash
Executable File
142 lines
3.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# Copyright 2015 The Chromium Authors
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
# Runs Chrome / content_shell and attaches to the renderer process for the
|
|
# target URL (or the first navigation if none is specified).
|
|
|
|
usage() {
|
|
echo "usage: $(basename $0) [-d <debug-url>] <path-to-content-shell> <url> [more-args...]"
|
|
exit 1
|
|
}
|
|
|
|
DEFAULT_TARGET_FLAGS=(--no-sandbox --disable-hang-monitor --wait-for-debugger-on-navigation)
|
|
|
|
while getopts "h?d:" OPTION
|
|
do
|
|
case $OPTION in
|
|
h|\?)
|
|
usage
|
|
;;
|
|
d)
|
|
DEBUG_URL=$OPTARG
|
|
;;
|
|
esac
|
|
done
|
|
|
|
shift $[$OPTIND-1]
|
|
|
|
TARGET=$1
|
|
shift
|
|
|
|
if [ -z "$TARGET" ]; then
|
|
usage
|
|
fi
|
|
|
|
if [[ "$TARGET" =~ run_web_tests.py$ ]]; then
|
|
# Adjust flags to be passed to driver
|
|
WEB_TESTS_FLAGS=(--jobs=1 --timeout-ms=100000000 --driver-logging)
|
|
for DEFAULT_FLAG in "${DEFAULT_TARGET_FLAGS[@]}"; do
|
|
WEB_TESTS_FLAGS=(${WEB_TESTS_FLAGS[@]} --additional-driver-flag="$DEFAULT_FLAG")
|
|
done
|
|
TARGET_FLAGS=(${WEB_TESTS_FLAGS[@]} "$@")
|
|
elif [[ "$TARGET" =~ run_wpt_tests.py$ ]]; then
|
|
WPT_TESTS_FLAGS=(--jobs=1 --timeout-multiplier=10000 --verbose)
|
|
for DEFAULT_FLAG in "${DEFAULT_TARGET_FLAGS[@]}"; do
|
|
WPT_TESTS_FLAGS=(${WPT_TESTS_FLAGS[@]} --additional-driver-flag="$DEFAULT_FLAG")
|
|
done
|
|
TARGET_FLAGS=(${WPT_TESTS_FLAGS[@]} "$@")
|
|
else
|
|
TARGET_FLAGS=(${DEFAULT_TARGET_FLAGS[@]} "$@")
|
|
fi
|
|
|
|
if [ -z "$DEBUG_URL" ]; then
|
|
echo "Debugging first renderer"
|
|
fi
|
|
|
|
# TODO: If you pass a URL containing characters that require URL encoding,
|
|
# the URL will be encoded by chrome and won't be equivalent to the $DEBUG_URL.
|
|
# We should url encode DEBUG_URL so that it matches the url chrome navigates to.
|
|
RENDERER_PID_RE='Renderer url="([^"]+)" \(([0-9]+)\) paused waiting for debugger'
|
|
|
|
if [ -z "$DEBUGGER" ]; then
|
|
if which lldb > /dev/null; then
|
|
DEBUGGER="lldb"
|
|
CONTINUE="continue"
|
|
elif which gdb > /dev/null; then
|
|
DEBUGGER="gdb -q"
|
|
CONTINUE="signal SIGUSR1"
|
|
else
|
|
echo "no debugger found"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
OUTPUT=$(mktemp "${TMPDIR:-/tmp}"/"$(basename $0)".XXXXX)
|
|
|
|
UNBUFFER=""
|
|
# Use unbuffer to ensure we get the output while the subprocess is paused
|
|
# waiting for a renderer.
|
|
if [ -z `which unbuffer` ]; then
|
|
echo "Warning: Couldn't find unbuffer. Buffered output can result in" \
|
|
"failure to read the PID of the paused renderer from the pipe. If" \
|
|
"you encounter a hang install unbuffer tool from your package manager."
|
|
else
|
|
UNBUFFER="unbuffer "
|
|
fi
|
|
|
|
maybe_kill() {
|
|
[ -n "$1" ] && ps -p $1 > /dev/null && kill $1
|
|
}
|
|
|
|
cleanup() {
|
|
rm $OUTPUT
|
|
maybe_kill "$BROWSER_PID"
|
|
maybe_kill "$SIGNAL_PID"
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
echo "Running ${UNBUFFER}${TARGET} ${TARGET_FLAGS[@]}" >&2
|
|
${UNBUFFER}"${TARGET}" "${TARGET_FLAGS[@]}" > >(tee $OUTPUT) 2>&1 &
|
|
BROWSER_PID=$!
|
|
echo "Process $BROWSER_PID logging to $OUTPUT"
|
|
|
|
wait_renderer_pid() {
|
|
NEXT_LINE=1
|
|
tail +1f $OUTPUT | while read LINE; do
|
|
NEXT_LINE=$[$NEXT_LINE + 1]
|
|
if [[ "$LINE" =~ $RENDERER_PID_RE ]]; then
|
|
RENDERER_URL=${BASH_REMATCH[1]}
|
|
RENDERER_PID=${BASH_REMATCH[2]}
|
|
if [ -z "$DEBUG_URL" ] || [[ "$RENDERER_URL" == "$DEBUG_URL" ]]; then
|
|
echo "$NEXT_LINE $RENDERER_PID"
|
|
return
|
|
fi
|
|
# Unblock unrelated renderers.
|
|
kill -s SIGUSR1 "$RENDERER_PID"
|
|
fi
|
|
done
|
|
}
|
|
|
|
signal_renderers() {
|
|
STARTING_OUTPUT_LINE=$1
|
|
tail +${STARTING_OUTPUT_LINE}f $OUTPUT | while read LINE; do
|
|
if [[ "$LINE" =~ $RENDERER_PID_RE ]]; then
|
|
kill -s SIGUSR1 ${BASH_REMATCH[2]}
|
|
fi
|
|
done
|
|
}
|
|
|
|
RESULT=$(wait_renderer_pid)
|
|
NEXT_LINE=$(echo $RESULT|cut -d' ' -f 1)
|
|
RENDERER_PID=$(echo $RESULT|cut -d' ' -f 2)
|
|
if [ -n "$RENDERER_PID" ]; then
|
|
echo "Target renderer found. Sending SIGUSR1 to unblock any subsequent renderers."
|
|
signal_renderers ${NEXT_LINE} &
|
|
SIGNAL_PID=$!
|
|
# print yellow message
|
|
echo -e "\n\033[1;33mDebugging renderer, use '$CONTINUE' to run.\033[0m\n"
|
|
$DEBUGGER -p $RENDERER_PID
|
|
fi
|