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 2/3] Modify %M directive to support variable width.


This patch will make %M directive dump the variable width
buffer in hex format instead of returning uint64_t number
as before.

* runtime/vsprintf.c: Modify %M directive.
* stap.1.in: Update description.
* testsuite/systemtap.printf/memory1.stp: Add test case.
---
 runtime/vsprintf.c                     |   31 ++++++++++++++++++++-----------
 stap.1.in                              |    2 +-
 testsuite/systemtap.printf/memory1.stp |   14 ++++++++++++++
 3 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/runtime/vsprintf.c b/runtime/vsprintf.c
index 38ab0e2..549f209 100644
--- a/runtime/vsprintf.c
+++ b/runtime/vsprintf.c
@@ -361,18 +361,16 @@ static int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
                             else
                               len = 1;
 
+                            if (*fmt_copy == 'M')
+                               len = len * 2; /* hex dump print size */
+
                             if (!(flags & STP_LEFT)) {
                               while (len < field_width--) {
                                 num_bytes++;
                               }
                             }
-                            if (*fmt_copy == 'M') {
-                              num_bytes += number_size((unsigned long) *(uint64_t *) s,
-                                  16, field_width, len, flags);
-                            }
-                            else {
-                              num_bytes += len;
-                            }
+
+                            num_bytes += len;
 
                             while (len < field_width--) {
                               num_bytes++;
@@ -636,16 +634,27 @@ static int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
 			  len = 1;
 
 			if (!(flags & STP_LEFT)) {
-				while (len < field_width--) {
+                                int actlen = len;
+                                if (*fmt == 'M')
+                                    actlen = len * 2;
+                                while (actlen < field_width--) {
 					if (str <= end)
 						*str = ' ';
 					++str;
 				}
 			}
 			if (*fmt == 'M') {
-			  str = number(str, str + len - 1 < end ? str + len - 1 : end,
-			      (unsigned long) *(uint64_t *) s,
-			      16, field_width, len, flags);
+				const char _stp_hex_asc[] = "0123456789abcdef";
+				int j;
+				#define _stp_hex_asc_lo(x)   _stp_hex_asc[((x) & 0x0f)]
+				#define _stp_hex_asc_hi(x)   _stp_hex_asc[((x) & 0xf0) >> 4]
+			        for (i = 0, j = 0; i < len; i++) {
+			               *str = _stp_hex_asc_hi(*s);
+				       str++;
+			               *str = _stp_hex_asc_lo(*s);
+				       str++; s++;
+			         }
+				len = len * 2; /* the actual length */
 			}
 			else {
                                 for (i = 0; i < len; ++i) {
diff --git a/stap.1.in b/stap.1.in
index aed473d..a8609d6 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -674,7 +674,7 @@ Signed decimal.
 Safely reads kernel memory at the given address, outputs its content.  The precision specifier determines the number of bytes to read.  Default is 1 byte.
 .TP
 %M
-Same as %m, but outputs in hexadecimal.  The precision specifier determines the number of hexadecimal digits to output.  Default is 1 digit.
+Same as %m, but outputs in hexadecimal.  The minimal size of output is double the precision specifier.
 .TP
 %o
 Unsigned octal.
diff --git a/testsuite/systemtap.printf/memory1.stp b/testsuite/systemtap.printf/memory1.stp
index f9cbf60..93a4edf 100644
--- a/testsuite/systemtap.printf/memory1.stp
+++ b/testsuite/systemtap.printf/memory1.stp
@@ -113,6 +113,20 @@ probe syscall.open {
 		success = 0;
 	}
 
+	expected_16_actual = sprintf ("  %x%x%x%x%x%x",
+				      chrofstr(filename, 0),
+				      chrofstr(filename, 1),
+				      chrofstr(filename, 2),
+				      chrofstr(filename, 3),
+				      chrofstr(filename, 4),
+				      chrofstr(filename, 5));
+        testName = "%M dynamic width larger than dynamic precision";
+        result = sprintf ("%*.*M", 14, 6, $filename);
+	if (result != expected_16_actual) {
+		printf ("Test %s failed\n", testName);
+		success = 0;
+	}
+
 	if (success)
 	   print ("Test passed\n");
 
-- 
1.5.6


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