* defs.h (paths_selected): Remove the declaration. (tracing_paths): Replace the macro with a global variable. * strace.c (tracing_paths): New global variable. (init): Adjust -P option handler. * pathtrace.c (pathmatch): Add a parameter of type struct path_set. (upathmatch, fdmatch, storepath): Likewise. (path_select, pathtrace_fdmatch, pathtrace_upathmatch): New functions. (pathtrace_select): Use path_select. (pathtrace_match): Change upathmatch to pathtrace_upathmatch and change fdmath to pathtrace_fdmatch. --- defs.h | 3 +- pathtrace.c | 118 ++++++++++++++++++++++++++++++++++++------------------------ strace.c | 3 ++ 3 files changed, 75 insertions(+), 49 deletions(-)
diff --git a/defs.h b/defs.h index 9c0518d..d16eb41 100644 --- a/defs.h +++ b/defs.h @@ -372,8 +372,7 @@ extern unsigned int qflag; extern bool not_failing_only; extern unsigned int show_fd_path; /* are we filtering traces based on paths? */ -extern const char **paths_selected; -#define tracing_paths (paths_selected != NULL) +extern bool tracing_paths; extern unsigned xflag; extern unsigned followfork; #ifdef USE_LIBUNWIND diff --git a/pathtrace.c b/pathtrace.c index 90974f4..82a32e4 100644 --- a/pathtrace.c +++ b/pathtrace.c @@ -32,19 +32,23 @@ #include "syscall.h" -const char **paths_selected = NULL; -static unsigned num_selected = 0; +struct path_set { + const char **paths_selected; + unsigned num_selected; +}; + +static struct path_set pathtrace_set = { NULL, 0 }; /* * Return true if specified path matches one that we're tracing. */ static int -pathmatch(const char *path) +pathmatch(const char *path, struct path_set *set) { unsigned i; - for (i = 0; i < num_selected; ++i) { - if (strcmp(path, paths_selected[i]) == 0) + for (i = 0; i < set->num_selected; ++i) { + if (strcmp(path, set->paths_selected[i]) == 0) return 1; } return 0; @@ -54,24 +58,25 @@ pathmatch(const char *path) * Return true if specified path (in user-space) matches. */ static int -upathmatch(struct tcb *const tcp, const kernel_ulong_t upath) +upathmatch(struct tcb *const tcp, const kernel_ulong_t upath, + struct path_set *set) { char path[PATH_MAX + 1]; return umovestr(tcp, upath, sizeof path, path) > 0 && - pathmatch(path); + pathmatch(path, set); } /* * Return true if specified fd maps to a path we're tracing. */ static int -fdmatch(struct tcb *tcp, int fd) +fdmatch(struct tcb *tcp, int fd, struct path_set *set) { char path[PATH_MAX + 1]; int n = getfdpath(tcp, fd, path, sizeof(path)); - return n >= 0 && pathmatch(path); + return n >= 0 && pathmatch(path, set); } /* @@ -79,17 +84,18 @@ fdmatch(struct tcb *tcp, int fd) * Specifying NULL will delete all paths. */ static void -storepath(const char *path) +storepath(const char *path, struct path_set *set) { unsigned i; - if (pathmatch(path)) + if (pathmatch(path, set)) return; /* already in table */ - i = num_selected++; - paths_selected = xreallocarray(paths_selected, num_selected, - sizeof(paths_selected[0])); - paths_selected[i] = path; + i = set->num_selected++; + set->paths_selected = xreallocarray(set->paths_selected, + set->num_selected, + sizeof(set->paths_selected[0])); + set->paths_selected[i] = path; } /* @@ -115,16 +121,12 @@ getfdpath(struct tcb *tcp, int fd, char *buf, unsigned bufsize) return n; } -/* - * Add a path to the set we're tracing. Also add the canonicalized - * version of the path. Secifying NULL will delete all paths. - */ -void -pathtrace_select(const char *path) +static void +path_select(const char *path, struct path_set *set) { char *rpath; - storepath(path); + storepath(path, set); rpath = realpath(path, NULL); @@ -138,7 +140,29 @@ pathtrace_select(const char *path) } error_msg("Requested path '%s' resolved into '%s'", path, rpath); - storepath(rpath); + storepath(rpath, set); +} + +/* + * Add a path to the set we're tracing. Also add the canonicalized + * version of the path. Secifying NULL will delete all paths. + */ +void +pathtrace_select(const char *path) +{ + path_select(path, &pathtrace_set); +} + +static int +pathtrace_upathmatch(struct tcb *const tcp, const kernel_ulong_t upath) +{ + return upathmatch(tcp, upath, &pathtrace_set); +} + +static int +pathtrace_fdmatch(struct tcb *tcp, int fd) +{ + return fdmatch(tcp, fd, &pathtrace_set); } /* @@ -168,8 +192,8 @@ pathtrace_match(struct tcb *tcp) case SEN_sendfile64: case SEN_tee: /* fd, fd */ - return fdmatch(tcp, tcp->u_arg[0]) || - fdmatch(tcp, tcp->u_arg[1]); + return pathtrace_fdmatch(tcp, tcp->u_arg[0]) || + pathtrace_fdmatch(tcp, tcp->u_arg[1]); case SEN_faccessat: case SEN_fchmodat: @@ -187,28 +211,28 @@ pathtrace_match(struct tcb *tcp) case SEN_unlinkat: case SEN_utimensat: /* fd, path */ - return fdmatch(tcp, tcp->u_arg[0]) || - upathmatch(tcp, tcp->u_arg[1]); + return pathtrace_fdmatch(tcp, tcp->u_arg[0]) || + pathtrace_upathmatch(tcp, tcp->u_arg[1]); case SEN_link: case SEN_mount: case SEN_pivotroot: /* path, path */ - return upathmatch(tcp, tcp->u_arg[0]) || - upathmatch(tcp, tcp->u_arg[1]); + return pathtrace_upathmatch(tcp, tcp->u_arg[0]) || + pathtrace_upathmatch(tcp, tcp->u_arg[1]); case SEN_quotactl: /* x, path */ - return upathmatch(tcp, tcp->u_arg[1]); + return pathtrace_upathmatch(tcp, tcp->u_arg[1]); case SEN_linkat: case SEN_renameat2: case SEN_renameat: /* fd, path, fd, path */ - return fdmatch(tcp, tcp->u_arg[0]) || - fdmatch(tcp, tcp->u_arg[2]) || - upathmatch(tcp, tcp->u_arg[1]) || - upathmatch(tcp, tcp->u_arg[3]); + return pathtrace_fdmatch(tcp, tcp->u_arg[0]) || + pathtrace_fdmatch(tcp, tcp->u_arg[2]) || + pathtrace_upathmatch(tcp, tcp->u_arg[1]) || + pathtrace_upathmatch(tcp, tcp->u_arg[3]); case SEN_old_mmap: #if defined(S390) @@ -219,29 +243,29 @@ pathtrace_match(struct tcb *tcp) case SEN_mmap_pgoff: case SEN_ARCH_mmap: /* x, x, x, x, fd */ - return fdmatch(tcp, tcp->u_arg[4]); + return pathtrace_fdmatch(tcp, tcp->u_arg[4]); case SEN_symlinkat: /* path, fd, path */ - return fdmatch(tcp, tcp->u_arg[1]) || - upathmatch(tcp, tcp->u_arg[0]) || - upathmatch(tcp, tcp->u_arg[2]); + return pathtrace_fdmatch(tcp, tcp->u_arg[1]) || + pathtrace_upathmatch(tcp, tcp->u_arg[0]) || + pathtrace_upathmatch(tcp, tcp->u_arg[2]); case SEN_copy_file_range: case SEN_splice: /* fd, x, fd, x, x, x */ - return fdmatch(tcp, tcp->u_arg[0]) || - fdmatch(tcp, tcp->u_arg[2]); + return pathtrace_fdmatch(tcp, tcp->u_arg[0]) || + pathtrace_fdmatch(tcp, tcp->u_arg[2]); case SEN_epoll_ctl: /* x, x, fd, x */ - return fdmatch(tcp, tcp->u_arg[2]); + return pathtrace_fdmatch(tcp, tcp->u_arg[2]); case SEN_fanotify_mark: /* x, x, x, fd, path */ - return fdmatch(tcp, tcp->u_arg[3]) || - upathmatch(tcp, tcp->u_arg[4]); + return pathtrace_fdmatch(tcp, tcp->u_arg[3]) || + pathtrace_upathmatch(tcp, tcp->u_arg[4]); case SEN_oldselect: case SEN_pselect6: @@ -297,7 +321,7 @@ pathtrace_match(struct tcb *tcp) j = next_set_bit(fds, j, nfds); if (j < 0) break; - if (fdmatch(tcp, j)) { + if (pathtrace_fdmatch(tcp, j)) { free(fds); return 1; } @@ -324,7 +348,7 @@ pathtrace_match(struct tcb *tcp) for (cur = start; cur < end; cur += sizeof(fds)) if ((umove(tcp, cur, &fds) == 0) - && fdmatch(tcp, fds.fd)) + && pathtrace_fdmatch(tcp, fds.fd)) return 1; return 0; @@ -361,10 +385,10 @@ pathtrace_match(struct tcb *tcp) */ if (s->sys_flags & TRACE_FILE) - return upathmatch(tcp, tcp->u_arg[0]); + return pathtrace_upathmatch(tcp, tcp->u_arg[0]); if (s->sys_flags & (TRACE_DESC | TRACE_NETWORK)) - return fdmatch(tcp, tcp->u_arg[0]); + return pathtrace_fdmatch(tcp, tcp->u_arg[0]); return 0; } diff --git a/strace.c b/strace.c index 2933a78..766a288 100644 --- a/strace.c +++ b/strace.c @@ -127,6 +127,8 @@ bool not_failing_only = 0; /* Show path associated with fd arguments */ unsigned int show_fd_path = 0; +bool tracing_paths = false; + static bool detach_on_execve = 0; static int exit_code; @@ -1701,6 +1703,7 @@ init(int argc, char *argv[]) process_opt_p_list(optarg); break; case 'P': + tracing_paths = true; pathtrace_select(optarg); break; case 's': -- 2.7.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel