This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Bug #5001 - ctime() vs _stp_ctime() duplication


Hi,

There were two ctime like functions in the tapset, one tapset function
called ctime() and another (complete) embedded C function _stp_ctime.
They both had slightly different formats. This patch makes the two
syscall probes (utime and compat_utime) that used the _stp_ctime one use
the ctime one. This also changes the helper functions in
aux_syscalls.stp to just return the utimebuf struct field values instead
of doing the time string conversion itself (they used embedded C static
char[] buffers to do it, which isn't safe if a probe runs on different
processors at the same time).

Most functions in aux_syscalls.stp are actually of the same kind, they
inspect a struct in user space. It would be nice if there was a tapset
language structure for this.

Two tests were changed to expect the new (fuller) time string format.
This is a user visible change but it is unlikely anybody depended on the
old format. And it is good to have one and the same time string format
for everything now.

tapset/ChangeLog
2008-05-20  Mark Wielaard  <mwielaard@redhat.com>

    PR 5001
    * aux_syscalls.stp (_stp_ctime): Removed.
    (_struct_utimbuf_u): Removed.
    (_struct_compat_utimbuf_u): Removed.
    (_struct_utimbuf_actime): New function.
    (_struct_utimbuf_modtime): New function.
    (_struct_compat_utimbuf_actime): New function.
    (_struct_compat_utimbuf_modtime): New function.
    * syscalls2.stp (syscall.utime): Use new functions and ctime.
    (syscall.compat_utime): Likewise.

testsuite/ChangeLog
2008-05-20  Mark Wielaard  <mwielaard@redhat.com>

    PR 5001
    * systemtap.syscall/futimes.c (utime): Expect new time format.
    * systemtap.syscall/stat.c (utime): Likewise.

Let me know if this patch is ok, or can be improved.

Cheers,

Mark
diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp
index da72a7f..ec7fdcb 100644
--- a/tapset/aux_syscalls.stp
+++ b/tapset/aux_syscalls.stp
@@ -60,77 +60,77 @@ function _struct_timezone_u:string(uaddr:long)
 %} 
 
 %{
-static const int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-static void _stp_ctime(time_t t, char *buf, int buflen)
-{
-	int mon=1, day, hour, min, sec, num, d, year = 1970;
-	
-	sec = t % 60; 
-	min = t/60 % 60;
-	hour = t/(60*60) % 24;	
-	day = t/(24*60*60);
-
-	while(1) {
-		d =  (!(year % 4) && ((year % 100) || !(year % 400))) ? 366 : 365;
-		if (day >= d)
-			day -= d;
-		else
-			break;
-		year++;
-	}
-	while (mon < 12) {
-		num = days_in_month[mon-1];
-		if (mon == 2 && d == 366)
-			num++;
-		if (day >= num)
-			day -= num;
-		else
-			break;
-		mon++;
-	}
-	
-	snprintf(buf, buflen, "%4d/%02d/%02d-%02d:%02d:%02d", year, mon, day+1, hour, min, sec);
-	buf[buflen-1] = 0;
-}
+	// Needed for the following four functions
+	// _struct_utimbuf_actime, _struct_utimbuf_modtime,
+	// _struct_compat_utimbuf_actime, _struct_compat_utimbuf_modtime
+	#include <linux/utime.h>
 %}
 
-function _struct_utimbuf_u:string(uaddr:long)
+// Returns the value of the actime field of a utimbuf in user space
+// at the given address, or zero on when userspace data is not accessible.
+function _struct_utimbuf_actime:long(uaddr:long)
 %{ /* pure */
-	#include <linux/utime.h>
 	struct utimbuf ubuf;
-	static char abuf[24], mbuf[24];
 	char *ptr = (char *)(unsigned long)THIS->uaddr;
 	
 	if (ptr == NULL)
-		strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN);
-	else {
-		if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0) {
-			_stp_ctime(ubuf.actime, abuf, 24);
-			_stp_ctime(ubuf.modtime, mbuf, 24);
-			snprintf(THIS->__retvalue, MAXSTRINGLEN, "[%s, %s]", abuf, mbuf);
-		} else
-			strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN);
-	}
+	  THIS->__retvalue = 0;
+	else
+	  if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0)
+	    THIS->__retvalue = ubuf.actime;
+	  else
+	    THIS->__retvalue = 0;
 %} 
 
