Skip to content

Commit 3d6f2df

Browse files
committed
Merge branch 'leo/111-ccg_testing' into 'master'
Adapt gnatcov_rts for CCG and add support for CCG testing in the testsuite See merge request eng/das/cov/gnatcoverage!333 This MR brings various changes related to CCG support: * A configuration option in gnatcov_rts to be able to ignore the C sources, to be compatible with CCG * various preparatory changes in the testsuite: * The possibility to use an alternate builder in an altrun * Missing test.opt settings for native light runtime configuration * More configurability in libsupport, to be able to override the last chance handler heuristics and pass cargs on the command line * And a new altrun to be able to build test executables through CCG, for a native target only. A MR will follow in Anod to schedule a run with CCG. Part of eng/das/cov/gnatcoverage#111
2 parents 9e2ef02 + 5164407 commit 3d6f2df

File tree

28 files changed

+603
-56
lines changed

28 files changed

+603
-56
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ lib
2424
/testsuite/suite.cgpr
2525
/testsuite/support
2626
/testsuite/tmp
27+
/testsuite/altrun/ccg_native/ccg_gnatcov_rts
28+
/testsuite/altrun/ccg_native/adainclude
2729
gnatcov-loc.xml
2830
gnatinspect.db
2931
README.html

doc/gnatcov/src_traces.rst

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,7 @@ the default coverage runtime library, in practice only one use case is
972972
supported currently: changing the behavior of the
973973
``--dump-channel=base64-stdout`` instrumentation option.
974974
975+
.. _custom_base_64:
975976
976977
Customize the ``base64-stdout`` dump channel
977978
--------------------------------------------
@@ -1037,3 +1038,71 @@ file so that it implements the interface described in the (unmodified)
10371038
const char *str;
10381039
size_t length;
10391040
};
1041+
1042+
Building instrumented programs with CCG
1043+
=======================================
1044+
1045+
Programs instrumented with |gcvins| can be built using the
1046+
`GNAT Pro Common Code Generator <https://docs.adacore.com/live/wave/gnat-ccg/html/gnatccg_ug/gnat_ccg.html>`_
1047+
provided a few modifications are made to the coverage runtime, and
1048+
respecting some limitations in terms of dump-trigger and dump-channel choice.
1049+
1050+
Customizing the runtime
1051+
-----------------------
1052+
1053+
Given the workflow associated with CCG, it is not possible to use the |gcvstp|
1054+
command to setup the coverage runtime. Instead, it must be prepared manually.
1055+
1056+
The coverage runtime contains both Ada and C sources. When using CCG through
1057+
GPRbuild, projects containing C sources are not well handled and some steps of
1058+
the build procedure won't be executed. There thus is an external variable to
1059+
remove all C sources from the project. This means that C sources must be
1060+
manually managed during the executable compilation later on.
1061+
1062+
The first step is to copy the runtime sources in a dedicated directory. For the
1063+
remainder of this section, it will be denoted by ``ccg_gnatcov_rts``.
1064+
1065+
.. code-block:: sh
1066+
1067+
mkdir ccg_gnatcov_rts
1068+
cp -r <gnatdas_install_dir>/share/gnatcoverage/gnatcov_rts ccg_gnatcov_rts
1069+
1070+
Then, C sources not relevant to the coverage runtime for the CCG configuration
1071+
must be deleted:
1072+
1073+
.. code-block:: sh
1074+
1075+
rm ccg_gnatcov_rts/gnatcov_rts_c-base-io.c
1076+
rm ccg_gnatcov_rts/gnatcov_rts_c-trace-output-files.*
1077+
rm ccg_gnatcov_rts/gnatcov_rts_c-os_interface.*
1078+
1079+
Finally, it is necessary to modify the contents of
1080+
``ccg_gnatcov_rts/gnatcov_rts-base_io.adb`` to use an alternate medium on which
1081+
the execution trace will be output. By default this relies on ``GNAT.IO``,
1082+
which is not available in the CCG runtime. It is possible to replace occurrences
1083+
of this unit by ``Ada.Text_IO``, which is supported by CCG, but which relies on
1084+
the C standard function ``putchar``. Otherwise, see :ref:`custom_base_64` for
1085+
more details on the expected interface to dump the coverage trace information.
1086+
1087+
Building an instrumented program with CCG
1088+
-----------------------------------------
1089+
1090+
Building an instrumented program with CCG is done in the same manner as with
1091+
any other target, with the exception that GPRbuild must be instructed to use
1092+
the custom coverage runtime prepared in the previous step, and by setting an
1093+
external variable to configure the coverage runtime project for a build with
1094+
CCG:
1095+
1096+
.. code-block:: sh
1097+
1098+
gprbuild -P <user_project.gpr> --src-subdirs=gnatcov-instr \
1099+
--implicit-with=ccg_gnatcov_rts/gnatcov_rts.gpr \
1100+
-XGNATCOV_RTS_FOR_CCG=true \
1101+
<relevant target cargs>
1102+
1103+
After the generation of C sources is complete, all the coverage runtime C sources
1104+
must be included in the build process of the executable. These can be found
1105+
under ``ccg_gnatcov_rts/`` for the sources already present before the gprbuild
1106+
invocation, and under ``ccg_gnatcov_rts/obj-gnatcov_rts.static`` for the sources
1107+
generated by CCG. The C sources generated from the instrumented Ada sources will
1108+
be available in the object directory of their corresponding project.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c XFAIL Runtime check bug in CCG, see eng/toolchain/gnat-llvm#73
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c DEAD ASM inlining not supported by CCG
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c DEAD ASM inlining not supported by CCG
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
native,RTS_ZFP DEAD Test assumes bin file available on native platform

