When trace-cmd runs a command, specified with the "-F" flag, it forks a child process and executes the command in its context. This child process receives a full copy of the parents memory at the moment of fork(). When it modifies this copy, the parent memory is not affected. Calling the function update_task_filter() in the child context will operate on a valid data, but will not update anything in the parent's databases. Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@xxxxxxxxx> --- tracecmd/trace-record.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c index 1e4d38fa..2b5cd42a 100644 --- a/tracecmd/trace-record.c +++ b/tracecmd/trace-record.c @@ -11,6 +11,7 @@ #include <stdarg.h> #include <getopt.h> #include <time.h> +#include <semaphore.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> @@ -1487,18 +1488,35 @@ static int change_user(const char *user) return 0; } +#define TRACE_RUN_SEM "trace_cmd_semaphore_run" +#define TRACE_INIT_SEM "trace_cmd_semaphore_init" static void run_cmd(enum trace_type type, const char *user, int argc, char **argv) { + sem_t *sem_init; + sem_t *sem_run; int status; int pid; + sem_init = sem_open(TRACE_INIT_SEM, O_CREAT, S_IRUSR|S_IWUSR, 0); + if (sem_init == SEM_FAILED) + die("failed to init trace_cmd init semaphore"); + + sem_run = sem_open(TRACE_RUN_SEM, O_CREAT, S_IRUSR|S_IWUSR, 0); + if (sem_run == SEM_FAILED) { + sem_close(sem_init); + sem_unlink(TRACE_INIT_SEM); + die("failed to init trace_cmd run semaphore"); + } + if ((pid = fork()) < 0) die("failed to fork"); if (!pid) { /* child */ - update_task_filter(); + sem_wait(sem_init); tracecmd_enable_tracing(); enable_ptrace(); + sem_post(sem_run); + /* * If we are using stderr for stdout, switch * it back to the saved stdout for the code we run. @@ -1519,11 +1537,17 @@ static void run_cmd(enum trace_type type, const char *user, int argc, char **arg die("Failed to exec %s", argv[0]); } } - if (do_ptrace) { - add_filter_pid(pid, 0); - ptrace_attach(pid); + update_task_filter(); + sem_post(sem_init); + sem_wait(sem_run); + sem_close(sem_init); + sem_unlink(TRACE_INIT_SEM); + sem_close(sem_run); + sem_unlink(TRACE_RUN_SEM); + + if (do_ptrace) ptrace_wait(type); - } else + else trace_waitpid(type, pid, &status, 0); } -- 2.25.4