[PATCH] decode fcntl's F_{GET, SET}LEASE, F_NOTIFY, and F_DUPFD_CLOEXEC
Denys Vlasenko
dvlasenk at redhat.com
Tue Mar 10 20:47:53 UTC 2009
On Tue, 2009-03-10 at 05:48 -0400, Mike Frysinger wrote:
> I was tracing an app that was trying to do dnotify calls, but this was
> hard to deduce at first because all I got was:
> fcntl(11, 0x402 /* F_??? */, 0x8000000e) = -1 EINVAL (Invalid argument)
> Which made me think that the code was doing something broken (since the
> fields we not being decoded). Once I found out 0x402 is actually a valid
> fcntl command for Linux, I took a stab at fixing strace.
>
> F_DUPFD_CLOEXEC is just like F_DUPFD. The LEASE funcs are easy becuase
> we can reuse lockfcmds. F_NOTIFY required a little more work as it has
> its own array of unique flags.
>
> Now I get a nicely decoded trace:
> fcntl(11, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_DELETE|DN_MULTISHOT) = -1 EINVAL (Invalid argument)
>
> Signed-off-by: Mike Frysinger <vapier at gentoo.org>
Applied to cvs as "obviously better than before" category :)
Thanks Mike.
Noticed that we have two places for generation of O_xxx|O_yyy
strings, and merged them into one. Run tested.
Changelog and patch are below.
--
vda
Optimize printing of open modes.
* defs.h: Declare sprint_open_modes(),
remove unused parameter in tprint_open_modes().
* desc.c (sprint_open_modes): Move fuction definition from here...
* file.c (sprint_open_modes): To here.
(tprint_open_modes): Use sprint_open_modes(), it already
generates needed string.
* ipc.c: Remove unused parameter from calls
to tprint_open_modes().
diff -d -urpN strace.7/defs.h strace.8/defs.h
--- strace.7/defs.h 2009-03-10 21:44:24.000000000 +0100
+++ strace.8/defs.h 2009-03-10 21:01:48.000000000 +0100
@@ -534,7 +534,8 @@ extern void printtrailer P((void));
extern void tabto P((int));
extern void call_summary P((FILE *));
extern void tprint_iov P((struct tcb *, unsigned long, unsigned long));
-extern void tprint_open_modes P((struct tcb *, mode_t));
+extern void tprint_open_modes P((mode_t));
+extern const char *sprint_open_modes P((mode_t));
extern int is_restart_error P((struct tcb *));
extern int change_syscall P((struct tcb *, int));
diff -d -urpN strace.7/desc.c strace.8/desc.c
--- strace.7/desc.c 2009-03-10 21:44:37.000000000 +0100
+++ strace.8/desc.c 2009-03-10 21:00:30.000000000 +0100
@@ -300,40 +300,6 @@ printflock64(struct tcb *tcp, long addr,
}
#endif
-/*
- * low bits of the open(2) flags define access mode,
- * other bits are real flags.
- */
-static const char *
-sprint_open_modes(mode_t flags)
-{
- static char outstr[1024];
- const char *str = xlookup(open_access_modes, flags & 3);
- const char *sep = "";
- const struct xlat *x;
-
- strcpy(outstr, "flags ");
- if (str) {
- strcat(outstr, str);
- flags &= ~3;
- if (!flags)
- return outstr;
- strcat(outstr, "|");
- }
-
- for (x = open_mode_flags; x->str; x++) {
- if ((flags & x->val) == x->val) {
- sprintf(outstr + strlen(outstr),
- "%s%s", sep, x->str);
- sep = "|";
- flags &= ~x->val;
- }
- }
- if (flags)
- sprintf(outstr + strlen(outstr), "%s%#x", sep, flags);
- return outstr;
-}
-
int
sys_fcntl(struct tcb *tcp)
{
@@ -353,7 +319,7 @@ sys_fcntl(struct tcb *tcp)
break;
case F_SETFL:
tprintf(", ");
- tprint_open_modes(tcp, tcp->u_arg[2]);
+ tprint_open_modes(tcp->u_arg[2]);
break;
case F_SETLK: case F_SETLKW:
#ifdef F_FREESP
diff -d -urpN strace.7/file.c strace.8/file.c
--- strace.7/file.c 2009-03-10 21:44:24.000000000 +0100
+++ strace.8/file.c 2009-03-10 21:19:34.000000000 +0100
@@ -239,7 +239,7 @@ const struct xlat open_mode_flags[] = {
#ifdef O_RSYNC
{ O_RSYNC, "O_RSYNC" },
#endif
-#ifdef O_NDELAY
+#if defined(O_NDELAY) && (O_NDELAY != O_NONBLOCK)
{ O_NDELAY, "O_NDELAY" },
#endif
#ifdef O_PRIV
@@ -339,23 +339,61 @@ print_dirfd(long fd)
#endif
/*
+ * Pity stpcpy() is not standardized...
+ */
+static char *
+str_append(char *dst, const char *src)
+{
+ while ((*dst = *src++) != '\0')
+ dst++;
+ return dst;
+}
+
+/*
* low bits of the open(2) flags define access mode,
* other bits are real flags.
*/
-void
-tprint_open_modes(struct tcb *tcp, mode_t flags)
+const char *
+sprint_open_modes(mode_t flags)
{
- const char *str = xlookup(open_access_modes, flags & 3);
+ static char outstr[1024];
+ char *p;
+ char sep = 0;
+ const char *str;
+ const struct xlat *x;
- if (str)
- {
- tprintf("%s", str);
+ p = str_append(outstr, "flags ");
+ str = xlookup(open_access_modes, flags & 3);
+ if (str) {
+ p = str_append(p, str);
flags &= ~3;
if (!flags)
- return;
- tprintf("|");
+ return outstr;
+ sep = '|';
}
- printflags(open_mode_flags, flags, "O_???");
+
+ for (x = open_mode_flags; x->str; x++) {
+ if ((flags & x->val) == x->val) {
+ if (sep)
+ *p++ = sep;
+ p = str_append(p, x->str);
+ flags &= ~x->val;
+ if (!flags)
+ return outstr;
+ sep = '|';
+ }
+ }
+ /* flags is still nonzero */
+ if (sep)
+ *p++ = sep;
+ sprintf(p, "%#x", flags);
+ return outstr;
+}
+
+void
+tprint_open_modes(mode_t flags)
+{
+ tprintf(sprint_open_modes(flags) + sizeof("flags"));
}
static int
@@ -365,7 +403,7 @@ decode_open(struct tcb *tcp, int offset)
printpath(tcp, tcp->u_arg[offset]);
tprintf(", ");
/* flags */
- tprint_open_modes(tcp, tcp->u_arg[offset + 1]);
+ tprint_open_modes(tcp->u_arg[offset + 1]);
if (tcp->u_arg[offset + 1] & O_CREAT) {
/* mode */
tprintf(", %#lo", tcp->u_arg[offset + 2]);
diff -d -urpN strace.7/ipc.c strace.8/ipc.c
--- strace.7/ipc.c 2009-03-10 21:44:24.000000000 +0100
+++ strace.8/ipc.c 2009-03-10 21:00:40.000000000 +0100
@@ -420,7 +420,7 @@ sys_mq_open(struct tcb *tcp)
printpath(tcp, tcp->u_arg[0]);
tprintf(", ");
/* flags */
- tprint_open_modes(tcp, tcp->u_arg[1]);
+ tprint_open_modes(tcp->u_arg[1]);
if (tcp->u_arg[1] & O_CREAT) {
# ifndef HAVE_MQUEUE_H
tprintf(", %lx", tcp->u_arg[2]);
@@ -489,7 +489,7 @@ printmqattr(struct tcb *tcp, long addr)
return;
}
tprintf("{mq_flags=");
- tprint_open_modes(tcp, attr.mq_flags);
+ tprint_open_modes(attr.mq_flags);
tprintf(", mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsg=%ld}",
attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
# endif
More information about the Strace-devel
mailing list