[PATCH 1/2] Extend path trace related function interface
JingPiao Chen
chenjingpiao at gmail.com
Tue Apr 18 11:05:15 UTC 2017
* 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
More information about the Strace-devel
mailing list