Enable coverage when strace is self terminated by signal
authorDmitry V. Levin <ldv@altlinux.org>
Sat, 27 May 2017 18:58:31 +0000 (18:58 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sat, 27 May 2017 18:58:31 +0000 (18:58 +0000)
The data collected by -fprofile-arcs during program run is saved
on program exit.  When program is terminated by signal, the data
is not saved.  However, libgcov provides an interface to dump
the data at runtime.

* m4/ax_code_coverage.m4 (AX_CODE_COVERAGE): Add -DENABLE_COVERAGE_GCOV
to CODE_COVERAGE_CPPFLAGS.
* strace.c [ENABLE_COVERAGE_GCOV] (__gcov_flush): New prototype.
(main) [ENABLE_COVERAGE_GCOV]: Call __gcov_flush() before raise()
and sigprocmask() calls that might cause program termination.

m4/ax_code_coverage.m4
strace.c

index 93dfce3a0d735035ed27ba0b12bf96ce3810dab5..3d417f0f7934c0e104cfb351924b8259d7fcc2ec 100644 (file)
@@ -140,7 +140,7 @@ AC_DEFUN([AX_CODE_COVERAGE],[
                ])
 
                dnl Build the code coverage flags
-               CODE_COVERAGE_CPPFLAGS="-DNDEBUG"
+               CODE_COVERAGE_CPPFLAGS="-DENABLE_COVERAGE_GCOV -DNDEBUG"
                CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
                CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
                CODE_COVERAGE_LDFLAGS="-lgcov"
index bdfe1357fd3955d644956b2d05e6eab1bb0fee72..42650ab51f9afcc822443175b68f7875e7102a35 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -2512,6 +2512,10 @@ restart_tracee:
        return true;
 }
 
+#ifdef ENABLE_COVERAGE_GCOV
+extern void __gcov_flush();
+#endif
+
 int
 main(int argc, char *argv[])
 {
@@ -2538,12 +2542,18 @@ main(int argc, char *argv[])
                /* Child was killed by a signal, mimic that.  */
                exit_code &= 0xff;
                signal(exit_code, SIG_DFL);
+#ifdef ENABLE_COVERAGE_GCOV
+               __gcov_flush();
+#endif
                raise(exit_code);
 
                /* Unblock the signal.  */
                sigset_t mask;
                sigemptyset(&mask);
                sigaddset(&mask, exit_code);
+#ifdef ENABLE_COVERAGE_GCOV
+               __gcov_flush();
+#endif
                sigprocmask(SIG_UNBLOCK, &mask, NULL);
 
                /* Paranoia - what if this signal is not fatal?