| xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 1 | #! @BASH@ | 
|  | 2 | # Copyright (C) 1999-2016 Free Software Foundation, Inc. | 
|  | 3 | # This file is part of the GNU C Library. | 
|  | 4 | # Contributed by Ulrich Drepper <drepper@gnu.org>, 1999. | 
|  | 5 |  | 
|  | 6 | # The GNU C Library is free software; you can redistribute it and/or | 
|  | 7 | # modify it under the terms of the GNU Lesser General Public | 
|  | 8 | # License as published by the Free Software Foundation; either | 
|  | 9 | # version 2.1 of the License, or (at your option) any later version. | 
|  | 10 |  | 
|  | 11 | # The GNU C Library is distributed in the hope that it will be useful, | 
|  | 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | 14 | # Lesser General Public License for more details. | 
|  | 15 |  | 
|  | 16 | # You should have received a copy of the GNU Lesser General Public | 
|  | 17 | # License along with the GNU C Library; if not, see | 
|  | 18 | # <http://www.gnu.org/licenses/>. | 
|  | 19 |  | 
|  | 20 | pcprofileso='@SLIBDIR@/libpcprofile.so' | 
|  | 21 | pcprofiledump='@BINDIR@/pcprofiledump' | 
|  | 22 | TEXTDOMAIN=libc | 
|  | 23 |  | 
|  | 24 | # Print usage message. | 
|  | 25 | do_usage() { | 
|  | 26 | printf $"Usage: xtrace [OPTION]... PROGRAM [PROGRAMOPTION]...\n" | 
|  | 27 | exit 0 | 
|  | 28 | } | 
|  | 29 |  | 
|  | 30 | # Refer to --help option. | 
|  | 31 | help_info() { | 
|  | 32 | printf >&2 $"Try \`%s --help' or \`%s --usage' for more information.\n" xtrace xtrace | 
|  | 33 | exit 1 | 
|  | 34 | } | 
|  | 35 |  | 
|  | 36 | # Message for missing argument. | 
|  | 37 | do_missing_arg() { | 
|  | 38 | printf >&2 $"%s: option '%s' requires an argument.\n" xtrace "$1" | 
|  | 39 | help_info | 
|  | 40 | } | 
|  | 41 |  | 
|  | 42 | # Print help message | 
|  | 43 | do_help() { | 
|  | 44 | printf $"Usage: xtrace [OPTION]... PROGRAM [PROGRAMOPTION]...\n" | 
|  | 45 | printf $"Trace execution of program by printing currently executed function. | 
|  | 46 |  | 
|  | 47 | --data=FILE          Don't run the program, just print the data from FILE. | 
|  | 48 |  | 
|  | 49 | -?,--help              Print this help and exit | 
|  | 50 | --usage             Give a short usage message | 
|  | 51 | -V,--version           Print version information and exit | 
|  | 52 |  | 
|  | 53 | Mandatory arguments to long options are also mandatory for any corresponding | 
|  | 54 | short options. | 
|  | 55 |  | 
|  | 56 | " | 
|  | 57 | printf $"For bug reporting instructions, please see:\\n%s.\\n" \ | 
|  | 58 | "@REPORT_BUGS_TO@" | 
|  | 59 | exit 0 | 
|  | 60 | } | 
|  | 61 |  | 
|  | 62 | do_version() { | 
|  | 63 | echo 'xtrace @PKGVERSION@@VERSION@' | 
|  | 64 | printf $"Copyright (C) %s Free Software Foundation, Inc. | 
|  | 65 | This is free software; see the source for copying conditions.  There is NO | 
|  | 66 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 
|  | 67 | " "2016" | 
|  | 68 | printf $"Written by %s. | 
|  | 69 | " "Ulrich Drepper" | 
|  | 70 | exit 0 | 
|  | 71 | } | 
|  | 72 |  | 
|  | 73 | # Print out function name, file, and line number in a nicely formatted way. | 
|  | 74 | format_line() { | 
|  | 75 | fct=$1 | 
|  | 76 | file=${2%%:*} | 
|  | 77 | line=${2##*:} | 
|  | 78 | width=$(expr $COLUMNS - 30) | 
|  | 79 | filelen=$(expr length $file) | 
|  | 80 | if test "$filelen" -gt "$width"; then | 
|  | 81 | rwidth=$(expr $width - 3) | 
|  | 82 | file="...$(expr substr $file $(expr 1 + $filelen - $rwidth) $rwidth)" | 
|  | 83 | fi | 
|  | 84 | printf '%-20s  %-*s  %6s\n' $fct $width $file $line | 
|  | 85 | } | 
|  | 86 |  | 
|  | 87 |  | 
|  | 88 | # If the variable COLUMNS is not set do this now. | 
|  | 89 | COLUMNS=${COLUMNS:-80} | 
|  | 90 |  | 
|  | 91 | # If `TERMINAL_PROG' is not set, set it to `xterm'. | 
|  | 92 | TERMINAL_PROG=${TERMINAL_PROG:-xterm} | 
|  | 93 |  | 
|  | 94 | # The data file to process, if any. | 
|  | 95 | data= | 
|  | 96 |  | 
|  | 97 | # Process arguments.  But stop as soon as the program name is found. | 
|  | 98 | while test $# -gt 0; do | 
|  | 99 | case "$1" in | 
|  | 100 | --d | --da | --dat | --data) | 
|  | 101 | if test $# -eq 1; then | 
|  | 102 | do_missing_arg $1 | 
|  | 103 | fi | 
|  | 104 | shift | 
|  | 105 | data="$1" | 
|  | 106 | ;; | 
|  | 107 | --d=* | --da=* | --dat=* | --data=*) | 
|  | 108 | data=${1##*=} | 
|  | 109 | ;; | 
|  | 110 | -\? | --h | --he | --hel | --help) | 
|  | 111 | do_help | 
|  | 112 | ;; | 
|  | 113 | -V | --v | --ve | --ver | --vers | --versi | --versio | --version) | 
|  | 114 | do_version | 
|  | 115 | ;; | 
|  | 116 | --u | --us | --usa | --usag | --usage) | 
|  | 117 | do_usage | 
|  | 118 | ;; | 
|  | 119 | --) | 
|  | 120 | # Stop processing arguments. | 
|  | 121 | shift | 
|  | 122 | break | 
|  | 123 | ;; | 
|  | 124 | --*) | 
|  | 125 | printf >&2 $"xtrace: unrecognized option \`$1'\n" | 
|  | 126 | help_info | 
|  | 127 | ;; | 
|  | 128 | *) | 
|  | 129 | # Unknown option.  This means the rest is the program name and parameters. | 
|  | 130 | break | 
|  | 131 | ;; | 
|  | 132 | esac | 
|  | 133 | shift | 
|  | 134 | done | 
|  | 135 |  | 
|  | 136 | # See whether any arguments are left. | 
|  | 137 | if test $# -eq 0; then | 
|  | 138 | printf >&2 $"No program name given\n" | 
|  | 139 | help_info | 
|  | 140 | fi | 
|  | 141 |  | 
|  | 142 | # Determine the program name and check whether it exists. | 
|  | 143 | program=$1 | 
|  | 144 | shift | 
|  | 145 | if test ! -f "$program"; then | 
|  | 146 | printf >&2 $"executable \`$program' not found\n" | 
|  | 147 | help_info | 
|  | 148 | fi | 
|  | 149 | if test ! -x "$program"; then | 
|  | 150 | printf >&2 $"\`$program' is no executable\n" | 
|  | 151 | help_info | 
|  | 152 | fi | 
|  | 153 |  | 
|  | 154 | # We have two modes.  If a data file is given simply print the included data. | 
|  | 155 | printf "%-20s  %-*s  %6s\n" Function $(expr $COLUMNS - 30) File Line | 
|  | 156 | for i in $(seq 1 $COLUMNS); do printf -; done; printf '\n' | 
|  | 157 | if test -n "$data"; then | 
|  | 158 | $pcprofiledump "$data" | | 
|  | 159 | sed 's/this = \([^,]*\).*/\1/' | | 
|  | 160 | addr2line -fC -e "$program" | | 
|  | 161 | while read fct; do | 
|  | 162 | read file | 
|  | 163 | if test "$fct" != '??' -a "$file" != '??:0'; then | 
|  | 164 | format_line "$fct" "$file" | 
|  | 165 | fi | 
|  | 166 | done | 
|  | 167 | else | 
|  | 168 | fifo=$(mktemp -ut xtrace.XXXXXX) || exit | 
|  | 169 | trap 'rm -f "$fifo"; exit 1' HUP INT QUIT TERM PIPE | 
|  | 170 | mkfifo -m 0600 $fifo || exit 1 | 
|  | 171 |  | 
|  | 172 | # Now start the program and let it write to the FIFO. | 
|  | 173 | $TERMINAL_PROG -T "xtrace - $program $*" -e /bin/sh -c "LD_PRELOAD=$pcprofileso PCPROFILE_OUTPUT=$fifo $program $*; read < $fifo" & | 
|  | 174 | termpid=$! | 
|  | 175 | $pcprofiledump -u "$fifo" | | 
|  | 176 | while read line; do | 
|  | 177 | echo "$line" | | 
|  | 178 | sed 's/this = \([^,]*\).*/\1/' | | 
|  | 179 | addr2line -fC -e "$program" | 
|  | 180 | done | | 
|  | 181 | while read fct; do | 
|  | 182 | read file | 
|  | 183 | if test "$fct" != '??' -a "$file" != '??:0'; then | 
|  | 184 | format_line "$fct" "$file" | 
|  | 185 | fi | 
|  | 186 | done | 
|  | 187 | read -p "Press return here to close $TERMINAL_PROG($program)." | 
|  | 188 | echo > "$fifo" | 
|  | 189 | rm "$fifo" | 
|  | 190 | fi | 
|  | 191 |  | 
|  | 192 | exit 0 | 
|  | 193 | # Local Variables: | 
|  | 194 | #  mode:ksh | 
|  | 195 | # End: |