Move two global flags to tracee scope
A simultaneous use of -p option and tracing of a command available since commit v4.11-183-gfa8c286 introduces a race condition because the flags whether the first exec has happened are global. Fix the race by moving hide_log_until_execve and hide_log_until_execve global variables to TCB_HIDE_LOG and TCB_SKIP_DETACH_ON_FIRST_EXEC bits in struct tcb.flags, correspondingly. * defs.h (TCB_HIDE_LOG, TCB_SKIP_DETACH_ON_FIRST_EXEC, hide_log): New macros. (hide_log_until_execve): Remove prototype. * strace.c (skip_one_b_execve, hide_log_until_execve): Remove. (startup_child): Set TCB_HIDE_LOG and TCB_SKIP_DETACH_ON_FIRST_EXEC bits in the allocated tcb structure. (init): Remove initialization of hide_log_until_execve and skip_one_b_execve. (print_stopped): Use hide_log() instead of hide_log_until_execve. (trace): Check and clear TCB_SKIP_DETACH_ON_FIRST_EXEC flag instead of skip_one_b_execve. * syscall.c (trace_syscall_entering): Clear TCB_HIDE_LOG flag instead of hide_log_until_execve. (trace_syscall_entering, trace_syscall_exiting): Check hide_log() instead of hide_log_until_execve.
This commit is contained in:
parent
7910ac9638
commit
634a6a55e8
4
defs.h
4
defs.h
@ -280,6 +280,8 @@ struct tcb {
|
||||
#define TCB_REPRINT 0x10 /* We should reprint this syscall on exit */
|
||||
#define TCB_FILTERED 0x20 /* This system call has been filtered out */
|
||||
#define TCB_FAULT_INJ 0x40 /* A syscall fault has been injected */
|
||||
#define TCB_HIDE_LOG 0x80 /* We should hide everything (until execve) */
|
||||
#define TCB_SKIP_DETACH_ON_FIRST_EXEC 0x100 /* -b execve should skip detach on first execve */
|
||||
|
||||
/* qualifier flags */
|
||||
#define QUAL_TRACE 0x001 /* this system call should be traced */
|
||||
@ -300,6 +302,7 @@ typedef uint8_t qualbits_t;
|
||||
#define verbose(tcp) ((tcp)->qual_flg & QUAL_VERBOSE)
|
||||
#define abbrev(tcp) ((tcp)->qual_flg & QUAL_ABBREV)
|
||||
#define filtered(tcp) ((tcp)->flags & TCB_FILTERED)
|
||||
#define hide_log(tcp) ((tcp)->flags & TCB_HIDE_LOG)
|
||||
|
||||
#include "xlat.h"
|
||||
|
||||
@ -399,7 +402,6 @@ extern bool count_wallclock;
|
||||
extern unsigned int qflag;
|
||||
extern bool not_failing_only;
|
||||
extern unsigned int show_fd_path;
|
||||
extern bool hide_log_until_execve;
|
||||
/* are we filtering traces based on paths? */
|
||||
extern const char **paths_selected;
|
||||
#define tracing_paths (paths_selected != NULL)
|
||||
|
30
strace.c
30
strace.c
@ -133,10 +133,6 @@ bool not_failing_only = 0;
|
||||
unsigned int show_fd_path = 0;
|
||||
|
||||
static bool detach_on_execve = 0;
|
||||
/* Are we "strace PROG" and need to skip detach on first execve? */
|
||||
static bool skip_one_b_execve = 0;
|
||||
/* Are we "strace PROG" and need to hide everything until execve? */
|
||||
bool hide_log_until_execve = 0;
|
||||
|
||||
static int exit_code;
|
||||
static int strace_child = 0;
|
||||
@ -1418,17 +1414,17 @@ startup_child(char **argv)
|
||||
kill(pid, SIGCONT);
|
||||
}
|
||||
tcp = alloctcb(pid);
|
||||
if (!NOMMU_SYSTEM)
|
||||
tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
|
||||
else
|
||||
tcp->flags |= TCB_ATTACHED | TCB_STARTUP;
|
||||
tcp->flags |= TCB_ATTACHED | TCB_STARTUP
|
||||
| TCB_SKIP_DETACH_ON_FIRST_EXEC
|
||||
| (NOMMU_SYSTEM ? 0 : (TCB_HIDE_LOG | post_attach_sigstop));
|
||||
newoutf(tcp);
|
||||
}
|
||||
else {
|
||||
/* With -D, we are *child* here, the tracee is our parent. */
|
||||
strace_child = strace_tracer_pid;
|
||||
strace_tracer_pid = getpid();
|
||||
alloctcb(strace_child);
|
||||
tcp = alloctcb(strace_child);
|
||||
tcp->flags |= TCB_SKIP_DETACH_ON_FIRST_EXEC | TCB_HIDE_LOG;
|
||||
/* attaching will be done later, by startup_attach */
|
||||
/* note: we don't do newoutf(tcp) here either! */
|
||||
|
||||
@ -1859,9 +1855,6 @@ init(int argc, char *argv[])
|
||||
* in the startup_child() mode we kill the spawned process anyway.
|
||||
*/
|
||||
if (argv[0]) {
|
||||
if (!NOMMU_SYSTEM || daemonized_tracer)
|
||||
hide_log_until_execve = 1;
|
||||
skip_one_b_execve = 1;
|
||||
startup_child(argv);
|
||||
}
|
||||
|
||||
@ -2130,7 +2123,7 @@ static void
|
||||
print_stopped(struct tcb *tcp, const siginfo_t *si, const unsigned int sig)
|
||||
{
|
||||
if (cflag != CFLAG_ONLY_STATS
|
||||
&& !hide_log_until_execve
|
||||
&& !hide_log(tcp)
|
||||
&& (qual_flags[sig] & QUAL_SIGNAL)
|
||||
) {
|
||||
printleader(tcp);
|
||||
@ -2266,11 +2259,14 @@ trace(void)
|
||||
if (os_release >= KERNEL_VERSION(3,0,0))
|
||||
tcp = maybe_switch_tcbs(tcp, pid);
|
||||
|
||||
if (detach_on_execve && !skip_one_b_execve) {
|
||||
detach(tcp); /* do "-b execve" thingy */
|
||||
return true;
|
||||
if (detach_on_execve) {
|
||||
if (tcp->flags & TCB_SKIP_DETACH_ON_FIRST_EXEC) {
|
||||
tcp->flags &= ~TCB_SKIP_DETACH_ON_FIRST_EXEC;
|
||||
} else {
|
||||
detach(tcp); /* do "-b execve" thingy */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
skip_one_b_execve = 0;
|
||||
}
|
||||
|
||||
/* Set current output file */
|
||||
|
@ -1107,7 +1107,7 @@ trace_syscall_entering(struct tcb *tcp)
|
||||
#if defined SPARC || defined SPARC64
|
||||
case SEN_execv:
|
||||
#endif
|
||||
hide_log_until_execve = 0;
|
||||
tcp->flags &= ~TCB_HIDE_LOG;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1121,7 +1121,7 @@ trace_syscall_entering(struct tcb *tcp)
|
||||
|
||||
tcp->flags &= ~TCB_FILTERED;
|
||||
|
||||
if (hide_log_until_execve) {
|
||||
if (hide_log(tcp)) {
|
||||
res = 0;
|
||||
goto ret;
|
||||
}
|
||||
@ -1188,7 +1188,7 @@ trace_syscall_exiting(struct tcb *tcp)
|
||||
update_personality(tcp, tcp->currpers);
|
||||
#endif
|
||||
res = (get_regs_error ? -1 : get_syscall_result(tcp));
|
||||
if (filtered(tcp) || hide_log_until_execve)
|
||||
if (filtered(tcp) || hide_log(tcp))
|
||||
goto ret;
|
||||
|
||||
if (syserror(tcp) && syscall_fault_injected(tcp))
|
||||
|
Loading…
x
Reference in New Issue
Block a user