blob: 9f00b5f82b2c04c5d377895c8e2f7abaea300c0e [file] [log] [blame]
#!/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
CUR_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
export PATH="$PATH:$CUR_DIR"
if [ "$TMPDIR" == "" ]; then
TMPDIR=/tmp
fi
function get_gn_value() {
local out=$1
local key=$2
gn args "$out" --list --short | sed -n -e "s/$key = \"\(.*\)\"/\1/p"
}
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_gn_target_and_host_value_equal() {
local out=$1
local key=$2
local host
local target
host=$(get_gn_value "$out" "host_$key")
target=$(get_gn_value "$out" "target_$key")
[ -z "$target" ] && target="$host"
test "$target" == "$host"
}
function is_cross_compilation() {
local out=$1
if is_gn_target_and_host_value_equal "$out" cpu &&
is_gn_target_and_host_value_equal "$out" os; then
false
else
true
fi
}
function is_mac() {
! 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_cross_compilation "$OUT"; then
# shellcheck disable=SC2029
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_cross_compilation "$OUT"; then
echo scp "$1" "$TARGET:$DIR"
scp "$1" "$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_cross_compilation "$OUT"; then
echo scp "$TARGET:$DIR/$1" "$2"
scp "$TARGET:$DIR/$1" "$2"
else
echo mv "$DIR/$1" "$2"
mv "$DIR/$1" "$2"
fi
}
BACKGROUND=0
SKIP_CONVERTERS=0
TMUX_LAYOUT="even-vertical"
while getopts "bl:nt:c:C:" o; do
case "$o" in
b) BACKGROUND=1 ;;
l) TMUX_LAYOUT=${OPTARG} ;;
n) SKIP_CONVERTERS=1 ;;
t) TARGET=${OPTARG} ;;
c) CONFIG=${OPTARG} ;;
C) OUT=${OPTARG} ;;
*)
echo "Invalid option $o"
exit
;;
esac
done
# Allow out to be passed as argument
shift $((OPTIND - 1))
OUT="${OUT:-$1}"
# Warn about invalid output directories
if [ -z "$OUT" ]; then
echo "Usage: $0 [OPTION]... [OUTPUT]"
echo ""
echo "Options:"
echo " -b run in the background"
echo " -l 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 ""
echo "Environment variables:"
echo " TARGET SSH device target"
echo " CONFIG trace configuration file"
echo " OUTPUT output directory"
exit 1
fi
# Warn about invalid output directories
if [ ! -f "$OUT/args.gn" ]; then
echo "OUT=$OUT doesn't look like an output directory."
echo "Please specify a directory by doing:"
echo " export OUT=out/xxx $0"
exit 1
fi
# If we are cross-compiling we need to know the SSH target
if is_cross_compilation "$OUT" && ! ssh -q "$TARGET" exit; then
echo "TARGET=$TARGET doesn't look like a valid SSH target."
echo "Please specify a SSH cross-compilation target by doing:"
echo " export TARGET=<user>@<host> $0"
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_cross_compilation "$OUT"; then
DIR=$(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
tools/ninja -C "$OUT" traced traced_probes perfetto trace_to_text test/configs
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=""
if [[ "$CONFIG" == *.protobuf ]]; then
CONFIG_DEVICE_PATH="$CONFIG"
CONFIG_PATH=$OUT/$CONFIG
if [[ ! -f $CONFIG_PATH ]]; then
echo "Config \"$CONFIG_PATH\" not known."
exit 1
fi
push "$CONFIG_PATH"
elif [[ "$CONFIG" != ":test" ]]; then
CONFIG_DEVICE_PATH="$(basename "$CONFIG")"
CONFIG_PATH=test/configs/$CONFIG
# Check if this is a valid absolute path
if [[ ! -f $CONFIG_PATH ]]; then
CONFIG_PATH=$CONFIG
if [[ ! -f $CONFIG_PATH ]]; then
echo "Config \"$CONFIG\" not known."
exit 1
fi
fi
CMD_OPTS="--txt $CMD_OPTS"
push "$CONFIG_PATH"
fi
POSTFIX=""
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 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
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
sleep 2
tmux select-pane -t 1
if is_cross_compilation "$OUT"; then
tmux send-keys "ssh $TARGET" Enter
fi
tmux_ensure_bash
tmux send-keys "PS1='[traced]$ '" Enter
tmux send-keys "cd $DIR" Enter
tmux send-keys "$PREFIX ./traced 2>&1 | tee traced.log $POSTFIX" Enter
tmux select-pane -t 0
if is_cross_compilation "$OUT"; then
tmux send-keys "ssh $TARGET" Enter
fi
tmux_ensure_bash
tmux send-keys "PS1='[traced_probes]$ '" Enter
tmux send-keys "cd $DIR" Enter
tmux send-keys "$PREFIX ./traced_probes 2>&1 | tee traced_probes.log $POSTFIX" Enter
tmux select-pane -t 2
if is_cross_compilation "$OUT"; then
tmux send-keys "ssh $TARGET" Enter
fi
tmux_ensure_bash
tmux send-keys "PS1='[consumer]$ '" Enter
tmux send-keys "cd $DIR" Enter
tmux send-keys "$PREFIX ./perfetto $CMD_OPTS -c $CONFIG_DEVICE_PATH -o trace 2>&1 | tee perfetto.log $POSTFIX"
# 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=$HOME/Downloads/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