[PATCH v5] Print absolute paths in printpathn when -yy is used

Zubin Mithra zubin.mithra at gmail.com
Sun Aug 24 19:22:12 UTC 2014


Hi Dmitry,

Please find below a diff of the changes for having `renameat` decode paths using oldfd and newfd. Other *at syscalls could be modified similarly. Does this look good?

diff --git a/defs.h b/defs.h
index 4aedee3..97a0c08 100644
--- a/defs.h
+++ b/defs.h
@@ -679,7 +679,9 @@ extern void printstr(struct tcb *, long, long);
 extern void printnum(struct tcb *, long, const char *);
 extern void printnum_int(struct tcb *, long, const char *);
 extern void printpath(struct tcb *, long);
+extern void printpathat(struct tcb *, int, long);
 extern void printpathn(struct tcb *, long, int);
+extern void printpathnat(struct tcb *, int, long, int);
 #define TIMESPEC_TEXT_BUFSIZE (sizeof(long)*3 * 2 + sizeof("{%u, %u}"))
 #define TIMEVAL_TEXT_BUFSIZE  TIMESPEC_TEXT_BUFSIZE
 extern void printtv_bitness(struct tcb *, long, enum bitness_t, int);
diff --git a/file.c b/file.c
index 360408f..f6f6a37 100644
--- a/file.c
+++ b/file.c
@@ -1772,10 +1772,10 @@ sys_renameat(struct tcb *tcp)
 {
 	if (entering(tcp)) {
 		print_dirfd(tcp, tcp->u_arg[0]);
-		printpath(tcp, tcp->u_arg[1]);
+		printpathat(tcp, tcp->u_arg[0], tcp->u_arg[1]);
 		tprints(", ");
 		print_dirfd(tcp, tcp->u_arg[2]);
-		printpath(tcp, tcp->u_arg[3]);
+		printpathat(tcp, tcp->u_arg[2], tcp->u_arg[3]);
 	}
 	return 0;
 }
diff --git a/strace.c b/strace.c
index 0292c96..8b3adb2 100644
--- a/strace.c
+++ b/strace.c
@@ -204,6 +204,7 @@ usage: strace [-CdffhiqrtttTvVxxy] [-I n] [-e expr]...\n\
               -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
    or: strace -c[df] [-I n] [-e expr]... [-O overhead] [-S sortby]\n\
               -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
+-A -- print absolute paths instead of relative paths everywhere\n\
 -c -- count time, calls, and errors for each syscall and report summary\n\
 -C -- like -c but also print regular output\n\
 -w -- summarise syscall latency (default is system time)\n\
@@ -1678,6 +1679,7 @@ init(int argc, char *argv[])
 #ifdef USE_LIBUNWIND
 		"k"
 #endif
+		"A"
 		"D"
 		"a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
 		switch (c) {
diff --git a/util.c b/util.c
index 6d70623..e5a29b2 100644
--- a/util.c
+++ b/util.c
@@ -405,7 +405,8 @@ printfd(struct tcb *tcp, int fd)
 {
 	char path[PATH_MAX + 1];

-	if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0)
+	if ((show_fd_path || show_abs_path) &&
+	    getfdpath(tcp, fd, path, sizeof(path)) >= 0)
 		tprintf("%d<%s>", fd, path);
 	else
 		tprintf("%d", fd);
@@ -590,12 +591,8 @@ print_tracee_cwd(struct tcb *tcp)
 	return false;
 }

-/*
- * Print path string specified by address `addr' and length `n'.
- * If path length exceeds `n', append `...' to the output.
- */
 void
