This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[patch] Bug #5001 - ctime() vs _stp_ctime() duplication
- From: Mark Wielaard <mwielaard at redhat dot com>
- To: systemtap at sources dot redhat dot com
- Date: Tue, 20 May 2008 21:54:22 +0200
- Subject: [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", × );
- // 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;
}