File: coverage_cc.sh

package info (click to toggle)
fis-gtm 7.1-006-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 32,908 kB
  • sloc: ansic: 344,906; asm: 5,184; csh: 4,859; sh: 2,000; awk: 294; makefile: 73; sed: 13
file content (187 lines) | stat: -rwxr-xr-x 6,897 bytes parent folder | download | duplicates (3)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#!/bin/sh
#################################################################
#								#
# Copyright (c) 2021 Fidelity National Information		#
# Services, Inc. and/or its subsidiaries. All rights reserved.	#
#								#
#	This source code contains the intellectual property	#
#	of its copyright holder(s), and is made available	#
#	under a license.  If you do not know the terms of	#
#	the license, please stop and do not read further.	#
#								#
#################################################################

##
# @file
#
# @brief Replace the standard GT.M compiler with a coverage enabled one
#
# Our purpose here in this script is to be a drop-in C compiler (for linux/gcc only)
# which can be the object of the gt_cc_compiler environment variable.
#
# If we are invoked, our only purpose in life is to add the "--coverage"
# and supporting flags to compiles, and the "-lgcov" flag to loads, *except* for certain
# exceptional files (forex: tmpCFile2.c from scantypedefs.m)
#
# Since all our gcc versions on hosts participating in a coverage run must be
# the same, and since we originally used some advanced coverage features, we standardize
# on gcc-10.2.0 for our underlying compiler here.  Since this is not the default on
# any of our hosts, we use a set-aside directory to make sure we get the correct version.
# If we can't find a compliant compiler, we just fall back to an unuseful, but
# harmless regular run.

##
# @brief Main driver for the compiler script
#
# We run through the command line here, deciding if we are doing a coverage compile or now.
# If we are, and the system supports it, we massage argv so as to add the needed flags to
# enable coverage mode in GCC and pull in libgcov at link time.
#
# @return We will generally exit with the exit status of the underlying compiler
#
main () {
	real_compiler="gcc"
	can_profile=1
	# We assume we are run from /usr/library/VXXX/dbg/obj
	#obj_dir=`pwd`
	#build=`echo $obj_dir | sed -e 's?/usr/library/??' -e 's?/.*$??'`

	# First, determine if we are compile or link invocation of the compiler
	# and if we are doing a DEBUG build. (We only add coverage flags to a debug
	# build)
	is_debug_build=0
	is_compile=0
	is_link=0
	is_stop_list=0

	# List of C files for which we do not want to turn on --coverage
	stop_list="tmpCFile.c tmpCFile2.c gtm_threadgbl_deftypes.c"

	# Peek at our command line arguments to guess what we are doing
	for arg
	do
		if [ $arg = "-DDEBUG" ]; then
			is_debug_build=1
		fi

		# We are a debug link if we see something like "-L/usr/library/V972/dbg/obj"
		case $arg in
			-L*dbg/obj)
				is_debug_build=1
				;;
		esac

		if [ $arg = "-std=c99" ]; then
			is_compile=1
		fi

		if [ $arg = "-lrt" ]; then
			is_link=1
		fi

		for stop_file in $stop_list
		do
			case $arg in
				$stop_file)
					is_stop_list=1
					;;
				*/${stop_file})
					is_stop_list=1
					;;
			esac
		done
	done

	# If we are not linux, not doing a debug build, or if we are on the stop list punt to the original compiler/options
	if [ \( $OSTYPE != "linux" \) -o \( $is_debug_build -eq 0 \) -o \( $is_stop_list -eq 1 \) ]; then
		exec $real_compiler $*
	fi

	# We are doing a debug build.  Can our default compiler profile at the pid-separated level?

	# Find the gcc version, gcc --version will return something like
	# gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
	# and we always care only about the first line/last field
	#
	gcc_version=`$real_compiler --version | head -1 | sed -e 's/^.* //'`

	# This section used to look for gcc >= 10, but it turns out that the
	# profiling data is *very* version specific, so we must use gcc-10.2.0.
	# If that is not the system gcc (and it won't be on any current linux box of ours)
	# then we have to check to see if we have installed 10.2.0 on the side and
	# use it. If not, we just skip profiling and do a normal compile, que sera, sera.
	if [ $gcc_version != "10.2.0" ]; then
		can_profile=0
		if [ -x "/usr/local/cluster/gcc-10.2.0/bin/gcc" ]; then
			export PATH="/usr/local/cluster/gcc-10.2.0/bin:$PATH"
			real_compiler=gcc
			can_profile=1
		fi
	fi

	# Overlay ourselves and punt to a standard compile.
	if [ $can_profile -ne 1 ]; then
		exec $real_compiler $*
	fi

	# It is standard practice for automated (ie: not developer driven) test runs to be compiled as
	# 'library' and run as 'gtmtest'.  Therefore, if we are running as library, we want to adjust
	# things so gcda files land under gtmtest.
	runtime_user=$USER
	if [ $USER = "library" ]; then
		runtime_user="gtmtest"
	fi

	# If we get here, we are building DEBUG & can profile
	# GCOV_PREFIX_STRIP lets us move the GCDA files easily.
	# (Re)Creating the gcda output dir and its ACL here is not ideal,
	# but if we don't, it's possible some GCDA files will be created during
	# build with a non 666 mode and might be unwritable by different userids in
	# a later test.
	export GCOV_PREFIX_STRIP=5

	# We go ahead and create this directory here because later parts of
	# the build process run mumps code so we can't really leave it to the
	# test system.  I think the gcc runtime would create it, but would not get the ACL
	# created, which could leave us with unwritable .gcda files later.
	# We use a timestamp on the output dir so if the build changes, it doesn't write to the wrong version
	time_stamp=`ls -ld /usr/library/$gtm_verno | \
		gawk '{time=sprintf("%s_%02d_%s",toupper($6),$7,$8); gsub(":","",time); print time}'`
	profile_dir="/testarea1/${runtime_user}/coverage/${gtm_verno}_${time_stamp}/gcda"
	if [ ! -d $profile_dir ]; then
		mkdir -p $profile_dir
	fi
	chmod ugo+rx $profile_dir

	# we need ACLs because tests run as a number of different users.  If this fails, punt
	# to standard compile. (This is our last chance to punt because after this we start fiddling argv)
	# We trash stderr because there's no point in punting to standard compile if we are going to break
	# the build with an error message anyway.
	if setfacl -d -m other::rw -m user::rw -m group::rw $profile_dir 2> /dev/null; then
		:
	else
		exec $real_compiler $*
	fi

	# Patch argv to include coverage options.  Originally the gcda files were generated
	# in /usr/library/VXXX/dbg/obj, but that was blowing up /usr/library, so now they
	# are generated in /testarea1/$runtime_user/coverage/gcda.
	# The profile-prefix-path keeps the files from being renamed with weird '#' escapes.
	argv="$*"
	if [ \( $is_compile -eq 1 \) -a \( $is_debug_build -eq 1 \) -a \( $is_stop_list -eq 0 \) ]; then
		argv="-fprofile-prefix-path=/usr/library/${gtm_verno}/dbg/obj $argv"
		argv="-fprofile-dir=${profile_dir} $argv"
		argv="--coverage $argv"
	fi

	# If we are linking, we can always add -lgcov and this will be
	# harmless if none of the objects need those symbols
	if [ $is_link -eq 1 ]; then
		argv="$argv -lgcov"
	fi

	# Now that we have edited our command line, run it with the real compiler
	exec $real_compiler $argv
}

main $*