blob: e527015f738d1bf3045ee387aa2a8c694f9998aa [file] [log] [blame]
#!/bin/bash
# Copyright 2019 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 fidlcat on given target.
## Runs fidlcat in the given configuration; currently, fidlcat logs all FIDL
## chatter from the given target executable. Starts the debug agent on the
## proposed target, and closes the debug agent on exit.
##
## CAUTION: This support is experimental, and invocation strategy is likely to
## change. The component launching configuration is *especially* likely to go
## away over time.
##
## 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 --debug-mode flag to see
## the debug log's from the debug agent and fidlcat.
## - This scripts uses the tool "nc" for testing TCP connections. Check that it
## is in $PATH and that it works.
##
## Usage: fx fidlcat [--debug-mode] [(--port|-p) <PORT>] [--with-symbol-server]
## [--with-process-info] [--stack=<value>]
## [--syscalls=<regexp>] [--exclude-syscalls=<regexp>] [--dump-messages]
## [--verbose=<value> | --quiet=<value>] [--log-file <path>]
## [--remote-pid=<pid> | --remote-name=<name> | run <component specification>]
##
## --port Port the debug agent will be listening on. Will use 2345
## by default.
## --with-symbol-server Connect to the symbol server. The first time you use this option,
## fidlcat will give you a link to an authentication page.
## You then have to use the generated key to authenticate.
## --debug-mode Whether the debug agent's debug logs should be shown.
## --with-process-info Display the process name, process id and thread id on
## each line (useful for grep).
## --stack=<value> Define the amount of stack frame to display
## 0: none (default value)
## 1: call site (1 to 4 levels)
## 2: full stack frame (adds some overhead)
## --syscalls A regular expression which selects the syscalls to decode and display.
## Can be passed multiple times.
## By default, only zx_channel_.* syscalls are displayed.
## To display all the syscalls, use: --syscalls ".*"
## --exclude-syscalls A regular expression which selects the syscalls to not decode and
## display.
## Can be passed multiple times.
## To be displayed, a syscall must verify --syscalls and not verify
## --exclude-syscalls.
## To display all the syscalls but the zx_handle syscalls, use:
## --syscalls ".*" --exclude-syscalls "zx_handle_.*"
## --dump-messages Always does a hexadecimal dump of the messages even if we can
## decode them.
## --verbose=<value> The log verbosity. Legal values are "info", "warning",
## "error", "fatal", or a number, starting from 0. Extra
## verbosity comes with higher levels.
## --quiet=<value> The log verbosity. Legal values are "info", "warning",
## "error", "fatal", or a number, starting from 0. Extra
## verbosity comes with lower levels.
## --log-file=<path> The log file destination.
## --remote-pid The koid of the remote process to trace
## --remote-name A set of comma-separated regexes. Fidlcat will monitor all existing
## and future processes whose names match one of the regexes.
## Can be provided multiple times for multiple regexes.
## --symbol-path=<path> An extra location where fildcat can find debug symbols.
## --fidl-ir-path=<path> An extra location where fidlcat can find FIDL compiled files.
## --gdb Launch fidlcat using gdb. This is only useful to be able to debug
## fidlcat. When this option is used, the string you have to type within
## gdb to launch fidlcat is printed and then, gdb is launched.
## This option only works if you have the unstripped version of fidlcat.
## run A token indicating that you want to invoke and trace
## the following component. The component is specified
## with either a bash regex that matches a component URL
## known to the build, or a full component URL not known
## to your build, but available to your target.
##
## Flags after -- are parsed by fidlcat. Example usage:
##
## # Attaches to the process with the given pid on the target:
## fx fidlcat --remote-pid=4755
##
## # Launches the echo client, and monitors its FIDL chatter:
## fx fidlcat run fuchsia-pkg://fuchsia.com/echo_client_cpp#meta/echo_client_cpp.cmx
##
## # Also launches the echo client, and monitors its FIDL chatter:
## fx fidlcat run echo_client_cpp.cmx
##
## # Will trace existing and future processes whose name contains "echo_client"
## fx fidlcat --remote-name=echo_client
##
## All three options --remote-pid, --remote-name and run can be used together.
## However, run must always be the last one.
## When --remote-name and run are used together, only processes which match
## --remote-name are monitored.
##
## Examples (echo_server is launched by echo_client):
##
## # run and monitor echo_client.
## fx fidlcat run echo_client_cpp.cmx
##
## # run and monitor echo_client.
## fx fidlcat --remote-name=echo_client run echo_client_cpp.cmx
##
## # run echo_client and monitor echo_server.
## fx fidlcat --remote-name=echo_server run echo_client_cpp.cmx
##
## # run echo_client and monitor echo_client and echo_server.
## fx fidlcat --remote-name=echo run echo_client_cpp.cmx
##
## # run echo_client and monitor echo_client and echo_server.
## fx fidlcat --remote-name=echo_client --remote-name=echo_server run echo_client_cpp.cmx
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)"/../contrib/lib/debug-agent.sh || exit $?
action=
arguments=()
use_gdb=0
# Options for the zxdb client.
agent_out="/dev/null"
debug_mode=
while [[ $# -gt 0 ]]; do
case "$1" in
--help|-h)
fx-command-help
exit 0
;;
--port|-p)
shift
port="$1"
;;
--with-symbol-server)
arguments+=("--symbol-server")
arguments+=("gs://fuchsia-artifacts-release/debug")
;;
--debug-mode)
agent_out="/dev/stdout"
debug_mode="--debug-mode"
;;
--with-process-info)
arguments+=("--with-process-info")
;;
--dump-messages)
arguments+=("--dump-messages")
;;
--stack=*)
arguments+=("$1")
;;
--syscalls=*)
arguments+=("$1")
;;
--exclude-syscalls=*)
arguments+=("$1")
;;
--verbose=*)
arguments+=("$1")
;;
--quiet=*)
arguments+=("$1")
;;
--log-file=*)
arguments+=("$1")
;;
--remote-pid=*)
arguments+=("$1")
;;
--remote-name=*)
arguments+=("$1")
;;
--symbol-path=*)
arguments+=("$1")
;;
--fidl-ir-path=*)
arguments+=("$1")
;;
--gdb)
use_gdb=1
;;
run)
action="$1"
shift
break # Remaining flags are passed to fidlcat, with processing below
;;
--)
shift
break # Remaining flags are passed to fidlcat
;;
*)
echo "Invalid flag $1"
exit 1
esac
shift
done
# Infer the package URL from a regex-specified name.
package_file="${FUCHSIA_BUILD_DIR}/component_index_metadata"
if [[ "${action}" == "run" ]]; then
component=$1
components=()
all_pkgs="$(cat "${package_file}")"
if [[ -n "${all_pkgs}" ]]; then
for pkg in ${all_pkgs}; do
if [[ "${pkg}" =~ ${component} ]]; then
components+=("${pkg}")
fi
done
else
# If there aren't any packages in the component_index_metadata file, then
# assume the users know what they are doing. fidlcat should complain.
components+=("${component}")
fi
if [[ ${#components[@]} = 0 ]]; then
fx-error "Package $component is not known to the current build configuration."
fx-error "Check \`fx list-packages\` for the correct name,"
fx-error "or adjust the build configuration with \`fx set\`."
exit 1
elif [[ ${#components[@]} -gt 1 ]]; then
fx-error "Ambiguous match: $component matches the following ${#components[@]} packages:"
for component in "${components[@]}"; do
fx-error " $component"
done
exit 1
fi
component="${components[0]}"
shift
# We have now removed "run <partial component URL regex>" from the remaining
# positional parameters. The following set command replaces them with "run
# <full component URL>".
set - "$@" "run" "${component}"
fi
if [[ -z "${port}" ]]; then
port=2345
fi
if launch_debug_agent "${port}" "" "${agent_out}"; then
arguments+=("--connect" "$(get-device-addr-resource):${port}")
arguments+=("--fidl-ir-path" @"${FUCHSIA_BUILD_DIR}"/all_fidl_json.txt)
arguments+=("-s" "${FUCHSIA_BUILD_DIR}")
arguments+=("-s" "${ZIRCON_BUILDROOT}")
arguments+=("-s" "${PREBUILT_CLANG_DIR}/lib/debug")
arguments+=("--symbol-cache" "~")
arguments+=("--pretty-print")
arguments+=("$@")
if [[ ${use_gdb} -eq 1 ]]; then
# Starts gdb.
gdb --args ${FUCHSIA_BUILD_DIR}/host_x64/exe.unstripped/fidlcat ${arguments[@]}
else
# Now that the debug agent is launched, starts fidlcat.
"${FUCHSIA_BUILD_DIR}/host-tools/fidlcat" ${arguments[@]}
fi
# launch_debug_agent starts an agent in the background. Note: killing
# the ssh session as below generally won't terminate the agent, but
# it prevents us ending up with a zobmie on the host.
pids=$(jobs -p)
if [[ -n "${pids}" ]]; then
kill "${pids}" > /dev/null >&2
wait
fi
else
fx-error "Could not launch debug agent. Exiting. Make sure you're running 'fx serve'."
exit 1
fi