xtrace 5.1 KB

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