Skip to content

Commit e17069f

Browse files
Michalis Pappasmichpappas
authored andcommitted
Introduce lib-embedded-gcov
Port of embedded-gcov[1] for Unikraft. [1] https://github.com/nasa-jpl/embedded-gcov Signed-off-by: Michalis Pappas <[email protected]>
1 parent c3154a3 commit e17069f

File tree

5 files changed

+263
-1
lines changed

5 files changed

+263
-1
lines changed

Config.uk

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
menuconfig LIBEMBEDDEDGCOV
2+
bool "embedded-gcov"
3+
default n
4+
5+
if LIBEMBEDDEDGCOV
6+
config LIBEMBEDDEDGCOV_PROVIDE_CALL_CONSTRUCTORS
7+
bool "Provide call constructors"
8+
help
9+
In most systems __gcov_init() is called on startup. If you are
10+
running on a non-standard startup environment you can enable this
11+
option, and gcov-embedded will provide __gcov_call_constructors()
12+
that you can run manually. You will also need to define __ctor_list
13+
and __ctor_end.
14+
default n
15+
16+
config LIBEMBEDDEDGCOV_PRINT_STATUS
17+
bool "Print status to console"
18+
help
19+
Print status and error messages to the serial console. If the
20+
coverage data output is set to console, status is always printed
21+
to the console.
22+
default n
23+
24+
config LIBEMBEDDEDGCOV_USE_MALLOC
25+
bool "Use malloc"
26+
depends on LIBUKALLOC
27+
help
28+
Use malloc to get space for coverage data"
29+
default y
30+
31+
choice LIBEMBEDDEDGCOV_OUTPUT
32+
prompt "Coverage data output"
33+
default LIBEMBEDDEDGCOV_OUTPUT_SERIAL_HEXDUMP
34+
config LIBEMBEDDEDGCOV_OUTPUT_SERIAL_HEXDUMP
35+
bool "Console"
36+
endchoice
37+
38+
endif

Makefile.uk

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
#
3+
# embedded-gcov Makefile.uk
4+
#
5+
# Authors: Michalis Pappas <[email protected]>
6+
#
7+
# Copyright (c) 2023, Unikraft GmbH
8+
#
9+
# Redistribution and use in source and binary forms, with or without
10+
# modification, are permitted provided that the following conditions
11+
# are met:
12+
#
13+
# 1. Redistributions of source code must retain the above copyright
14+
# notice, this list of conditions and the following disclaimer.
15+
# 2. Redistributions in binary form must reproduce the above copyright
16+
# notice, this list of conditions and the following disclaimer in the
17+
# documentation and/or other materials provided with the distribution.
18+
# 3. Neither the name of the copyright holder nor the names of its
19+
# contributors may be used to endorse or promote products derived from
20+
# this software without specific prior written permission.
21+
#
22+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32+
# POSSIBILITY OF SUCH DAMAGE.
33+
#
34+
################################################################################
35+
# App registration
36+
################################################################################
37+
$(eval $(call addlib,libembeddedgcov,$(CONFIG_LIBEMBEDDEDGCOV)))
38+
39+
################################################################################
40+
# Sources
41+
################################################################################
42+
LIBEMBEDDEDGCOV_BRANCH = main
43+
LIBEMBEDDEDGCOV_URL = https://github.com/nasa-jpl/embedded-gcov.git
44+
LIBEMBEDDEDGCOV_PATCHDIR = $(LIBEMBEDDEDGCOV_BASE)/patches
45+
$(eval $(call clone,libembeddedgcov,$(LIBEMBEDDEDGCOV_URL),$(LIBEMBEDDEDGCOV_BRANCH)))
46+
$(eval $(call patch,libembeddedgcov,$(LIBEMBEDDEDGCOV_PATCHDIR),$(LIBEMBEDDEDGCOV_BASENAME)))
47+
48+
################################################################################
49+
# Library sources
50+
################################################################################
51+
LIBEMBEDDEDGCOV_SRCS-y += $(LIBEMBEDDEDGCOV_ORIGIN)/code/gcov_public.c
52+
LIBEMBEDDEDGCOV_SRCS-y += $(LIBEMBEDDEDGCOV_ORIGIN)/code/gcov_gcc.c
53+
LIBEMBEDDEDGCOV_SRCS-y += $(LIBEMBEDDEDGCOV_ORIGIN)/code/gcov_printf.c
54+
55+
################################################################################
56+
# Library includes
57+
################################################################################
58+
CINCLUDES-$(CONFIG_LIBEMBEDDEDGCOV) += -I$(LIBEMBEDDEDGCOV_ORIGIN)/code
59+
CXXINCLUDES-$(CONFIG_LIBEMBEDDEDGCOV) += -I$(LIBEMBEDDEDGCOV_ORIGIN)/code
60+
61+
################################################################################
62+
# Library flags
63+
################################################################################
64+
65+
CFLAGS-$(CONFIG_LIBEMBEDDEDGCOV) += -ftest-coverage -fprofile-arcs
66+
67+
ifneq ($(CONFIG_LIBEMBEDDEDGCOV_OUTPUT_BINARY_FILE),)
68+
$(error Binary file output not implemented)
69+
endif
70+
ifneq ($(CONFIG_LIBEMBEDDEDGCOV_OUTPUT_BINARY_MEMORY),)
71+
$(error Memory output not implemented)
72+
endif
73+
74+
LIBEMBEDDEDGCOV_CFLAGS-y += -Dgcov_printf=printf
75+
LIBEMBEDDEDGCOV_CFLAGS-$(CONFIG_LIBEMBEDDEDGCOV_OUTPUT_SERIAL_HEXDUMP) += -DGCOV_OPT_OUTPUT_SERIAL_HEXDUMP
76+
LIBEMBEDDEDGCOV_CFLAGS-$(CONFIG_LIBEMBEDDEDGCOV_PRINT_STATUS) += -DGCOV_OPT_PRINT_STATUS
77+
LIBEMBEDDEDGCOV_CFLAGS-$(CONFIG_LIBEMBEDDEDGCOV_PROVIDE_CALL_CONSTRUCTORS) += -DGCOV_OPT_PROVIDE_CALL_CONSTRUCTORS
78+
LIBEMBEDDEDGCOV_CFLAGS-$(CONFIG_LIBEMBEDDEDGCOV_USE_MALLOC) += -DGCOV_OPT_USE_MALLOC

