#!/bin/sh # Copyright (C) 2018 The Qt Company Ltd. # Contact: https://www.qt.io/licensing/ # # This file is part of Qt Creator. # # Commercial License Usage # Licensees holding valid commercial Qt licenses may use this file in # accordance with the commercial license agreement provided with the # Software or, alternatively, in accordance with the terms contained in # a written agreement between you and The Qt Company. For licensing terms # and conditions see https://www.qt.io/terms-conditions. For further # information use the contact form at https://www.qt.io/contact-us. # # GNU General Public License Usage # Alternatively, this file may be used under the terms of the GNU # General Public License version 3 as published by the Free Software # Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT # included in the packaging of this file. Please review the following # information to ensure the GNU General Public License requirements will # be met: https://www.gnu.org/licenses/gpl-3.0.html. >&2 echo "
"
mount -o remount,mode=755 /sys/kernel/debug/ || return 1
mount -o remount,mode=755 /sys/kernel/debug/tracing/ || return 1
>&2 echo "done"
register_arguments() {
REGISTERS="$1"
shift
ARGUMENTS=""
for R in $REGISTERS; do
test -z "$*" && break;
ARGUMENTS="$ARGUMENTS $R=$1";
shift;
done
return ARGUMENTS
}
remove_tracepoints() {
perf probe -d "perfprofiler_$1_$2*"
return 0
}
match_tracepoints() {
MACHINE=$1
NAME=$2
BASE="perfprofiler_${MACHINE}_${NAME}"
RETURN=`perf probe -l "${BASE}_ret" | awk '{print $3}'`
if [ -z "$RETURN" ]; then
RETURN=`perf probe -l "${BASE}_ret__return" | awk '{print $3}'`
fi
CHECK=
for RET in $RETURN; do
if [ -n "$CHECK" ]; then
CHECK="$CHECK && "
fi
CHECK="$CHECK\$3 != \"$RET\""
done
ENTRY=`echo ${RETURN} | awk '{sub(/%return/, ""); print $1}'`
BAD=`perf probe -l "${BASE}*" | awk '{ if ('"$CHECK"' && $3 != "'$ENTRY'") { print $1 } }'`
for PROBE in $BAD; do
perf probe -d $PROBE
done
return 0
}
set_simple_tracepoint() {
MACHINE="$1"
shift
BINARY="$1"
shift
NAME="$1"
shift
FUNCTION="$1"
shift
REGISTERS="$1"
shift
ARGUMENTS=""
for R in ${REGISTERS}; do
test -z "$*" && break;
ARGUMENTS="${ARGUMENTS} $1=${R}";
shift;
done
FULL_NAME="perfprofiler_${MACHINE}_${NAME}"
perf probe -x "${BINARY}" -a "${FULL_NAME}=${FUNCTION} ${ARGUMENTS}" || return 1
return 0
}
set_symbolic_tracepoint() {
>&2 echo ""
set_simple_tracepoint "$1" "$2" "$3_paramstest" "$4" "\$params" "$5" || return 1
PARAM=`perf probe -l | awk "/perfprofiler_$1_$3_paramstest"'/{sub(/\)$/, ""); print $(NF)}'`
perf probe -d "perfprofiler_$1_$3_paramstest"
set_simple_tracepoint "$1" "$2" "$3" "$4" "$5" "$PARAM" || return 1
return 0
}
set_register_tracepoint() {
>&2 echo ""
case "$1" in
aarch64|arm*)
set_simple_tracepoint "$1" "$2" "$3" "$4" "%r0 %r1 %r2 %r3" $5 || return 1;
;;
x86_64)
set_simple_tracepoint "$1" "$2" "$3" "$4" "%di %si %dx %cx" $5 || return 1;
;;
*)
>&2 echo "Register trace points are not supported on $1"
return 1
;;
esac
return 0
}
set_tracepoint() {
if [ -n "$6" ]; then
>&2 echo ""
set_simple_tracepoint "$1" "$2" "$3" "$4" "$5" "$6" || return 1
else
set_register_tracepoint "$1" "$2" "$3" "$4" "$5" || \
set_symbolic_tracepoint "$1" "$2" "$3" "$4" "$5" || \
return 1
fi
return 0
}
HOST_MACHINE=`uname -m`
find /lib/ -name libc.so.6 | while read LIBC; do
echo $LIBC | awk -F '/' '{print $(NF-1)}' | while IFS='-' read MACHINE KERNEL SYSTEM; do
if [ "$MACHINE" = "lib" ]; then MACHINE=$HOST_MACHINE; fi
>&2 echo ""
remove_tracepoints "$MACHINE" "malloc"
remove_tracepoints "$MACHINE" "free"
remove_tracepoints "$MACHINE" "cfree"
remove_tracepoints "$MACHINE" "realloc"
remove_tracepoints "$MACHINE" "calloc"
remove_tracepoints "$MACHINE" "valloc"
remove_tracepoints "$MACHINE" "pvalloc"
remove_tracepoints "$MACHINE" "memalign"
remove_tracepoints "$MACHINE" "aligned_alloc"
>&2 echo ""
set_tracepoint "$MACHINE" "$LIBC" "malloc" "malloc" "requested_amount" && \
set_tracepoint "$MACHINE" "$LIBC" "malloc_ret" "malloc%return" "\$retval" "obtained_id" && \
set_tracepoint "$MACHINE" "$LIBC" "free" "free" "released_id" && \
set_tracepoint "$MACHINE" "$LIBC" "cfree" "cfree" "released_id" && \
set_tracepoint "$MACHINE" "$LIBC" "realloc" "realloc" "released_id requested_amount" && \
set_tracepoint "$MACHINE" "$LIBC" "realloc_ret" "realloc%return" "\$retval" "moved_id" && \
set_tracepoint "$MACHINE" "$LIBC" "calloc" "calloc" "requested_blocks requested_amount" && \
set_tracepoint "$MACHINE" "$LIBC" "calloc_ret" "calloc%return" "\$retval" "obtained_id" && \
set_tracepoint "$MACHINE" "$LIBC" "valloc" "valloc" "requested_amount" && \
set_tracepoint "$MACHINE" "$LIBC" "valloc_ret" "valloc%return" "\$retval" "obtained_id" && \
set_tracepoint "$MACHINE" "$LIBC" "pvalloc" "pvalloc" "requested_amount" && \
set_tracepoint "$MACHINE" "$LIBC" "pvalloc_ret" "pvalloc%return" "\$retval" "obtained_id" && \
set_tracepoint "$MACHINE" "$LIBC" "memalign" "memalign" "align requested_amount" && \
set_tracepoint "$MACHINE" "$LIBC" "memalign_ret" "memalign%return" "\$retval" "obtained_id" && \
echo $MACHINE || \
>&2 echo "!!! Failed to create some trace points for $MACHINE !!!"
# aligned_alloc is conditional on C11 and may not be available
set_tracepoint "$MACHINE" "$LIBC" "aligned_alloc" "aligned_alloc" "align requested_amount" && \
set_tracepoint "$MACHINE" "$LIBC" "aligned_alloc_ret" "aligned_alloc%return" "\$retval" "obtained_id"
>&2 echo ""
match_tracepoints "$MACHINE" "malloc"
match_tracepoints "$MACHINE" "realloc"
match_tracepoints "$MACHINE" "calloc"
match_tracepoints "$MACHINE" "valloc"
match_tracepoints "$MACHINE" "pvalloc"
match_tracepoints "$MACHINE" "memalign"
match_tracepoints "$MACHINE" "aligned_alloc"
done
done
>&2 echo ""
exit