[PATCH] decode fcntl's F_{GET, SET}LEASE, F_NOTIFY, and F_DUPFD_CLOEXEC

Mike Frysinger vapier at gentoo.org
Tue Mar 10 09:48:25 UTC 2009


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>
---
 desc.c |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/desc.c b/desc.c
index 139b1e6..7c441b7 100644
--- a/desc.c
+++ b/desc.c
@@ -148,6 +148,18 @@ static const struct xlat fcntlcmds[] = {
 #ifdef F_UNSHARE
 	{ F_UNSHARE,	"F_UNSHARE"	},
 #endif
+#ifdef F_SETLEASE
+	{ F_SETLEASE,	"F_SETLEASE"	},
+#endif
+#ifdef F_GETLEASE
+	{ F_GETLEASE,	"F_GETLEASE"	},
+#endif
+#ifdef F_NOTIFY
+	{ F_NOTIFY,	"F_NOTIFY"	},
+#endif
+#ifdef F_DUPFD_CLOEXEC
+	{ F_DUPFD_CLOEXEC,	"F_DUPFD_CLOEXEC"	},
+#endif
 	{ 0,		NULL		},
 };
 
@@ -183,6 +195,33 @@ static const struct xlat lockfcmds[] = {
 	{ 0,		NULL		},
 };
 
+#ifdef F_NOTIFY
+static const struct xlat notifyflags[] = {
+#ifdef DN_ACCESS
+	{ DN_ACCESS,	"DN_ACCESS"	},
+#endif
+#ifdef DN_MODIFY
+	{ DN_MODIFY,	"DN_MODIFY"	},
+#endif
+#ifdef DN_CREATE
+	{ DN_CREATE,	"DN_CREATE"	},
+#endif
+#ifdef DN_DELETE
+	{ DN_DELETE,	"DN_DELETE"	},
+#endif
+#ifdef DN_RENAME
+	{ DN_RENAME,	"DN_RENAME"	},
+#endif
+#ifdef DN_ATTRIB
+	{ DN_ATTRIB,	"DN_ATTRIB"	},
+#endif
+#ifdef DN_MULTISHOT
+	{ DN_MULTISHOT,	"DN_MULTISHOT"	},
+#endif
+	{ 0,		NULL		},
+};
+#endif
+
 static const struct xlat whence[] = {
 	{ SEEK_SET,	"SEEK_SET"	},
 	{ SEEK_CUR,	"SEEK_CUR"	},
@@ -307,6 +346,9 @@ sys_fcntl(struct tcb *tcp)
 			printflags(fdflags, tcp->u_arg[2], "FD_???");
 			break;
 		case F_SETOWN: case F_DUPFD:
+#ifdef F_DUPFD_CLOEXEC
+		case F_DUPFD_CLOEXEC:
+#endif
 			tprintf(", %ld", tcp->u_arg[2]);
 			break;
 		case F_SETFL:
@@ -336,14 +378,35 @@ sys_fcntl(struct tcb *tcp)
 			printflock64(tcp, tcp->u_arg[2], 0);
 			break;
 #endif
+#ifdef F_NOTIFY
+		case F_NOTIFY:
+			tprintf(", ");
+			printflags(notifyflags, tcp->u_arg[2], "DN_???");
+			break;
+#endif
+#ifdef F_SETLEASE
+		case F_SETLEASE:
+			tprintf(", ");
+			printxval(lockfcmds, tcp->u_arg[2], "F_???");
+			break;
+#endif
 		}
 	}
 	else {
 		switch (tcp->u_arg[1]) {
 		case F_DUPFD:
+#ifdef F_DUPFD_CLOEXEC
+		case F_DUPFD_CLOEXEC:
+#endif
 		case F_SETFD: case F_SETFL:
 		case F_SETLK: case F_SETLKW:
 		case F_SETOWN: case F_GETOWN:
+#ifdef F_NOTIFY
+		case F_NOTIFY:
+#endif
+#ifdef F_SETLEASE
+		case F_SETLEASE:
+#endif
 			break;
 		case F_GETFD:
 			if (syserror(tcp) || tcp->u_rval == 0)
@@ -368,6 +431,13 @@ sys_fcntl(struct tcb *tcp)
 			printflock64(tcp, tcp->u_arg[2], 1);
 			break;
 #endif
+#ifdef F_GETLEASE
+		case F_GETLEASE:
+			if (syserror(tcp))
+				return 0;
+			tcp->auxstr = xlookup(lockfcmds, tcp->u_rval);
+			return RVAL_HEX|RVAL_STR;
+#endif
 		default:
 			tprintf(", %#lx", tcp->u_arg[2]);
 			break;
-- 
1.6.2





More information about the Strace-devel mailing list