[PATCH 2/2] Implement -eread=@path and -ewrite=@path option

JingPiao Chen chenjingpiao at gmail.com
Tue Apr 18 11:05:16 UTC 2017


* defs.h (readpath_select, readpath_match): New prototypes.
(writepath_select, writepath_match): Likewise.
* pathtrace.c (readpath_select, readpath_match): New functions.
(writepath_select, writepath_match): Likewise.
(path_select): Add syntax check.
* qualify.c (qualify_read): Use readpath_select.
(qualify_write): Use writepath_select.
* syscall.c (dumpio): Use readpath_match and writepath_match.
* NEWS: Mention -eread=@path and -ewrite=@path option.
* strace.1: Document -eread=@path and -ewrite=@path option.
* tests/read-write.test: Add check for -eread=@path and -ewrite=@path option.
* tests/options-syntax.test: Add check for invalid path.
---
FeatureRequests: Path tracing for -e read/write.
perform a full hexadecimal and ASCII dump of all the
data read from/written to the path.

Usage:
Only one path
$ strace -eread=@path
More then one path
$ strace -eread=@path1 -eread=@path2
Invalid usage:
$ strace -eread=!@path
$ strace -eread=@path, at path

 NEWS                      |  2 ++
 defs.h                    |  4 ++++
 pathtrace.c               | 31 +++++++++++++++++++++++++++++++
 qualify.c                 | 10 ++++++++--
 strace.1                  |  6 ++++++
 syscall.c                 |  5 ++---
 tests/options-syntax.test |  2 ++
 tests/read-write.test     |  4 ++++
 8 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index e4ab578..0f91a79 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,8 @@ Noteworthy changes in release ?.?? (????-??-??)
     syscalls.
   * Added -e trace=/regex option for filtering syscalls using regular
     expressions.
+  * Added -eread=@path and -ewrite=@path perform a full hexadecimal and ASCII
+    dump of all the data read from/written to the path.
   * Implemented decoding of signal mask in rt_sigreturn syscall on alpha, arc,
     arm, avr32, bfin, cris, hppa, m68k, metag, microblaze, mips, nios2, or1k,
     powerpc, powerpc64, riscv, sh, sh64, sparc, sparc64, tile, x86, and xtensa
diff --git a/defs.h b/defs.h
index d16eb41..c884615 100644
--- a/defs.h
+++ b/defs.h
@@ -492,6 +492,10 @@ extern long getrval2(struct tcb *);
 extern const char *signame(const int);
 extern void pathtrace_select(const char *);
 extern int pathtrace_match(struct tcb *);
+extern void readpath_select(const char *);
+extern int readpath_match(struct tcb *, int fd);
+extern void writepath_select(const char *);
+extern int writepath_match(struct tcb *, int fd);
 extern int getfdpath(struct tcb *, int, char *, unsigned);
 extern enum sock_proto getfdproto(struct tcb *, int);
 
diff --git a/pathtrace.c b/pathtrace.c
index 82a32e4..b892b22 100644
--- a/pathtrace.c
+++ b/pathtrace.c
@@ -38,6 +38,8 @@ struct path_set {
 };
 
 static struct path_set pathtrace_set = { NULL, 0 };
