blob: dd4402d248ae37831a498c0d7b635df96b0e5da8 [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.
### 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-process-info] [--stack=<value>]
## [--syscalls=<regexp>] [--exclude-syscalls=<regexp>]
## [--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.
## --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_.*"
## --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.
## 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 $?
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/../contrib/lib/debug.sh || exit $?
agent_out="/dev/null"
action=
debug_mode=
with_process_info=
stack=
syscalls=()
verbose=
quiet=
log_file=
remote_pids=()
remote_names=()
while [[ $# -gt 0 ]]; do
case "$1" in
--help|-h)
fx-command-help
exit 0
;;
--port|-p)
shift
port="$1"
;;
--debug-mode)
agent_out="/dev/stdout"
debug_mode="--debug-mode"
;;
--with-process-info)
with_process_info="--with-process-info"
;;
--stack=*)
stack="$1"
;;
--syscalls=*)
syscalls+="$1 "
;;
--exclude-syscalls=*)
syscalls+="$1 "
;;
--verbose=*)
verbose="$1"
;;
--quiet=*)
quiet="$1"
;;
--log-file=*)
log_file="$1"
;;
--remote-pid=*)
remote_pids+="$1 "
;;
--remote-name=*)
remote_names+="$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
target=$(get-fuchsia-device-addr)
# 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; then
# We start the client with the flag that tells it to quit the agent when zxdb quits.
"${FUCHSIA_BUILD_DIR}/host-tools/fidlcat" \
"--connect" "[${target}]:${port}" \
"--fidl-ir-path" @"${FUCHSIA_BUILD_DIR}"/all_fidl_json.txt \
"-s" "${FUCHSIA_BUILD_DIR}" \
"-s" "${ZIRCON_BUILDROOT}" \
"-s" "${PREBUILT_CLANG_DIR}/lib/debug" \
--pretty-print \
${with_process_info} \
${stack} \
${syscalls} \
${verbose} \
${quiet} \
${log_file} \
${remote_pids} \
${remote_names} \
$@
else
fx-error "Could not launch debug agent. Exiting."
exit 1
fi