[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