-function _struct_compat_utimbuf_u:string(uaddr:long)
+// Returns the value of the modtime field of a utimbuf in user space
+// at the given address, or zero on when userspace data is not accessible.
+function _struct_utimbuf_modtime:long(uaddr:long)
+%{ /* pure */
+	struct utimbuf ubuf;
+	char *ptr = (char *)(unsigned long)THIS->uaddr;
+	
+	if (ptr == NULL)
+	  THIS->__retvalue = 0;
+	else
+	  if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0)
+	    THIS->__retvalue = ubuf.modtime;
+	  else
+	    THIS->__retvalue = 0;
+%} 
+
+// Returns the value of the actime field of a compat_utimbuf in user space
+// at the given address, or zero on when userspace data is not accessible.
+function _struct_compat_utimbuf_actime:long(uaddr:long)
 %{ /* pure */
 #ifdef CONFIG_COMPAT
-	#include <linux/utime.h>
 	struct compat_utimbuf ubuf;
-	static char abuf[24], mbuf[24];
 	char *ptr = (char *)(unsigned long)THIS->uaddr;
 	
 	if (ptr == NULL)
-		strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN);
-	else {
-		if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0) {
-			_stp_ctime(ubuf.actime, abuf, 24);
-			_stp_ctime(ubuf.modtime, mbuf, 24);
-			snprintf(THIS->__retvalue, MAXSTRINGLEN, "[%s, %s]", abuf, mbuf);
-		} else
-			strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN);
-	}
+	  THIS->__retvalue = 0;
+	else
+	  if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0)
+	    THIS->__retvalue = ubuf.actime;
+	  else
+	    THIS->__retvalue = 0;
+#endif
+%} 
+
+// Returns the value of the modtime field of a compat_utimbuf in user space
+// at the given address, or zero on when userspace data is not accessible.
+function _struct_compat_utimbuf_modtime:long(uaddr:long)
+%{ /* pure */
+#ifdef CONFIG_COMPAT
+	struct compat_utimbuf ubuf;
+	char *ptr = (char *)(unsigned long)THIS->uaddr;
+	
+	if (ptr == NULL)
+	  THIS->__retvalue = 0;
+	else
+	  if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0)
+	    THIS->__retvalue = ubuf.modtime;
+	  else
+	    THIS->__retvalue = 0;
 #endif
 %} 
 
diff --git a/tapset/syscalls2.stp b/tapset/syscalls2.stp
index 558e89b..31e1830 100644
--- a/tapset/syscalls2.stp
+++ b/tapset/syscalls2.stp
@@ -2900,8 +2900,10 @@ probe syscall.utime = kernel.function("sys_utime") ? {
 	filename_uaddr = $filename
 	filename = user_string($filename)
 	buf_uaddr = $times
-	buf_str = _struct_utimbuf_u($times)
-	argstr = sprintf("%s, %s", user_string_quoted($filename), buf_str)
+	actime = _struct_utimbuf_actime(buf_uaddr)
+	modtime = _struct_utimbuf_modtime(buf_uaddr)
+	argstr = sprintf("%s, [%s, %s]", user_string_quoted($filename),
+	       	 	 ctime(actime), ctime(modtime))
 }
 probe syscall.utime.return = kernel.function("sys_utime").return ? {
 	name = "utime"
@@ -2914,8 +2916,10 @@ probe syscall.compat_utime = kernel.function("compat_sys_utime") ? {
 	filename_uaddr = $filename
 	filename = user_string($filename)
 	buf_uaddr = $t
-	buf_str = _struct_compat_utimbuf_u($t)
-	argstr = sprintf("%s, %s", user_string_quoted($filename), _struct_compat_utimbuf_u($t))
+	actime = _struct_compat_utimbuf_actime(buf_uaddr)
+	modtime = _struct_compat_utimbuf_modtime(buf_uaddr)
+	argstr = sprintf("%s, [%s, %s]", user_string_quoted($filename),
+	       	 	 ctime(actime), ctime(modtime))
 }
 probe syscall.compat_utime.return = kernel.function("compat_sys_utime").return ? {
 	name = "utime"
diff --git a/testsuite/systemtap.syscall/futimes.c b/testsuite/systemtap.syscall/futimes.c
index 359afad..eca1efc 100644
--- a/testsuite/systemtap.syscall/futimes.c
+++ b/testsuite/systemtap.syscall/futimes.c
@@ -31,7 +31,7 @@ int main()
  times.actime = 1000000000;
  times.modtime = 2000000000;
  syscall(__NR_utime, "foobar", &times );
- // utime ("foobar", \[2001/09/09-01:46:40, 2033/05/18-03:33:20\])
+ // utime ("foobar", \[Sun Sep  9 01:46:40 2001, Wed May 18 03:33:20 2033])
 #endif /* __NR_utimes */
   
 #ifdef __NR_utimes
diff --git a/testsuite/systemtap.syscall/stat.c b/testsuite/systemtap.syscall/stat.c
index deade3e..6be5cc7 100644
--- a/testsuite/systemtap.syscall/stat.c
+++ b/testsuite/systemtap.syscall/stat.c
@@ -39,7 +39,7 @@ int main()
 #ifdef __ia64__
   // utimes ("foobar", \[1.000000\]\[1135641600.000000\]) =
 #else
-  // utime ("foobar", \[1970/01/01-00:00:01, 2005/12/27-00:00:00\]) = 0
+  // utime ("foobar", \[Thu Jan  1 00:00:01 1970, Tue Dec 27 00:00:00 2005\]) = 0
 #endif
 
   ubuf.actime =  1135690000;
@@ -48,7 +48,7 @@ int main()
 #ifdef __ia64__
   // utimes ("foobar", \[1135690000.000000\]\[1135700000.000000\]) =
 #else
-  // utime ("foobar", \[2005/12/27-13:26:40, 2005/12/27-16:13:20\]) = 0
+  // utime ("foobar", \[Tue Dec 27 13:26:40 2005, Tue Dec 27 16:13:20 2005\]) = 0
 #endif
   return 0;
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]