| #!/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. | |
| ## --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 $? | |
| source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/../contrib/lib/debug.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-infra-debug-symbols") | |
| ;; | |
| --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") | |
| ;; | |
| --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 | |
| 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 | |
| arguments+=("--connect" "[${target}]:${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 | |
| else | |
| fx-error "Could not launch debug agent. Exiting. Make sure you're running 'fx serve'." | |
| exit 1 | |
| fi |