+static struct path_set readpath_set = { NULL, 0 };
+static struct path_set writepath_set = { NULL, 0 };
 
 /*
  * Return true if specified path matches one that we're tracing.
@@ -124,6 +126,9 @@ getfdpath(struct tcb *tcp, int fd, char *buf, unsigned bufsize)
 static void
 path_select(const char *path, struct path_set *set)
 {
+	if (*path == '\0')
+		error_msg_and_die("invalid path '%s'", path);
+
 	char *rpath;
 
 	storepath(path, set);
@@ -392,3 +397,29 @@ pathtrace_match(struct tcb *tcp)
 
 	return 0;
 }
+
+void
+readpath_select(const char *path)
+{
+	path_select(path, &readpath_set);
+}
+
+int
+readpath_match(struct tcb *tcp, int fd)
+{
+	return readpath_set.paths_selected != NULL
+	       && fdmatch(tcp, fd, &readpath_set);
+}
+
+void
+writepath_select(const char *path)
+{
+	path_select(path, &writepath_set);
+}
+
+int
+writepath_match(struct tcb *tcp, int fd)
+{
+	return writepath_set.paths_selected != NULL
+	       && fdmatch(tcp, fd, &writepath_set);
+}
diff --git a/qualify.c b/qualify.c
index a13b169..6b2fca8 100644
--- a/qualify.c
+++ b/qualify.c
@@ -519,13 +519,19 @@ parse_error:
 static void
 qualify_read(const char *const str)
 {
-	qualify_tokens(str, &read_set, string_to_uint, "descriptor");
+	if (*str == '@')
+		readpath_select(str + 1);
+	else
+		qualify_tokens(str, &read_set, string_to_uint, "descriptor");
 }
 
 static void
 qualify_write(const char *const str)
 {
-	qualify_tokens(str, &write_set, string_to_uint, "descriptor");
+	if (*str == '@')
+		writepath_select(str + 1);
+	else
+		qualify_tokens(str, &write_set, string_to_uint, "descriptor");
 }
 
 static void
diff --git a/strace.1 b/strace.1
index 2efa370..8408575 100644
--- a/strace.1
+++ b/strace.1
@@ -481,6 +481,9 @@ Note that this is independent from the normal tracing of the
 system call which is controlled by the option
 .BR -e "\ " trace = read .
 .TP
+\fB\-e\ read\fR=@\,\fIpath\fR
+Perform a full hexadecimal and ASCII dump of all the data read from the path.
+.TP
 \fB\-e\ write\fR=\,\fIset\fR
 Perform a full hexadecimal and ASCII dump of all the data written to
 file descriptors listed in the specified set.  For example, to see
@@ -495,6 +498,9 @@ Note that this is independent from the normal tracing of the
 system call which is controlled by the option
 .BR -e "\ " trace = write .
 .TP
+\fB\-e\ write\fR=@\,\fIpath\fR
+Perform a full hexadecimal and ASCII dump of all the data written to the path.
+.TP
 \fB\-e\ inject\fR=\,\fIset\/\fR[:\fBerror\fR=\,\fIerrno\/\fR|:\fBretval\fR=\,\fIvalue\/\fR][:\fBsignal\fR=\,\fIsig\/\fR][:\fBwhen\fR=\,\fIexpr\/\fR]
 Perform syscall tampering for the specified set of syscalls.
 
diff --git a/syscall.c b/syscall.c
index 3e91880..ee743bf 100644
--- a/syscall.c
+++ b/syscall.c
@@ -454,8 +454,7 @@ dumpio(struct tcb *tcp)
 	int fd = tcp->u_arg[0];
 	if (fd < 0)
 		return;
-
-	if (is_number_in_set(fd, &read_set)) {
+	if (is_number_in_set(fd, &read_set) || readpath_match(tcp, fd)) {
 		switch (tcp->s_ent->sen) {
 		case SEN_read:
 		case SEN_pread:
@@ -478,7 +477,7 @@ dumpio(struct tcb *tcp)
 			return;
 		}
 	}
-	if (is_number_in_set(fd, &write_set)) {
+	if (is_number_in_set(fd, &write_set) || writepath_match(tcp, fd)) {
 		switch (tcp->s_ent->sen) {
 		case SEN_write:
 		case SEN_pwrite:
diff --git a/tests/options-syntax.test b/tests/options-syntax.test
index a9fe710..d6e9ed9 100755
--- a/tests/options-syntax.test
+++ b/tests/options-syntax.test
@@ -107,6 +107,8 @@ check_e "invalid descriptor ','" -eread=,
 check_e "invalid descriptor '!'" -ewrite='!'
 check_e "invalid descriptor '!'" -eread='0,!'
 check_e "invalid descriptor '!,'" -ewrite='!,'
+check_e "invalid path ''" -eread=@
+check_e "invalid path ''" -ewrite=@
 
 check_e_using_grep 'regcomp: \+id: [[:alpha:]].+' -e trace='/+id'
 check_e_using_grep 'regcomp: \*id: [[:alpha:]].+' -e trace='/*id'
diff --git a/tests/read-write.test b/tests/read-write.test
index 29bb4dc..287fa28 100755
--- a/tests/read-write.test
+++ b/tests/read-write.test
@@ -13,3 +13,7 @@ tmpfile=read-write-tmpfile
 run_strace_match_diff \
 	-a15 -eread=0 -ewrite=1 -e trace=read,write \
 	-P $tmpfile -P /dev/zero -P /dev/null
+run_strace_match_diff \
+	-a15 -eread=@$tmpfile -eread=@/dev/zero \
+	-ewrite=@$tmpfile -ewrite=@/dev/null -e trace=read,write \
+	-P $tmpfile -P /dev/zero -P /dev/null
-- 
2.7.4





More information about the Strace-devel mailing list