]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
ci: collect coverage on _exit() as well
authorFrantisek Sumsal <frantisek@sumsal.cz>
Tue, 20 Jun 2023 21:01:35 +0000 (23:01 +0200)
committerFrantisek Sumsal <frantisek@sumsal.cz>
Thu, 22 Jun 2023 10:03:04 +0000 (12:03 +0200)
_exit() skips the gcov hooks, so we lose all coverage collected up to
that point. Let's work around this by intercepting _exit() with our
wrapper that calls __gcov_dump() just before _exit().

Makefile.am
include/Makemodule.am
include/coverage.h [new file with mode: 0644]

index e52a7f592d7155bce777019d3def3705a26454b2..0335f589372769f503ceca71376750300cb071cf 100644 (file)
@@ -17,6 +17,11 @@ AM_CPPFLAGS += \
 endif
 endif
 
+if WITH_COVERAGE
+AM_CPPFLAGS += \
+       -include $(top_srcdir)/include/coverage.h
+endif
+
 AM_CFLAGS = -fsigned-char $(WARN_CFLAGS)
 AM_CXXFLAGS = $(AM_CFLAGS)
 AM_LDFLAGS = $(ASAN_LDFLAGS) $(UBSAN_LDFLAGS) $(FUZZING_ENGINE_LDFLAGS) $(COVERAGE_LDFLAGS)
index 068b0f8e804f5cb59b6fc4c4cf43fbef7399ddf8..52657f7d1542283d5264e40aff065489c7ba753b 100644 (file)
@@ -13,6 +13,7 @@ dist_noinst_HEADERS += \
        include/closestream.h \
        include/colors.h \
        include/color-names.h \
+       include/coverage.h \
        include/cpuset.h \
        include/crc32.h \
        include/crc32c.h \
diff --git a/include/coverage.h b/include/coverage.h
new file mode 100644 (file)
index 0000000..f0148e5
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * No copyright is claimed.  This code is in the public domain; do with
+ * it what you wish.
+ */
+#ifndef UTIL_LINUX_COVERAGE_H
+#define UTIL_LINUX_COVERAGE_H
+
+/* When built with --coverage (gcov) we need to explicitly call __gcov_dump()
+ * in places where we use _exit(), since _exit() skips at-exit hooks resulting
+ * in lost coverage.
+ *
+ * To make sure we don't miss any _exit() calls, this header file is included
+ * explicitly on the compiler command line via the -include directive (only
+ * when built with --coverage/-Db_coverage=true)
+ */
+void __gcov_dump(void);
+void _exit(int);
+
+__attribute__((noreturn)) static inline void _coverage__exit(int status) {
+        __gcov_dump();
+        _exit(status);
+}
+#define _exit(x) _coverage__exit(x)
+
+#endif