You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
383 lines
9.1 KiB
383 lines
9.1 KiB
#!/bin/bash
|
|
# Copyright (C) 2018 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
set -e
|
|
SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
|
|
|
|
if [ "$TMPDIR" == "" ]; then
|
|
TMPDIR=/tmp
|
|
fi
|
|
|
|
function get_gn_value() {
|
|
local out=$1
|
|
local key=$2
|
|
"$SCRIPT_DIR/gn" args "$out" --list=$key --short | awk '{print $3}' \
|
|
| tr -d '"'
|
|
}
|
|
|
|
function is_monolithic() {
|
|
local out=$1
|
|
value=$(get_gn_value "$out" "monolithic_binaries")
|
|
test "$value" == "true"
|
|
}
|
|
|
|
function is_android() {
|
|
local out=$1
|
|
value=$(get_gn_value "$out" "target_os")
|
|
test "$value" == "android"
|
|
}
|
|
|
|
function is_ssh_target() {
|
|
[[ -n "$SSH_TARGET" ]]
|
|
}
|
|
|
|
function is_mac() {
|
|
# shellcheck disable=2251
|
|
! test -d /proc
|
|
return $?
|
|
}
|
|
|
|
function tmux_ensure_bash() {
|
|
if [[ $SHELL == *"fish" ]]; then
|
|
tmux send-keys "bash" Enter
|
|
fi
|
|
}
|
|
|
|
function reset_tracing() {
|
|
if is_android "$OUT"; then
|
|
adb shell 'echo 0 > /d/tracing/tracing_on'
|
|
elif ! is_mac; then
|
|
# shellcheck disable=SC2016
|
|
local script='
|
|
if [ ! -w /sys/kernel/debug ]; then
|
|
echo "debugfs not accessible, try sudo chown -R $USER /sys/kernel/debug"
|
|
sudo chown -R "$USER" /sys/kernel/debug
|
|
fi
|
|
|
|
echo 0 > /sys/kernel/debug/tracing/tracing_on
|
|
'
|
|
|
|
if is_ssh_target; then
|
|
# shellcheck disable=SC2029
|
|
ssh -t "$SSH_TARGET" "sh -c '$script'"
|
|
else
|
|
sh -c "$script"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function adb_supports_push_sync() {
|
|
adb --help 2>&1 | grep 'push.*\[--sync\]' >/dev/null 2>&1
|
|
}
|
|
|
|
function push() {
|
|
if is_android "$OUT"; then
|
|
local maybe_sync=''
|
|
if adb_supports_push_sync; then
|
|
maybe_sync='--sync'
|
|
fi
|
|
echo adb push $maybe_sync "$1" "$DIR"
|
|
adb push $maybe_sync "$1" "$DIR"
|
|
elif is_ssh_target; then
|
|
echo scp "$1" "$SSH_TARGET:$DIR"
|
|
scp "$1" "$SSH_TARGET:$DIR"
|
|
else
|
|
echo cp "$1" "$DIR"
|
|
cp "$1" "$DIR"
|
|
fi
|
|
}
|
|
|
|
function pull() {
|
|
if is_android "$OUT"; then
|
|
echo adb pull "$DIR/$1" "$2"
|
|
adb pull "$DIR/$1" "$2"
|
|
elif is_ssh_target; then
|
|
echo scp "$SSH_TARGET:$DIR/$1" "$2"
|
|
scp "$SSH_TARGET:$DIR/$1" "$2"
|
|
else
|
|
echo mv "$DIR/$1" "$2"
|
|
mv "$DIR/$1" "$2"
|
|
fi
|
|
}
|
|
|
|
BACKGROUND=0
|
|
SKIP_CONVERTERS=0
|
|
TMUX_LAYOUT="even-vertical"
|
|
CPU_MASK=""
|
|
|
|
while getopts "bl:nt:c:C:z:s:" o; do
|
|
case "$o" in
|
|
b) BACKGROUND=1 ;;
|
|
l) TMUX_LAYOUT=${OPTARG} ;;
|
|
n) SKIP_CONVERTERS=1 ;;
|
|
t) SSH_TARGET=${OPTARG} ;;
|
|
c) CONFIG=${OPTARG} ;;
|
|
C) OUT=${OPTARG} ;;
|
|
z) CPU_MASK=${OPTARG} ;;
|
|
s) SCRIPT=${OPTARG} ;;
|
|
*)
|
|
echo >&2 "Invalid option $o"
|
|
exit
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Allow out to be passed as argument
|
|
shift $((OPTIND - 1))
|
|
OUT="${OUT:-$1}"
|
|
|
|
# Provide useful usage information
|
|
if [ -z "$OUT" ]; then
|
|
echo "Usage: $0 [OPTION]... [OUTPUT]"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " -b run in the background"
|
|
echo " -l LAYOUT tmux pane layout"
|
|
echo " -n skip post-trace convertors"
|
|
echo " -t TARGET SSH device target"
|
|
echo " -c CONFIG trace configuration file"
|
|
echo " -C OUTPUT output directory"
|
|
echo " -z MASK constrain binaries to given cpu mask (taskset syntax)"
|
|
echo " -s SCRIPT a script to put into a tmux pane"
|
|
echo ""
|
|
echo "Environment variables:"
|
|
echo " SSH_TARGET SSH device target"
|
|
echo " CONFIG trace configuration file"
|
|
echo " OUT output directory"
|
|
exit 1
|
|
fi
|
|
|
|
# Warn about invalid output directories
|
|
if [ ! -f "$OUT/args.gn" ]; then
|
|
echo >&2 "OUT=$OUT doesn't look like an output directory."
|
|
echo >&2 "Please specify a directory by doing:"
|
|
echo >&2 " export OUT=out/xxx $0"
|
|
exit 1
|
|
fi
|
|
|
|
# Check SSH target is valid
|
|
if is_ssh_target && ! ssh -q "$SSH_TARGET" exit; then
|
|
echo >&2 "SSH_TARGET=$SSH_TARGET doesn't look like a valid SSH target."
|
|
echo >&2 "Please specify a SSH cross-compilation target by doing:"
|
|
echo >&2 " export SSH_TARGET=<user>@<host> $0"
|
|
exit 1
|
|
fi
|
|
|
|
if ! builtin type -P tmux &>/dev/null; then
|
|
echo >&2 "tmux not found"
|
|
exit 1
|
|
fi
|
|
|
|
# You can set the config to one of the files under test/configs e.g.
|
|
# CONFIG=ftrace.cfg or to :test. Defaults to :test.
|
|
CONFIG="${CONFIG:-:test}"
|
|
|
|
if is_android "$OUT"; then
|
|
DIR=/data/local/tmp
|
|
elif is_ssh_target; then
|
|
DIR=$(ssh "$SSH_TARGET" mktemp -d $TMPDIR/perfetto.XXXXXX)
|
|
elif is_mac; then
|
|
DIR=$(mktemp -d $TMPDIR/perfetto.XXXXXX)
|
|
else
|
|
DIR=$(mktemp -p $TMPDIR -d perfetto.XXXXXX)
|
|
fi
|
|
|
|
# (re)build the binaries
|
|
BUILD_TARGETS=(traced traced_probes perfetto test/configs)
|
|
if [[ SKIP_CONVERTERS -eq 0 ]]; then
|
|
BUILD_TARGETS+=(trace_to_text)
|
|
fi
|
|
|
|
"$SCRIPT_DIR/ninja" -C "$OUT" ${BUILD_TARGETS[*]}
|
|
|
|
push "$OUT/traced"
|
|
push "$OUT/traced_probes"
|
|
push "$OUT/perfetto"
|
|
reset_tracing
|
|
|
|
if is_android "$OUT"; then
|
|
PREFIX="PERFETTO_CONSUMER_SOCK_NAME=@perfetto_test_consumer PERFETTO_PRODUCER_SOCK_NAME=@perfetto_test_producer"
|
|
else
|
|
PREFIX=""
|
|
fi
|
|
|
|
if ! is_monolithic "$OUT"; then
|
|
PREFIX="$PREFIX LD_LIBRARY_PATH=$DIR"
|
|
push "$OUT/libperfetto.so"
|
|
fi
|
|
|
|
CONFIG_DEVICE_PATH="$CONFIG"
|
|
CMD_OPTS=""
|
|
# Shorthand for using serialized test configs.
|
|
if [[ "$CONFIG" == *.protobuf ]]; then
|
|
CONFIG_DEVICE_PATH="$CONFIG"
|
|
CONFIG_PATH=$OUT/$CONFIG
|
|
if [[ ! -f $CONFIG_PATH ]]; then
|
|
echo >&2 "Config \"$CONFIG_PATH\" not known."
|
|
exit 1
|
|
fi
|
|
push "$CONFIG_PATH"
|
|
elif [[ "$CONFIG" != ":test" ]]; then
|
|
CONFIG_DEVICE_PATH="$(basename "$CONFIG")"
|
|
CONFIG_PATH=$CONFIG
|
|
# If path isn't valid, assume it's a name of a test config.
|
|
if [[ ! -f $CONFIG_PATH ]]; then
|
|
CONFIG_PATH=test/configs/$CONFIG
|
|
if [[ ! -f $CONFIG_PATH ]]; then
|
|
echo >&2 "Config \"$CONFIG\" not known."
|
|
exit 1
|
|
fi
|
|
fi
|
|
CMD_OPTS="--txt $CMD_OPTS"
|
|
push "$CONFIG_PATH"
|
|
fi
|
|
|
|
if [[ -f "$SCRIPT" ]]; then
|
|
push "$SCRIPT"
|
|
fi
|
|
|
|
POSTFIX=""
|
|
|
|
if [[ -n "$CPU_MASK" ]]; then
|
|
PREFIX="$PREFIX taskset $CPU_MASK"
|
|
fi
|
|
|
|
if [[ BACKGROUND -eq 1 ]]; then
|
|
PREFIX="$PREFIX nohup"
|
|
POSTFIX=" &> /dev/null &"
|
|
fi
|
|
|
|
if tmux has-session -t demo; then
|
|
tmux kill-session -t demo
|
|
fi
|
|
tmux -2 new-session -d -s demo
|
|
|
|
if [ ! -z "$ANDROID_ADB_SERVER_PORT" ]; then
|
|
tmux set-environment -t demo ANDROID_ADB_SERVER_PORT $ANDROID_ADB_SERVER_PORT
|
|
fi
|
|
|
|
if tmux -V | awk '{split($2, ver, "."); if (ver[1] < 2) exit 1 ; else if (ver[1] == 2 && ver[2] < 1) exit 1 }'; then
|
|
tmux set-option -g mouse on
|
|
else
|
|
tmux set-option -g mode-mouse on
|
|
tmux set-option -g mouse-resize-pane on
|
|
tmux set-option -g mouse-select-pane on
|
|
tmux set-option -g mouse-select-window on
|
|
fi
|
|
|
|
tmux split-window -v
|
|
tmux split-window -v
|
|
|
|
if [[ -n "$SCRIPT" ]]; then
|
|
tmux split-window -v
|
|
fi
|
|
|
|
tmux select-layout "${TMUX_LAYOUT}"
|
|
|
|
tmux select-pane -t 0
|
|
tmux send-keys "clear" C-m
|
|
if is_android "$OUT"; then
|
|
tmux send-keys "adb shell" C-m
|
|
fi
|
|
|
|
tmux select-pane -t 1
|
|
tmux send-keys "clear" C-m
|
|
if is_android "$OUT"; then
|
|
tmux send-keys "adb shell" C-m
|
|
fi
|
|
|
|
tmux select-pane -t 2
|
|
tmux send-keys "clear" C-m
|
|
if is_android "$OUT"; then
|
|
tmux send-keys "adb shell" C-m
|
|
fi
|
|
|
|
if [[ -n "$SCRIPT" ]]; then
|
|
tmux select-pane -t 3
|
|
tmux send-keys "clear" C-m
|
|
if is_android "$OUT"; then
|
|
tmux send-keys "adb shell" C-m
|
|
fi
|
|
fi
|
|
|
|
sleep 2
|
|
|
|
tmux select-pane -t 1
|
|
if is_ssh_target; then
|
|
tmux send-keys "ssh $SSH_TARGET" Enter
|
|
fi
|
|
tmux_ensure_bash
|
|
tmux send-keys "PS1='[traced]$ '" Enter
|
|
tmux send-keys "cd $DIR" Enter
|
|
tmux send-keys "clear" C-m
|
|
tmux send-keys "$PREFIX ./traced $POSTFIX" Enter
|
|
|
|
tmux select-pane -t 0
|
|
if is_ssh_target; then
|
|
tmux send-keys "ssh $SSH_TARGET" Enter
|
|
fi
|
|
tmux_ensure_bash
|
|
tmux send-keys "PS1='[traced_probes]$ '" Enter
|
|
tmux send-keys "cd $DIR" Enter
|
|
tmux send-keys "clear" C-m
|
|
tmux send-keys "$PREFIX ./traced_probes $POSTFIX" Enter
|
|
|
|
tmux select-pane -t 2
|
|
if is_ssh_target; then
|
|
tmux send-keys "ssh $SSH_TARGET" Enter
|
|
fi
|
|
tmux_ensure_bash
|
|
tmux send-keys "PS1='[consumer]$ '" Enter
|
|
tmux send-keys "cd $DIR" Enter
|
|
tmux send-keys "clear" C-m
|
|
tmux send-keys "$PREFIX ./perfetto $CMD_OPTS -c $CONFIG_DEVICE_PATH -o trace $POSTFIX"
|
|
|
|
if [[ -n "$SCRIPT" ]]; then
|
|
tmux select-pane -t 3
|
|
if is_ssh_target; then
|
|
tmux send-keys "ssh $SSH_TARGET" Enter
|
|
fi
|
|
tmux_ensure_bash
|
|
tmux send-keys "PS1='[script]$ '" Enter
|
|
tmux send-keys "cd $DIR" Enter
|
|
tmux send-keys "clear" C-m
|
|
if [[ -f "$SCRIPT" ]]; then
|
|
tmux send-keys "./$(basename "$SCRIPT")"
|
|
else
|
|
tmux send-keys "$SCRIPT"
|
|
fi
|
|
fi
|
|
|
|
# Select consumer pane.
|
|
tmux select-pane -t 2
|
|
|
|
tmux -2 attach-session -t demo
|
|
if [[ BACKGROUND -eq 1 ]]; then
|
|
exit 0
|
|
fi
|
|
|
|
reset_tracing
|
|
|
|
TRACE=$TMPDIR/trace
|
|
echo -e "\n\x1b[32mPulling trace into $TRACE.protobuf\x1b[0m"
|
|
pull trace "$TRACE.protobuf"
|
|
|
|
if [[ SKIP_CONVERTERS -eq 0 ]]; then
|
|
echo -e "\n\x1b[32mPulling trace into $TRACE.pbtext\x1b[0m"
|
|
"$OUT/trace_to_text" text <"$TRACE.protobuf" >"$TRACE.pbtext"
|
|
echo -e "\n\x1b[32mPulling trace into $TRACE.json\x1b[0m"
|
|
"$OUT/trace_to_text" systrace <"$TRACE.protobuf" >"$TRACE.json"
|
|
# Keep this last so it can fail.
|
|
fi
|