aboutsummaryrefslogtreecommitdiffstats
path: root/test/run_and_catch_crashes
blob: 690706a9ab9ffdadd894c80fa8c642a1935a2d31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#! /bin/sh
#
# Run command in a way that catches crashes
#
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# Copyright 2015 Gerald Combs
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Run the command we're passed in a subshell, so that said subshell will
# catch any signals from it and report it.
#
# This must be done for commands that aren't the last command in the
# pipeline, as, given that the exit status of a pipeline is the exit
# status of the last command in the pipeline, there's no guarantee that
# the shell will bother to pick up the exit status of earlier commands
# in the pipeline.
#
# It can also be done for other tests, to get more information than
# "it crashed due to signal XXX" if the tests fail with a crash signal.
#
# XXX - on macOS, core dumps are in /cores/core.{PID}; would they appear
# elsewhere on any other UN*X?
#
rm -f core
"$@"
exitstatus=$?
if [ -r core ]
then
	#
	# Core dumped - try to get a stack trace.
	#
	# First, find the executable.  Skip past env and any env
	# arguments to find the actual executable path.  (If you
	# run a program with an explicit path, and it dumps core,
	# at least on Solaris the output of "file" on the core dump
	# will not give the path, so we don't use that.)
	#
	if [ "$1" = "env" ]
	then
		#
		# Skip past the env command name.
		#
		shift
		#
		# Skip past environment-variable arguments; anything
		# with an "=" in it is an environment-variable argument.
		#
		while expr "$1" : ".*=.*" >/dev/null 2>&1
		do
			shift
		done
echo last expr command was expr "$1" : ".*=.*"
	fi
	if [ -x "$1" ]
	then
		executable="$1"
	else
		executable=`which "$1"`
	fi

	if [ ! -z "$executable" ]
	then
		#
		# Found the executable.
		# Is it a libtool wrapper script?  Look for a .libs
		# directory.
		#
		executable_dirname=`dirname "$executable"`
		if [ -d "$executable_dirname"/.libs ]
		then
			is_libtool_wrapper=yes
		else
			is_libtool_wrapper=no
		fi

		#
		# Now, look for a debugger.
		# XXX - lldb?
		#
		dbx=`which dbx`
		if [ ! -z "$dbx" ]
		then
			#
			# Found dbx.  Run it to get a stack trace;
			# cause the stack trace to go to the standard
			# error.
			#
			if [ $is_libtool_wrapper = yes ]
			then
				$executable_dirname/libtool --mode=execute dbx "$executable" core 1>&2 <<EOF
where
quit
EOF
			else
				dbx "$executable" core 1>&2 <<EOF
where
quit
EOF
			fi
		else
			gdb=`which gdb`
			if [ ! -z "$gdb" ]
			then
				#
				# Found gdb.  Run it to get a stack trace;
				# cause the stack trace to go to the standard
				# error.
				#
				if [ $is_libtool_wrapper = yes ]
				then
					$executable_dirname/libtool --mode=execute gdb "$executable" core 1>&2 <<EOF
backtrace
quit
EOF
				else
					gdb "$executable" core 1>&2 <<EOF
backtrace
quit
EOF
				fi
			fi
		fi
	fi
fi
exit $exitstatus