[PATCH v3 2/4] printrusage: Correctly print the long types from the rusage struct

Alistair Francis alistair.francis at wdc.com
Sat Mar 7 02:22:21 UTC 2020


The kernel's rusage struct uses the kernel's __kernel_old_timeval which
means that even for 32-bit archs with 64-bit time_t (like RV32) the time
values are 32-bit.

There are two possible options here:
 1. Use the glibc getrusage() function. Which takes a struct rusage with
    a 64-bit time_t but does a syscall with a 32-bit time_t and handles
    the conversion internally.
 2. Specify our own rusage struct that uses a long for the time.

This patch fixes the failure useing option 2 above as we then get to
call the raw syscall.

Signed-off-by: Alistair Francis <alistair.francis at wdc.com>
---
 print_timeval.c   | 13 +++++++++++++
 printrusage.c     |  4 ++--
 tests/getrusage.c | 28 ++++++++++++++++++++++++++--
 3 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/print_timeval.c b/print_timeval.c
index ff87b27b..4cc400e1 100644
--- a/print_timeval.c
+++ b/print_timeval.c
@@ -7,6 +7,7 @@
  */
 
 #include "defs.h"
+#include <linux/time_types.h>
 
 #include DEF_MPERS_TYPE(timeval_t)
 
@@ -25,6 +26,13 @@ print_timeval_t(const timeval_t *t)
 		zero_extend_signed_to_ull(t->tv_usec));
 }
 
+static void
+print_old_timeval_t(const struct __kernel_old_timeval *t)
+{
+	tprintf(timeval_fmt, (long long) t->tv_sec,
+		zero_extend_signed_to_ull(t->tv_usec));
+}
+
 static void
 print_timeval_t_utime(const timeval_t *t)
 {
@@ -38,6 +46,11 @@ MPERS_PRINTER_DECL(void, print_struct_timeval, const void *arg)
 	print_timeval_t(arg);
 }
 
+MPERS_PRINTER_DECL(void, print_struct_old_timeval, const void *arg)
+{
+	print_old_timeval_t(arg);
+}
+
 MPERS_PRINTER_DECL(bool, print_struct_timeval_data_size,
 		   const void *arg, const size_t size)
 {
diff --git a/printrusage.c b/printrusage.c
index 7cfeb7a0..04da400a 100644
--- a/printrusage.c
+++ b/printrusage.c
@@ -51,9 +51,9 @@ MPERS_PRINTER_DECL(void, printrusage,
 		return;
 
 	tprints("{ru_utime=");
-	MPERS_FUNC_NAME(print_struct_timeval)(&ru.ru_utime);
+	MPERS_FUNC_NAME(print_struct_old_timeval)(&ru.ru_utime);
 	tprints(", ru_stime=");
-	MPERS_FUNC_NAME(print_struct_timeval)(&ru.ru_stime);
+	MPERS_FUNC_NAME(print_struct_old_timeval)(&ru.ru_stime);
 	if (abbrev(tcp)) {
 		tprints(", ...");
 	} else {
diff --git a/tests/getrusage.c b/tests/getrusage.c
index b046fde2..cb2c4835 100644
--- a/tests/getrusage.c
+++ b/tests/getrusage.c
@@ -21,8 +21,32 @@
 # include "xlat.h"
 # include "xlat/usagewho.h"
 
+struct kernel_old_timeval {
+	kernel_long_t	tv_sec;
+	long		tv_usec;
+};
+
+struct rusage_t {
+	struct kernel_old_timeval ru_utime;
+	struct kernel_old_timeval ru_stime;
+	kernel_long_t	ru_maxrss;
+	kernel_long_t	ru_ixrss;
+	kernel_long_t	ru_idrss;
+	kernel_long_t	ru_isrss;
+	kernel_long_t	ru_minflt;
+	kernel_long_t	ru_majflt;
+	kernel_long_t	ru_nswap;
+	kernel_long_t	ru_inblock;
+	kernel_long_t	ru_oublock;
+	kernel_long_t	ru_msgsnd;
+	kernel_long_t	ru_msgrcv;
+	kernel_long_t	ru_nsignals;
+	kernel_long_t	ru_nvcsw;
+	kernel_long_t	ru_nivcsw;
+};
+
 int
-invoke_print(int who, const char *who_str, struct rusage *usage)
+invoke_print(int who, const char *who_str, struct rusage_t *usage)
 {
 	int rc = syscall(__NR_getrusage, who, usage);
 	int saved_errno = errno;
@@ -49,7 +73,7 @@ invoke_print(int who, const char *who_str, struct rusage *usage)
 int
 main(void)
 {
-	TAIL_ALLOC_OBJECT_CONST_PTR(struct rusage, usage);
+	TAIL_ALLOC_OBJECT_CONST_PTR(struct rusage_t, usage);
 	if (invoke_print(ARG_STR(RUSAGE_SELF), usage)) {
 		perror_msg_and_fail("RUSAGE_SELF");
 	}
-- 
2.25.1



More information about the Strace-devel mailing list