#!/bin/bash # # Copyright (C) 2017 Francis Deslauriers # # SPDX-License-Identifier: GPL-2.0-only # TEST_DESC="Kernel tracer - Callstack context" CURDIR=$(dirname "$0")/ TESTDIR=$CURDIR/../.. NUM_TESTS=11 TEST_APP_USERSPACE="$TESTDIR/utils/testapp/gen-syscall-events-callstack/gen-syscall-events-callstack" TEST_APP_KERNELSPACE="$TESTDIR/utils/testapp/gen-syscall-events/gen-syscall-events" PARSE_CALLSTACK="$TESTDIR/utils/parse-callstack.py" SESSION_NAME="callstack" CHANNEL_NAME="chan0" source "$TESTDIR/utils/utils.sh" function lttng_untrack_all() { lttng_untrack 0 "-s $SESSION_NAME --all --pid -k" } function lttng_track_pid() { local PID=$1 lttng_track 0 "-s $SESSION_NAME -k --pid=$PID" } function run_workload() { local TEST_APP=$1 # shift the first argument, passing along the other args if any to the # test app. shift local start_file_sync start_file_sync=$(mktemp -u) lttng_untrack_all ./"$TEST_APP" "$start_file_sync" "$@" & PID=$! lttng_track_pid $PID start_lttng_tracing_ok # Create start file to launch the execution of the syscall call by the # test app. touch "$start_file_sync" wait $PID stop_lttng_tracing_ok # Clean up the synchronization file. rm -f "$start_file_sync" } function test_user_callstack() { TRACE_PATH=$(mktemp -d) # This is the expected userspace callstack. (see gen-syscall-events-callstack.c) USER_CS_EXPECTED="main fct_a fct_b fct_c my_gettid" EVENT_NAME="gettid" diag "Userspace callstack test" create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" lttng_enable_kernel_channel_ok "$SESSION_NAME" "$CHANNEL_NAME" lttng_enable_kernel_syscall_ok "$SESSION_NAME" "$EVENT_NAME" "$CHANNEL_NAME" add_context_kernel_ok "$SESSION_NAME" "$CHANNEL_NAME" "callstack-user" run_workload $TEST_APP_USERSPACE destroy_lttng_session_ok "$SESSION_NAME" "$BABELTRACE_BIN" "$TRACE_PATH" | grep $EVENT_NAME | ./"$PARSE_CALLSTACK" --user "$TEST_APP_USERSPACE" $USER_CS_EXPECTED ok $? "Validate userspace callstack" rm -rf "$TRACE_PATH" } function test_kernel_callstack() { TRACE_PATH=$(mktemp -d) # Those are symbol expected to be present in the kernel callstack. This # is not an exhaustive list since it's kernel dependent. # FIXME: we used to test for the following symbols as well: # save_stack_trace, lttng_callstack_get_size, but they were removed # because: # 1. kernel commit 77072f09 make it so that save_stack_trace is # omitted from the callstack itself, and # # 2. the code (of this commit) can trigger Tail Call Optimization # which mess up with the stacktrace by omiting the wrong address # from the stacktrace. # When this is fixed, we should add both save_stack_trace and # lttng_callstack_get_size symbols back in the list of expected # addresses. KERNEL_CS_EXPECTED="lttng_event_reserve" EVENT_NAME="read" diag "Kernel callstack test" create_lttng_session_ok $SESSION_NAME "$TRACE_PATH" lttng_enable_kernel_channel_ok "$SESSION_NAME" "$CHANNEL_NAME" lttng_enable_kernel_syscall_ok "$SESSION_NAME" "$EVENT_NAME" "$CHANNEL_NAME" add_context_kernel_ok "$SESSION_NAME" "$CHANNEL_NAME" "callstack-kernel" run_workload "$TEST_APP_KERNELSPACE" "/proc/cpuinfo" "/proc/cmdline" destroy_lttng_session_ok "$SESSION_NAME" "$BABELTRACE_BIN" "$TRACE_PATH" | grep $EVENT_NAME | ./"$PARSE_CALLSTACK" --kernel $KERNEL_CS_EXPECTED ok $? "Validate kernel callstack" rm -rf "$TRACE_PATH" } # Only run userspace callstack test on x86 uname -m | grep -E "x86" >/dev/null 2>&1 if test $? == 0; then NUM_TESTS=$((NUM_TESTS+11)) RUN_USERSPACE_TEST=1 else RUN_USERSPACE_TEST=0 fi # MUST set TESTDIR before calling those functions plan_tests $NUM_TESTS print_test_banner "$TEST_DESC" if [ "$(id -u)" == "0" ]; then isroot=1 else isroot=0 fi skip $isroot "Root access is needed. Skipping all tests." "$NUM_TESTS" || { which "$BABELTRACE_BIN" > /dev/null test $? -ne 0 skip $? "Babeltrace binary not found. Skipping callstack tests" "$NUM_TESTS" || { start_lttng_sessiond if test $RUN_USERSPACE_TEST == 1; then test_user_callstack fi test_kernel_callstack stop_lttng_sessiond } }