blob: 3efe679f8c7436bff56d53d2c31c19d044924ad9 [file] [log] [blame]
#!/bin/bash
# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#### CATEGORY=Run, inspect and debug
### run the debug agent on target and connect to it with zxdb
## Starts the debug agent on the proposed target and automatically connect zxdb
## to it. Will close the debug agent on exit.
##
## TROUBLESHOOTING TIPS:
##
## - Remember to use "fx set-device" when working with multiple devices.
## - This scripts by default will mute the SSH connection stdout/stderr, so any
## errors triggered by it won't appear. Use the --verbose-agent flag to see
## the output.
## - This scripts uses the tool "nc" for testing TCP connections. Check that it
## is in $PATH and that it works.
##
## Usage: fx debug [(--core|-c) <CORE>] [--no-agent] [(--port|-p) <PORT>]
## [--unwind=(aosp|ng|fuchsia)] [(--verbose-agent|-va)]
##
## --core Load a minidump file into zxdb.
## --no-agent Don't start a Debug Agent.
## --port Port the debug agent will be listening on.
## Will use 2345 by default.
## --target-core Look on the target for a minidump file taken by
## crashpad, download it and load it into zxdb.
## --unwind Choose the unwinder to use. Options are
## - "aosp" (Android's unwinder)
## - "ng" for "ngunwind" (Fuchsia's fork of libunwind)
## - "fuchsia" (an experimental homemade unwinder)
## Defaults to "aosp".
## --verbose-agent Whether the debug agent's stdout/stderr should be shown.
## Useful for debugging the debugger. Yo' dawg.
##
## Flags after -- are parsed by zxdb. See zxdb's documentation for more
## details.
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/../lib/vars.sh || exit $?
fx-config-read
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/debug-agent.sh || exit $?
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/symbol-index.sh || exit $?
# Defaults.
port=
core=
unwind_flag=
agent_out="/dev/null"
no_agent=
target_core=
# Flag parsing.
while [[ $# -gt 0 ]]; do
case "$1" in
--help|-h)
fx-command-help
exit 0
;;
--no-agent)
no_agent=true
;;
--port|-p)
shift
port="$1"
;;
--port=*)
port="${1:7}"
;;
--verbose-agent|-va)
agent_out="/dev/stdout"
;;
--core|-c)
arg=$1
shift
core="$1"
if [[ -z "${core}" ]]; then
echo "${arg} takes an argument"
exit 1
fi
no_agent=true
;;
--core=*)
core="${1:7}"
no_agent=true
;;
--target-core)
target_core=true
no_agent=true
;;
--unwind)
shift
unwind_flag="--unwind=$1"
;;
--unwind=*)
unwind_flag="--unwind=${1:9}"
;;
--)
shift
break # Remaining flags are passed to zxdb
;;
*)
echo "Invalid flag $1"
exit 1
esac
shift
done
if [[ -n "${port}" && -n "${core}" ]]; then
echo "Specifying both a port and a core doesn't make sense"
exit 1
fi
if [[ -n "${target_core}" && -n "${core}" ]]; then
echo "Cannot specify a core file when fetching a core from the target"
exit 1;
fi
if [[ -n "${port}" && -n "${target_core}" ]]; then
echo "Cannot specify a port file when fetching a core from the target"
exit 1
fi
if [[ -z "${port}" ]]; then
port=2345
fi
if [[ -n "${target_core}" ]]; then
id='fd81549e77f2f3b199d4dca16131c3525428140828f0843a0fd30e7c0d2e2631'
cache_coredumps=(`fx-command-run shell "find /data/cache/${id}/reports -name minidump.dmp -type f"`)
tmp_coredumps=(`fx-command-run shell "find /tmp/${id}/reports -name minidump.dmp -type f"`)
all_coredumps=(${cache_coredumps[@]} ${tmp_coredumps[@]})
num_coredumps=${#all_coredumps[@]}
if [[ ${num_coredumps} -eq 0 ]]; then
fx-error "No core dumps available on device"
exit 1
elif [[ ${num_coredumps} -ge 2 ]]; then
echo "Which core dump would you like to analyze?"
select choice in ${all_coredumps[@]}; do
coredump=${choice}
break
done
else
coredump=${all_coredumps[0]}
fi
core="/tmp/zxdb_fetched_core.dmp"
if ! fx-command-run cp --to-host ${coredump} ${core}; then
fx-error "Failed to copy core dump over to host"
exit 1
fi
fi
if [[ -n "${core}" && ! -f "${core}" ]]; then
echo "Cannot find file ${core}"
exit 1
fi
connect_ops=()
if [[ ! -z "${core}" ]]; then
connect_ops=("--core" "${core}")
elif [[ ! -z "${no_agent}" ]]; then
echo "Not starting a debug agent."
else
if launch_debug_agent "${port}" "${unwind_flag}" "${agent_out}"; then
connect_ops=("--connect" "$(get-device-addr-resource):${port}" "--quit-agent-on-exit")
else
fx-error "Could not launch debug agent. Exiting. Make sure you're running 'fx serve'."
exit 1
fi
fi
ensure-symbol-index-registered || fx-warn "Failed to register ${FUCHSIA_DIR} in symbol-index!"
"${FUCHSIA_BUILD_DIR}/host-tools/zxdb" \
${connect_ops[@]} \
"--symbol-server" "gs://fuchsia-artifacts-release/debug" \
"$@"
# launch_debug_agent starts the agent in a subprocess, which zxdb will
# terminate by --quit-agent-on-exit, we want to wait that process however.
wait