blob: 49240528793b91fa0f1ec6931044578209cae74f [file] [log] [blame] [edit]
#!/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)] [--gdb]
##
## --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.
## --gdb Launch zxdb using gdb. This is only useful to be able to debug zxdb. This
## option only works if you have the unstripped version of zxdb.
##
## 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=
use_gdb=0
# 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"
;;
--gdb)
use_gdb=1
;;
--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
arguments=("--symbol-server" "gs://fuchsia-artifacts-release/debug")
if [[ -n "${core}" ]]; then
arguments+=("--core" "${core}")
elif [[ -n "${no_agent}" ]]; then
echo "Not starting a debug agent."
else
if launch_debug_agent "${port}" "${unwind_flag}" "${agent_out}"; then
arguments+=("--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!"
ZXDB=$(fx-command-run host-tool --print zxdb)
ZXDB_UNSTRIPPED="$(dirname "$ZXDB")/exe.unstripped/$(basename "$ZXDB")"
arguments+=("$@")
if [[ ${use_gdb} -eq 1 ]]; then
# Starts gdb.
gdb --args "$ZXDB_UNSTRIPPED" "${arguments[@]}"
else
# Now that the debug agent is launched, start zxdb.
"$ZXDB" "${arguments[@]}"
fi
# 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