| 1 | #!/bin/bash |
| 2 | # |
| 3 | # Copyright (C) 2020 Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com> |
| 4 | # |
| 5 | # SPDX-License-Identifier: LGPL-2.1-only |
| 6 | |
| 7 | GENERATOR_CURDIR=$(dirname "$0")/ |
| 8 | GENERATOR_TESTDIR=$GENERATOR_CURDIR/../../../ |
| 9 | TESTAPP_PATH=${TESTAPP_PATH:-"$GENERATOR_TESTDIR/utils/testapp"} |
| 10 | |
| 11 | SYSCALL_TESTAPP_NAME=${SYSCALL_TESTAPP_NAME:-"gen-syscall-events"} |
| 12 | SYSCALL_TESTAPP_BIN=${SYSCALL_TESTAPP_BIN:-"$TESTAPP_PATH/$SYSCALL_TESTAPP_NAME/$SYSCALL_TESTAPP_NAME"} |
| 13 | |
| 14 | USERSPACE_PROBE_ELF_TESTAPP_NAME=${USERSPACE_PROBE_ELF_TESTAPP_NAME:-"userspace-probe-elf-binary"} |
| 15 | USERSPACE_PROBE_ELF_TESTAPP_BIN=${USERSPACE_PROBE_ELF_TESTAPP_BIN:-"$TESTAPP_PATH/$USERSPACE_PROBE_ELF_TESTAPP_NAME/.libs/$USERSPACE_PROBE_ELF_TESTAPP_NAME"} |
| 16 | |
| 17 | # shellcheck source=../utils/utils.sh |
| 18 | source "$GENERATOR_TESTDIR/utils/utils.sh" |
| 19 | |
| 20 | function generate_filter_events |
| 21 | { |
| 22 | local nr=$1 |
| 23 | /bin/echo -n "$nr" > /proc/lttng-test-filter-event 2> /dev/null |
| 24 | } |
| 25 | |
| 26 | function generate_syscalls |
| 27 | { |
| 28 | local nr=$1 |
| 29 | shift |
| 30 | |
| 31 | for _ in $(seq 1 "$nr"); do |
| 32 | # Pass /dev/null so to generate the syscall right away. |
| 33 | $SYSCALL_TESTAPP_BIN /dev/null "$@" |
| 34 | done |
| 35 | } |
| 36 | |
| 37 | function userspace_probe_testapp |
| 38 | { |
| 39 | local nr=$1 |
| 40 | shift |
| 41 | |
| 42 | for _ in $(seq 1 "$nr"); do |
| 43 | # This userspace probe test has to instrument the actual elf |
| 44 | # binary and not the generated libtool wrapper. However, we |
| 45 | # can't invoke the wrapper either since it will re-link the test |
| 46 | # application binary on its first invocation, resulting in a new |
| 47 | # binary with an 'lt-*' prefix under the .libs folder. The |
| 48 | # relinking stage adds the .libs folder to the 'lt-*' binary's |
| 49 | # rpath. |
| 50 | # |
| 51 | # To ensure the binary (inode) that instrumented is the same as |
| 52 | # what is running, set LD_LIBRARY_PATH to find the .libs folder |
| 53 | # that contains the libfoo.so library and invoke the binary |
| 54 | # directly. |
| 55 | LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$TESTDIR/utils/testapp/userspace-probe-elf-binary/.libs" $USERSPACE_PROBE_ELF_TESTAPP_BIN "$@" |
| 56 | done |
| 57 | } |
| 58 | |
| 59 | function ust_event_generator_toggle_state |
| 60 | { |
| 61 | ust_event_generator_suspended=$((ust_event_generator_suspended==0)) |
| 62 | } |
| 63 | |
| 64 | function generator_quit |
| 65 | { |
| 66 | generator_quit=0 |
| 67 | } |
| 68 | |
| 69 | # Note: Only one generator can be used at a time per domain type |
| 70 | function ust_event_generator_run_once_per_transition |
| 71 | { |
| 72 | # Used by the signal trap |
| 73 | ust_event_generator_suspended=0 |
| 74 | # Used by the signal trap for SIGUSR2 to end the generator |
| 75 | generator_quit=1 |
| 76 | |
| 77 | local test_app=$1 |
| 78 | local state_file=$2 |
| 79 | local nr_iter=$3 |
| 80 | local nr_usec_wait=$4 |
| 81 | local run=false |
| 82 | |
| 83 | # Pass any of the remaining arguments to the generator. |
| 84 | shift 4 |
| 85 | |
| 86 | trap ust_event_generator_toggle_state SIGUSR1 |
| 87 | trap generator_quit SIGUSR2 |
| 88 | |
| 89 | while [ $generator_quit -ne 0 ]; do |
| 90 | if [[ $ust_event_generator_suspended -eq "1" ]]; then |
| 91 | touch "$state_file" |
| 92 | # Reset the "run" state |
| 93 | run=true |
| 94 | sleep 0.5 |
| 95 | elif [ "$run" = true ]; then |
| 96 | taskset -c "$(get_any_available_cpu)" "$test_app" -i "$nr_iter" -w "$nr_usec_wait" "$@"> /dev/null 2>&1 |
| 97 | run=false; |
| 98 | if [[ -f $state_file ]]; then |
| 99 | rm -rf "$state_file" 2> /dev/null |
| 100 | fi |
| 101 | else |
| 102 | # Wait for a "suspend" to reset the run state |
| 103 | sleep 0.1 |
| 104 | fi |
| 105 | done |
| 106 | } |
| 107 | |
| 108 | # Note: Only one generator can be used at a time per domain type |
| 109 | function ust_event_generator |
| 110 | { |
| 111 | # Used by the signal trap |
| 112 | ust_event_generator_suspended=0 |
| 113 | # Used by the signal trap for SIGUSR2 to end the generator |
| 114 | generator_quit=1 |
| 115 | |
| 116 | local test_app=$1 |
| 117 | local state_file=$2 |
| 118 | local nr_iter=1000 |
| 119 | local nr_usec_wait=5 |
| 120 | |
| 121 | # Pass any of the remaining arguments to the generator. |
| 122 | shift 2 |
| 123 | |
| 124 | trap ust_event_generator_toggle_state SIGUSR1 |
| 125 | trap generator_quit SIGUSR2 |
| 126 | |
| 127 | while [ $generator_quit -ne 0 ]; do |
| 128 | if [[ $ust_event_generator_suspended -eq "1" ]]; then |
| 129 | touch "$state_file" |
| 130 | # Reset the "run" state |
| 131 | sleep 0.5 |
| 132 | else |
| 133 | taskset -c "$(get_any_available_cpu)" "$test_app" -i $nr_iter -w $nr_usec_wait "$@" > /dev/null 2>&1 |
| 134 | if [[ -f $state_file ]]; then |
| 135 | rm -rf "$state_file" 2> /dev/null |
| 136 | fi |
| 137 | fi |
| 138 | done |
| 139 | } |
| 140 | |
| 141 | function kernel_event_generator_toggle_state |
| 142 | { |
| 143 | kernel_event_generator_suspended=$((kernel_event_generator_suspended==0)) |
| 144 | } |
| 145 | |
| 146 | function kernel_event_generator_run_once_per_transition |
| 147 | { |
| 148 | # Used by the signal trap |
| 149 | kernel_event_generator_suspended=0 |
| 150 | # Used by the signal trap for SIGUSR2 to end the generator |
| 151 | generator_quit=1 |
| 152 | |
| 153 | local generator=$1 |
| 154 | local state_file=$2 |
| 155 | local nr_iter=$3 |
| 156 | |
| 157 | # Pass any of the remaining arguments to the generator. |
| 158 | shift 3 |
| 159 | |
| 160 | local run=false |
| 161 | trap kernel_event_generator_toggle_state SIGUSR1 |
| 162 | trap generator_quit SIGUSR2 |
| 163 | |
| 164 | while [ $generator_quit -ne 0 ]; do |
| 165 | if [[ $kernel_event_generator_suspended -eq "1" ]]; then |
| 166 | touch "$state_file" |
| 167 | run=true |
| 168 | sleep 0.5 |
| 169 | elif [ "$run" = true ]; then |
| 170 | $generator "$nr_iter" "$@" |
| 171 | run=false |
| 172 | if [[ -f $state_file ]]; then |
| 173 | rm "$state_file" 2> /dev/null |
| 174 | fi |
| 175 | else |
| 176 | # Wait for a "suspend" to reset the run state |
| 177 | sleep 0.1 |
| 178 | fi |
| 179 | done |
| 180 | } |
| 181 | |
| 182 | function kernel_event_generator |
| 183 | { |
| 184 | # Used by the signal trap |
| 185 | kernel_event_generator_suspended=0 |
| 186 | # Used by the signal trap for SIGUSR2 to end the generator |
| 187 | generator_quit=1 |
| 188 | |
| 189 | local generator=$1 |
| 190 | local state_file=$2 |
| 191 | |
| 192 | # Pass any of the remaining arguments to the generator. |
| 193 | shift 2 |
| 194 | |
| 195 | trap kernel_event_generator_toggle_state SIGUSR1 |
| 196 | trap generator_quit SIGUSR2 |
| 197 | |
| 198 | while [ $generator_quit -ne 0 ]; do |
| 199 | if [[ $kernel_event_generator_suspended -eq "1" ]]; then |
| 200 | touch "$state_file" |
| 201 | sleep 0.5 |
| 202 | else |
| 203 | $generator "10" "$@" |
| 204 | if [[ -f $state_file ]]; then |
| 205 | rm "$state_file" 2> /dev/null |
| 206 | fi |
| 207 | fi |
| 208 | done |
| 209 | } |