| #!/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 |