catchsegv 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #!/bin/sh
  2. # Copyright (C) 1998-2021 Free Software Foundation, Inc.
  3. # This file is part of the GNU C Library.
  4. # Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
  5. # The GNU C Library is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU Lesser General Public
  7. # License as published by the Free Software Foundation; either
  8. # version 2.1 of the License, or (at your option) any later version.
  9. # The GNU C Library is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. # Lesser General Public License for more details.
  13. # You should have received a copy of the GNU Lesser General Public
  14. # License along with the GNU C Library; if not, see
  15. # <https://www.gnu.org/licenses/>.
  16. if test $# -eq 0; then
  17. echo "$0: missing program name" >&2
  18. echo "Try \`$0 --help' for more information." >&2
  19. exit 1
  20. fi
  21. prog="$1"
  22. shift
  23. if test $# -eq 0; then
  24. case "$prog" in
  25. --h | --he | --hel | --help)
  26. echo 'Usage: catchsegv PROGRAM ARGS...'
  27. echo ' --help print this help, then exit'
  28. echo ' --version print version number, then exit'
  29. echo 'For bug reporting instructions, please see:'
  30. cat <<\EOF
  31. <https://bugs.linaro.org/>.
  32. EOF
  33. exit 0
  34. ;;
  35. --v | --ve | --ver | --vers | --versi | --versio | --version)
  36. echo 'catchsegv (GNU) 2.33'
  37. echo 'Copyright (C) 2021 Free Software Foundation, Inc.
  38. This is free software; see the source for copying conditions. There is NO
  39. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  40. Written by Ulrich Drepper.'
  41. exit 0
  42. ;;
  43. *)
  44. ;;
  45. esac
  46. fi
  47. segv_output=`mktemp ${TMPDIR:-/tmp}/segv_output.XXXXXX` || exit
  48. # Redirect stderr to avoid termination message from shell.
  49. (exec 3>&2 2>/dev/null
  50. LD_PRELOAD=${LD_PRELOAD:+${LD_PRELOAD}:}/\$LIB/libSegFault.so \
  51. SEGFAULT_USE_ALTSTACK=1 \
  52. SEGFAULT_OUTPUT_NAME=$segv_output \
  53. "$prog" ${1+"$@"} 2>&3 3>&-)
  54. exval=$?
  55. # Check for output. Even if the program terminated correctly it might
  56. # be that a minor process (clone) failed. Therefore we do not check the
  57. # exit code.
  58. if test -s "$segv_output"; then
  59. # The program caught a signal. The output is in the file with the
  60. # name we have in SEGFAULT_OUTPUT_NAME. In the output the names of
  61. # functions in shared objects are available, but names in the static
  62. # part of the program are not. We use addr2line to get this information.
  63. case $prog in
  64. */*) ;;
  65. *)
  66. old_IFS=$IFS
  67. IFS=:
  68. for p in $PATH; do
  69. test -n "$p" || p=.
  70. if test -f "$p/$prog"; then
  71. prog=$p/$prog
  72. break
  73. fi
  74. done
  75. IFS=$old_IFS
  76. ;;
  77. esac
  78. sed '/Backtrace/q' "$segv_output"
  79. sed '1,/Backtrace/d' "$segv_output" |
  80. (while read line; do
  81. line=`echo $line | sed "s@^$prog\\(\\[.*\\)@\1@"`
  82. case "$line" in
  83. \[*) addr=`echo "$line" | sed 's/^\[\(.*\)\]$/\1/'`
  84. complete=`addr2line -f -e "$prog" $addr 2>/dev/null`
  85. if test $? -eq 0; then
  86. echo "`echo "$complete"|sed 'N;s/\(.*\)\n\(.*\)/\2(\1)/;'`$line"
  87. else
  88. echo "$line"
  89. fi
  90. ;;
  91. *) echo "$line"
  92. ;;
  93. esac
  94. done)
  95. fi
  96. rm -f "$segv_output"
  97. exit $exval