testsuite/SUITE/context.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,12 @@ def suite_covpgm_for(self, cmd):
459459
"""
460460
return getattr(thistest.options, 'gnatcov_%s' % cmd, None)
461461

462+
def suite_gprpgm_for(self, pgm):
463+
"""
464+
Alternate program to launch in lieu of "gpr<tool>",
465+
"""
466+
return getattr(thistest.options, pgm, None)
467+
462468
def support_dir(self):
463469
return os.path.join(ROOT_DIR, 'support')
464470

testsuite/SUITE/control.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -241,20 +241,29 @@ def __init__(self, runtime_name=None):
241241
self.has_kernel_runtime = False
242242
self.has_light_runtime = False
243243
self.has_exception_propagation = True
244+
self.discrs = []
244245

245246
if not self.runtime_name:
246247
self.has_full_runtime = True
248+
self.discrs = ["RTS_FULL"]
247249
elif 'embedded' in self.runtime_name:
248250
self.has_ravenscar_runtime = True
251+
self.discrs = ["RTS_RAVENSCAR", "RTS_EMBEDDED"]
249252
elif 'light-tasking' in self.runtime_name:
250253
self.has_ravenscar_runtime = True
251254
self.has_exception_propagation = False
255+
self.discrs = ["RTS_RAVENSCAR", "RTS_LIGHT_TASKING"]
252256
elif self.runtime_name.startswith('zfp'):
253257
self.has_light_runtime = True
254258
self.has_exception_propagation = False
255-
elif self.runtime_name.startswith('light-'):
259+
self.discrs = ["RTS_ZFP"]
260+
elif (
261+
self.runtime_name == "light"
262+
or self.runtime_name.startswith('light-')
263+
):
256264
self.has_light_runtime = True
257265
self.has_exception_propagation = False
266+
self.discrs = ["RTS_ZFP"]
258267
elif self.runtime_name == 'kernel':
259268
self.has_kernel_runtime = True
260269
else:
@@ -273,12 +282,19 @@ def gnatcov_rts_project(self):
273282
else 'gnatcov_rts'
274283
)
275284

276-
def runtime_info(runtime=None):
277-
if runtime is None:
278-
runtime = env.main_options.RTS
285+
def _runtime_info(runtime, target):
286+
if target == "c":
287+
assert not runtime
288+
# CCG's runtime has no name, but it is for our purposes equivalent
289+
# to a light runtime.
290+
runtime = "light"
279291
return RuntimeInfo(runtime)
280292

281293

294+
def runtime_info():
295+
return _runtime_info(env.main_options.RTS, env.target.platform)
296+
297+
282298
# Target specificities. We don't have many variants but need to match each
283299
# against a few possible triplets.
284300

@@ -381,16 +397,19 @@ def gnatcov_info():
381397
('pre', 'testcase'),
382398
('post', 'testcase'))
383399

400+
# Allowed alternatives for the --gpr<tool> family of command line options
401+
ALTRUN_GPR = ('gprbuild', )
384402

385-
def altrun_opt_for(p0, p1):
403+
404+
def altrun_opt_for(p0, p1=None):
386405
"""Name of the command line option controlling the ALTRUN (P0, P1) pair."""
387-
return "%s_%s" % (p0, p1)
406+
return "%s_%s" % (p0, p1) if p1 else p0
388407

389408

390-
def altrun_attr_for(p0, p1):
409+
def altrun_attr_for(p0, p1=None):
391410
"""Name of our internal controlling options attribute for the
392411
ALTRUN (P0, P1) pair."""
393-
return "%s_%s" % (p0, p1)
412+
return "%s_%s" % (p0, p1) if p1 else p0
394413

395414

396415
def cargs_opt_for(lang):
@@ -419,6 +438,14 @@ def add_shared_options_to(parser, toplevel):
419438
metavar="CMD",
420439
help='Use CMD instead of "%s %s"' % (pgm, cmd))
421440

441+
# --gpr<tool> family
442+
for pgm in ALTRUN_GPR:
443+
parser.add_argument(
444+
f'--{altrun_opt_for(pgm)}', dest=altrun_attr_for(pgm),
445+
metavar="CMD",
446+
help=f'use CMD instead of "{pgm}"'
447+
)
448+
422449
# Valgrind control
423450
parser.add_argument(
424451
'--enable-valgrind', dest='enable_valgrind',

testsuite/SUITE/tutils.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,12 @@ def gprbuild(project,
291291
# Now cleanup, do build and check status
292292
thistest.cleanup(project)
293293

294-
args = (to_list(BUILDER.BASE_COMMAND) +
294+
builder = thistest.suite_gprpgm_for(os.path.basename(BUILDER.BASE_COMMAND))
295+
296+
if builder is None:
297+
builder = BUILDER.BASE_COMMAND
298+
299+
args = (to_list(builder) +
295300
['-P%s' % project] + all_gargs + all_cargs + all_largs)
296301
p = run_and_log(args, output=out, timeout=thistest.options.timeout)
297302
if register_failure:
@@ -836,7 +841,7 @@ def run_cov_program(executable, out=None, env=None, exec_args=None,
836841
inp = None
837842

838843
# If we are in a cross configuration, run the program using GNATemulator
839-
if thistest.options.target:
844+
if thistest.options.target and thistest.env.target.platform != "c":
840845
kernel = thistest.options.kernel
841846
board = thistest.options.board or thistest.env.target.machine
842847
args.append('{}-gnatemu'.format(thistest.env.target.triplet))
@@ -852,6 +857,14 @@ def run_cov_program(executable, out=None, env=None, exec_args=None,
852857
# failing. Redirecting the standard input to /dev/null works around
853858
# this issue.
854859
inp = DEVNULL
860+
else:
861+
# Native programs using a light runtime can't set the exit code, and
862+
# will often terminate with a non-zero status code even though nothing
863+
# went wrong. There is thus no point in checking the exit code in this
864+
# configuration.
865+
register_failure = (
866+
register_failure and not RUNTIME_INFO.has_light_runtime
867+
)
855868

856869
args.append(executable)
857870
args.extend(exec_args)

0 commit comments

Comments
 (0)