diff options
author | Wenji Huang <wenji.huang@oracle.com> | 2009-04-27 05:38:18 -0400 |
---|---|---|
committer | Wenji Huang <wenji.huang@oracle.com> | 2009-04-26 23:05:04 -0400 |
commit | c4f51a54acff992cf19902ffd56e8338158c5811 (patch) | |
tree | e09944d29060011dfc91c95748f07f673432df96 /runtime/vsprintf.c | |
parent | 40fc3e43cea224623400ac07b6f03c700d209dec (diff) | |
download | systemtap-steved-c4f51a54acff992cf19902ffd56e8338158c5811.tar.gz systemtap-steved-c4f51a54acff992cf19902ffd56e8338158c5811.tar.xz systemtap-steved-c4f51a54acff992cf19902ffd56e8338158c5811.zip |
PR10099: Extend %M directive to support hexdumping large buffers
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.
Diffstat (limited to 'runtime/vsprintf.c')
-rw-r--r-- | runtime/vsprintf.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/runtime/vsprintf.c b/runtime/vsprintf.c index 38ab0e2d..23810e75 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,25 @@ 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); + if (*fmt == 'M') { /* stolen from kernel: trace_seq_putmem_hex() */ + const char _stp_hex_asc[] = "0123456789abcdef"; + int j; + for (i = 0, j = 0; i < len; i++) { + *str = _stp_hex_asc[((*s) & 0xf0) >> 4]; + str++; + *str = _stp_hex_asc[((*s) & 0x0f)]; + str++; s++; + } + len = len * 2; /* the actual length */ } else { for (i = 0; i < len; ++i) { |