README.md

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,48 @@
11
# lib-embedded-gcov
2-
Coverage suppport
2+
3+
Unikraft port of [embedded-gcov](https://github.com/nasa-jpl/embedded-gcov).
4+
5+
## Initialization and Termination
6+
7+
Initialization of gcov is done transparently to the application. `lib-embedded-gcov` adds the required GCC options for coverage, and at runtime `__gcov_init()` is automatically call when Unikraft boots via constructors.
8+
9+
To dump the coverage data you need to update the application to manually call `__gcov_exit()`.
10+
11+
## Collecting Coverage Results
12+
13+
embedded-gcov provides three types of output:
14+
- Binary file
15+
- Memory
16+
- Serial console
17+
18+
At this moment `lib-gcov-embedded` supports only serial console output.
19+
20+
### Serial Console Output
21+
22+
To obtain coverage results via the console you need to dump the console output into a file. With QEMU this is possible by configuring the serial device to log all output into a file:
23+
```
24+
-chardev stdio,id=char0,logfile=serial.log,signal=off -serial chardev:char0
25+
```
26+
27+
The console output then needs to be processed into an lcov report. `lib-embedded-gcov` provides the `gcov_process.sh` script for that, which is essentially a wrapper around the tools provided by `embedded-gcov`.
28+
29+
Before executing the script make sure you have the required dependencies installed, that is:
30+
- dox2unix
31+
- lcov
32+
33+
With dependencies installed, execute the script as:
34+
```
35+
lib-embedded-gcov/scripts/gcov_process.sh <build_directory> <console_log>
36+
```
37+
38+
The script will generate an lcov report and provide a link as shown below.
39+
```
40+
...
41+
Writing directory view page.
42+
Overall coverage rate:
43+
lines......: 29.8% (2345 of 7858 lines)
44+
functions..: 36.3% (228 of 628 functions)
45+
46+
lcov report in file:///home/mpp/devel/unikraft_oss/uk_embedded-gcov/app-helloworld/build/libembeddedgcov/origin/results/html/index.html
47+
```
48+
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
From 51043fb1ad5b99a66749bce2661b388e26b6f90f Mon Sep 17 00:00:00 2001
2+
From: michpappas <[email protected]>
3+
Date: Sat, 21 Jan 2023 18:11:26 +0100
4+
Subject: [PATCH] Disable all user options to allow controlling via KConfig
5+
6+
---
7+
code/gcov_public.h | 10 +++++-----
8+
1 file changed, 5 insertions(+), 5 deletions(-)
9+
10+
diff --git a/code/gcov_public.h b/code/gcov_public.h
11+
index 0982c2c..9a32a8c 100644
12+
--- a/code/gcov_public.h
13+
+++ b/code/gcov_public.h
14+
@@ -51,7 +51,7 @@
15+
* If defined, you must also provide defs below
16+
* for GCOV_PRINT_STR and GCOV_PRINT_NUM.
17+
*/
18+
-#define GCOV_OPT_PRINT_STATUS
19+
+//#define GCOV_OPT_PRINT_STATUS
20+
21+
/* Reset watchdog timeout during gcov tree scanning.
22+
* Might be needed if you enable serial output on a slow port,
23+
@@ -95,7 +95,7 @@ extern void *__ctor_end;
24+
* You might NOT want this if you are extremely memory constrained
25+
* (such as in PROM) and do not need this function to take up some bytes.
26+
*/
27+
-#define GCOV_OPT_PROVIDE_CLEAR_COUNTERS
28+
+//#define GCOV_OPT_PROVIDE_CLEAR_COUNTERS
29+
30+
/* Provide small imitation printf function.
31+
* This is only needed if you want serial port outputs and
32+
@@ -104,7 +104,7 @@ extern void *__ctor_end;
33+
* write_bytes() that does the actual serial output in your system.
34+
* See gcov_printf.c
35+
*/
36+
-#define GCOV_OPT_PROVIDE_PRINTF_IMITATION
37+
+//#define GCOV_OPT_PROVIDE_PRINTF_IMITATION
38+
39+
/* select data output method(s) ------------------------------------ */
40+
41+
@@ -122,7 +122,7 @@ extern void *__ctor_end;
42+
43+
/* Modify this output filename if desired */
44+
/* Not used if you do not define GCOV_OPT_OUTPUT_BINARY_FILE */
45+
-#define GCOV_OUTPUT_BINARY_FILENAME "gcov_output.bin"
46+
+//#define GCOV_OUTPUT_BINARY_FILENAME "gcov_output.bin"
47+
48+
/* Modify file headers, data type and functions, if needed */
49+
/* Not used if you do not define GCOV_OPT_OUTPUT_BINARY_FILE */
50+
@@ -164,7 +164,7 @@ typedef FILE * GCOV_FILE_TYPE;
51+
* for GCOV_PRINT_STR and GCOV_PRINT_NUM.
52+
* Can be combined with other GCOV_OPT_OUTPUT_* options.
53+
*/
54+
-#define GCOV_OPT_OUTPUT_SERIAL_HEXDUMP
55+
+//#define GCOV_OPT_OUTPUT_SERIAL_HEXDUMP
56+
57+
/* Function to print a string without newline.
58+
* Not used if you don't define either GCOV_OPT_PRINT_STATUS
59+
--
60+
2.25.1
61+

scripts/gcov_process.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
set -e
3+
4+
if [[ $# -ne 2 ]]; then
5+
echo "Usage: $0 <build_dir> <console_dump>"
6+
exit
7+
fi
8+
9+
if [ -n "${CROSS_COMPILE}" ]; then
10+
GCOV=${CROSS_COMPILE}/gcov
11+
else
12+
GCOV=$(which gcov)
13+
fi
14+
15+
if [ -z "$GCOV" ]; then
16+
echo "$0: Could not find gcov"
17+
exit
18+
fi
19+
20+
BUILD_DIR=$(realpath $1)
21+
CONSOLE_DUMP=$(realpath $2)
22+
GCOV_DIR=${BUILD_DIR}/libembeddedgcov/origin/
23+
24+
cd ${GCOV_DIR}/scripts
25+
26+
rm -rf ../objs/*
27+
rm -rf ../results/*
28+
29+
find $BUILD_DIR -type d -name objs -prune -o -name \*.gcno -exec cp {} ../objs/ \;
30+
31+
lcov --gcov-tool ${CROSS_COMPILE}gcov --capture --initial \
32+
--directory ../objs/ -o ../results/baseline.info
33+
34+
./gcov_convert.sh $CONSOLE_DUMP
35+
./lcov_newcoverage.sh
36+
./lcov_combine_new_base.sh
37+
./genhtml_report.sh
38+
39+
echo -e "\nlcov report in file://$(realpath ../results/html)/index.html\n"

0 commit comments

Comments
 (0)