From 88a928ea6241800e48cb722070efca6c5a1bbb89 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sun, 16 Jan 2022 18:45:29 +0000 Subject: [PATCH] run: Avoid execve() when measuring test coverage Normally, we want to save a process and get better signal handling by replacing the `flatpak run` process with bubblewrap. However, when we're doing profiling or measuring coverage, we want to exit cleanly so that profiling data can be recorded, which is done in an atexit() hook. In this situation, bypass the execve() optimization; instead, start bubblewrap in the background, immediately wait for it, and propagate its exit status. Signed-off-by: Simon McVittie --- Makefile.am | 2 +- common/flatpak-run.c | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 29505eee..2082113f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -210,7 +210,7 @@ AM_DISTCHECK_CONFIGURE_FLAGS = \ coverage: $(AM_V_GEN) $(MAKE) $(AM_MAKEFLAGS) lcov-clean - $(AM_V_GEN) $(MAKE) check + $(AM_V_GEN) FLATPAK_TEST_COVERAGE=1 $(MAKE) check $(AM_V_GEN) $(MAKE) $(AM_MAKEFLAGS) genlcov lcov-clean: diff --git a/common/flatpak-run.c b/common/flatpak-run.c index 2eca4c98..7039854e 100644 --- a/common/flatpak-run.c +++ b/common/flatpak-run.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -4489,7 +4490,8 @@ flatpak_run_app (FlatpakDecomposed *app_ref, commandline = flatpak_quote_argv ((const char **) bwrap->argv->pdata, -1); g_debug ("Running '%s'", commandline); - if ((flags & FLATPAK_RUN_FLAG_BACKGROUND) != 0) + if ((flags & (FLATPAK_RUN_FLAG_BACKGROUND)) != 0 || + g_getenv ("FLATPAK_TEST_COVERAGE") != NULL) { GPid child_pid; char pid_str[64]; @@ -4497,7 +4499,8 @@ flatpak_run_app (FlatpakDecomposed *app_ref, GSpawnFlags spawn_flags; spawn_flags = G_SPAWN_SEARCH_PATH; - if (flags & FLATPAK_RUN_FLAG_DO_NOT_REAP) + if (flags & FLATPAK_RUN_FLAG_DO_NOT_REAP || + (flags & FLATPAK_RUN_FLAG_BACKGROUND) == 0) spawn_flags |= G_SPAWN_DO_NOT_REAP_CHILD; /* We use LEAVE_DESCRIPTORS_OPEN to work around dead-lock, see flatpak_close_fds_workaround */ @@ -4521,6 +4524,22 @@ flatpak_run_app (FlatpakDecomposed *app_ref, g_snprintf (pid_str, sizeof (pid_str), "%d", child_pid); pid_path = g_build_filename (instance_id_host_dir, "pid", NULL); g_file_set_contents (pid_path, pid_str, -1, NULL); + + if ((flags & (FLATPAK_RUN_FLAG_BACKGROUND)) == 0) + { + int wait_status; + + if (waitpid (child_pid, &wait_status, 0) != child_pid) + return glnx_throw_errno_prefix (error, "Failed to wait for child process"); + + if (WIFEXITED (wait_status)) + exit (WEXITSTATUS (wait_status)); + + if (WIFSIGNALED (wait_status)) + exit (128 + WTERMSIG (wait_status)); + + return glnx_throw (error, "Unknown wait status from waitpid(): %d", wait_status); + } } else {