autoconf: Add support for code coverage

Add support for code coverage collection. This helps
developers to check if their test scenarios really exercised
all the OpenOCD functionality that they intended to test.

- Option --enable-gcov has been added to configure.ac
  which enables the coverage collection using Gcov. (Disabled
  by default.)

- The steps to collect and inspect the coverage have been
  described in HACKING file.

Change-Id: I259e401937a255e7ad7f155359a0b7787e4d0752
Signed-off-by: Jan Matyas <jan.matyas@codasip.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8521
Tested-by: jenkins
Reviewed-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
Jan Matyas 2024-10-10 20:35:19 +02:00 committed by Antonio Borneo
parent fd62626dff
commit d4a64e3f38
5 changed files with 54 additions and 1 deletions

4
.gitignore vendored
View File

@ -15,6 +15,10 @@
src/jtag/minidriver_imp.h src/jtag/minidriver_imp.h
src/jtag/jtag_minidriver.h src/jtag/jtag_minidriver.h
# coverage files (gcov)
*.gcda
*.gcno
# OpenULINK driver files generated by SDCC # OpenULINK driver files generated by SDCC
src/jtag/drivers/OpenULINK/*.rel src/jtag/drivers/OpenULINK/*.rel
src/jtag/drivers/OpenULINK/*.asm src/jtag/drivers/OpenULINK/*.asm

16
HACKING
View File

@ -92,6 +92,22 @@ patch:
make make
@endcode @endcode
- Code coverage analysis
By inspecting the code coverage, you can identify potential gaps in your testing
and use that information to improve your test scenarios.
Example usage:
@code
mkdir build-gcov; cd build-gcov
../configure --enable-gcov [...]
make
# ... Now execute your test scenarios to collect OpenOCD code coverage ...
lcov --capture --directory ./src --output-file openocd-coverage.info
genhtml openocd-coverage.info --output-directory coverage_report
# ... Open coverage_report/index.html in a web browser ...
@endcode
Please consider performing these additional checks where appropriate Please consider performing these additional checks where appropriate
(especially Clang Static Analyzer for big portions of new code) and (especially Clang Static Analyzer for big portions of new code) and
mention the results (e.g. "Valgrind-clean, no new Clang analyzer mention the results (e.g. "Valgrind-clean, no new Clang analyzer

View File

@ -38,6 +38,7 @@ endif
# common flags used in openocd build # common flags used in openocd build
AM_CFLAGS = $(GCC_WARNINGS) AM_CFLAGS = $(GCC_WARNINGS)
AM_LDFLAGS =
AM_CPPFLAGS = $(HOST_CPPFLAGS)\ AM_CPPFLAGS = $(HOST_CPPFLAGS)\
-I$(top_srcdir)/src \ -I$(top_srcdir)/src \
@ -51,6 +52,12 @@ AM_CPPFLAGS += -I$(top_srcdir)/jimtcl \
else else
AM_CPPFLAGS += $(JIMTCL_CFLAGS) AM_CPPFLAGS += $(JIMTCL_CFLAGS)
endif endif
if USE_GCOV
AM_CFLAGS += --coverage
AM_LDFLAGS += --coverage
endif
EXTRA_DIST += \ EXTRA_DIST += \
BUGS \ BUGS \
HACKING \ HACKING \

View File

@ -171,6 +171,9 @@ m4_define([DUMMY_ADAPTER],
m4_define([OPTIONAL_LIBRARIES], m4_define([OPTIONAL_LIBRARIES],
[[[capstone], [Use Capstone disassembly framework], []]]) [[[capstone], [Use Capstone disassembly framework], []]])
m4_define([COVERAGE],
[[[gcov], [Collect coverage using gcov], []]])
AC_ARG_ENABLE([doxygen-html], AC_ARG_ENABLE([doxygen-html],
AS_HELP_STRING([--disable-doxygen-html], AS_HELP_STRING([--disable-doxygen-html],
[Disable building Doxygen manual as HTML.]), [Disable building Doxygen manual as HTML.]),
@ -199,6 +202,19 @@ AC_ARG_ENABLE([werror],
AS_HELP_STRING([--disable-werror], [Do not treat warnings as errors]), AS_HELP_STRING([--disable-werror], [Do not treat warnings as errors]),
[gcc_werror=$enableval], [gcc_werror=$gcc_warnings]) [gcc_werror=$enableval], [gcc_werror=$gcc_warnings])
AC_ARG_ENABLE([gcov],
AS_HELP_STRING([--enable-gcov], [Enable runtime coverage collection via gcov]),
[enable_gcov=$enableval], [enable_gcov=no])
AS_IF([test "x$enable_gcov" = "xyes"], [
AC_DEFINE([USE_GCOV], [1], [1 to enable coverage collection using gcov.])
dnl When collecting coverage, disable optimizations.
dnl This overrides the "-O2" that autoconf uses by default:
CFLAGS+=" -O0"
], [
AC_DEFINE([USE_GCOV], [0], [0 to leave coverage collection disabled.])
])
# set default verbose options, overridden by following options # set default verbose options, overridden by following options
debug_usb_io=no debug_usb_io=no
debug_usb_comms=no debug_usb_comms=no
@ -787,6 +803,8 @@ AM_CONDITIONAL([INTERNAL_JIMTCL], [test "x$use_internal_jimtcl" = "xyes"])
AM_CONDITIONAL([HAVE_JIMTCL_PKG_CONFIG], [test "x$have_jimtcl_pkg_config" = "xyes"]) AM_CONDITIONAL([HAVE_JIMTCL_PKG_CONFIG], [test "x$have_jimtcl_pkg_config" = "xyes"])
AM_CONDITIONAL([INTERNAL_LIBJAYLINK], [test "x$use_internal_libjaylink" = "xyes"]) AM_CONDITIONAL([INTERNAL_LIBJAYLINK], [test "x$use_internal_libjaylink" = "xyes"])
AM_CONDITIONAL([USE_GCOV], [test "x$enable_gcov" = "xyes"])
# Look for environ alternatives. Possibility #1: is environ in unistd.h or stdlib.h? # Look for environ alternatives. Possibility #1: is environ in unistd.h or stdlib.h?
AC_MSG_CHECKING([for environ in unistd.h and stdlib.h]) AC_MSG_CHECKING([for environ in unistd.h and stdlib.h])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@ -862,7 +880,8 @@ m4_foreach([adapter], [USB1_ADAPTERS,
LIBGPIOD_ADAPTERS, LIBGPIOD_ADAPTERS,
LIBJAYLINK_ADAPTERS, PCIE_ADAPTERS, SERIAL_PORT_ADAPTERS, LIBJAYLINK_ADAPTERS, PCIE_ADAPTERS, SERIAL_PORT_ADAPTERS,
DUMMY_ADAPTER, DUMMY_ADAPTER,
OPTIONAL_LIBRARIES], OPTIONAL_LIBRARIES,
COVERAGE],
[s=m4_format(["%-40s"], ADAPTER_DESC([adapter])) [s=m4_format(["%-40s"], ADAPTER_DESC([adapter]))
AS_CASE([$ADAPTER_VAR([adapter])], AS_CASE([$ADAPTER_VAR([adapter])],
[auto], [ [auto], [

View File

@ -375,6 +375,13 @@ int openocd_main(int argc, char *argv[])
log_exit(); log_exit();
#if USE_GCOV
/* Always explicitly dump coverage data before terminating.
* Otherwise coverage would not be dumped when exit_on_signal occurs. */
void __gcov_dump(void);
__gcov_dump();
#endif
if (ret == ERROR_FAIL) if (ret == ERROR_FAIL)
return EXIT_FAILURE; return EXIT_FAILURE;
else if (ret != ERROR_OK) else if (ret != ERROR_OK)