-printpathn(struct tcb *tcp, long addr, int n)
+printpath_common(struct tcb *tcp, int fd, long addr, int n)
 {
 	char path[MAXPATHLEN + 1];
 	int nul_seen;
@@ -618,13 +615,28 @@ printpathn(struct tcb *tcp, long addr, int n)
 		bool prefix_printed = false;

 		path[n] = '\0';
-		if (show_fd_path > 1 && *path && *path != '/')
+
+		/* If the call comes from `printpathn' and -y is used */
+		if (fd == -1 && show_fd_path && *path && *path != '/')
 			prefix_printed = print_tracee_cwd(tcp);
+
+		/* If the call comes from `printpathnat' and -A is used */
+		else if (show_abs_path && *path && *path != '/') {
+			if (fd == AT_FDCWD)
+				prefix_printed = print_tracee_cwd(tcp);
+			else {
+				char path[PATH_MAX + 1];
+				getfdpath(tcp, fd, path, sizeof(path));
+				tprintf("\"%s/", path);
+				prefix_printed = 1;
+			}
+		}
+
 		n++;
 		outstr = alloca(4 * n); /* 4*(n-1) + 3 for quotes and NUL */
 		string_quote(path, outstr, -1, n);

-		/* Dont print opening quotes if cwd is printed */
+		/* Dont print opening quotes if cwd/decoded dirfd is printed */
 		if (prefix_printed)
 			outstr += 1;
 		tprints(outstr);
@@ -634,6 +646,24 @@ printpathn(struct tcb *tcp, long addr, int n)
 }

 void
+printpathnat(struct tcb *tcp, int fd, long addr, int n)
+{
+	printpath_common(tcp, fd, addr, n);
+}
+
+void
+printpathat(struct tcb *tcp, int fd, long addr)
+{
+	printpathnat(tcp, fd, addr, MAXPATHLEN);
+}
+
+void
+printpathn(struct tcb *tcp, long addr, int n)
+{
+	printpath_common(tcp, -1, addr, n);
+}
+
+void
 printpath(struct tcb *tcp, long addr)
 {
 	/* Size must correspond to char path[] size in printpathn */

Thanks!
-- zm

On 20-Aug-2014, at 18:56, Dmitry V. Levin <ldv at altlinux.org> wrote:

> On Mon, Aug 11, 2014 at 09:31:25AM +0530, Zubin Mithra wrote:
> [...]
>> Currently this is how I've implemented it(this is a portion of the diff
>> minus the usage/documentation/variable declaration/print_tracee_cwd
>> function for brevity).
>> 
>> diff --git a/util.c b/util.c
>> index c78e962..57ea9fe 100644
>> --- a/util.c
>> +++ b/util.c
>> @@ -559,6 +559,60 @@ string_quote(const char *instr, char *outstr, long
>> len, int size)
>>  return 0;
>> }
>> +
>> +/* Returns the index of the dirfd to be decoded if the syscall
>> + * is a *at syscall */
>> +static bool
>> +is_at_syscall(struct tcb *tcp)
>> +{
>> + if  (tcp->s_ent->sys_func == sys_openat     ||
>> +     tcp->s_ent->sys_func == sys_mkdirat    ||
>> +     tcp->s_ent->sys_func == sys_mknodat    ||
>> +     tcp->s_ent->sys_func == sys_fchownat   ||
>> +     tcp->s_ent->sys_func == sys_futimesat  ||
>> +     tcp->s_ent->sys_func == sys_newfstatat ||
>> +     tcp->s_ent->sys_func == sys_unlinkat   ||
>> +     tcp->s_ent->sys_func == sys_renameat   ||
>> +     tcp->s_ent->sys_func == sys_linkat     ||
>> +     tcp->s_ent->sys_func == sys_readlinkat ||
>> +     tcp->s_ent->sys_func == sys_fchmodat   ||
>> +     tcp->s_ent->sys_func == sys_faccessat)
>> + return 0;
>> + else if (tcp->s_ent->sys_func == sys_symlinkat)
>> + return 1;
>> + return -1;
> 
> This won't work for renameat, renameat2, and linkat syscalls.
> A more robust approach is to introduce a new printing function, e.g.
> printpathat, and use it in these decoders.
> 
> 
> -- 
> ldv
> ------------------------------------------------------------------------------
> Slashdot TV.  
> Video for Nerds.  Stuff that matters.
> http://tv.slashdot.org/_______________________________________________
> Strace-devel mailing list
> Strace-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/strace-devel

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20140824/11ecbacb/attachment.bin>


More information about the Strace-devel mailing list