summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2008-02-27 12:54:34 -0500
committerFrank Ch. Eigler <fche@elastic.org>2008-02-27 12:54:34 -0500
commited1f47c32969a60eb074dc246c79ccda456ebf58 (patch)
tree65f8bc63b516fe525af1409fad83f44235d9e675
parent781c25855e35a7b77e5794bd027ca0cf41e4a3a4 (diff)
parenta2dc47ddef0dbed1b0dc912c876f5f57f97c1ede (diff)
downloadsystemtap-steved-ed1f47c32969a60eb074dc246c79ccda456ebf58.tar.gz
systemtap-steved-ed1f47c32969a60eb074dc246c79ccda456ebf58.tar.xz
systemtap-steved-ed1f47c32969a60eb074dc246c79ccda456ebf58.zip
Merge branch 'master' of git://sources.redhat.com/git/systemtap
-rw-r--r--ChangeLog49
-rw-r--r--NEWS29
-rw-r--r--elaborate.cxx57
-rw-r--r--elaborate.h1
-rw-r--r--runtime/ChangeLog7
-rw-r--r--runtime/vsprintf.c78
-rw-r--r--staprun.8.in4
-rw-r--r--staptree.cxx54
-rw-r--r--staptree.h25
-rw-r--r--systemtap.spec.in13
-rw-r--r--tapset/ChangeLog5
-rw-r--r--tapset/x86_64/syscalls.stp6
-rw-r--r--testsuite/ChangeLog10
-rw-r--r--testsuite/systemtap.base/marker.exp3
-rw-r--r--testsuite/systemtap.printf/bin6.expbin0 -> 1225 bytes
-rw-r--r--testsuite/systemtap.printf/bin6.stp40
-rw-r--r--testsuite/systemtap.printf/memory1.exp18
-rw-r--r--testsuite/systemtap.printf/memory1.stp27
18 files changed, 378 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index 491d114b..4326326c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2008-02-21 Dave Brolley <brolley@redhat.com>
+
+ PR5189
+ * staptree.h (print_format::conv_memory): New enumerator.
+ (print_format::width_type): New enumeration.
+ (print_format::precision_type): New enumeration.
+ (format_component::widthtype): New member.
+ (format_component::prectype): New member.
+ (format_component::is_empty): Test widthtype and prectype.
+ (format_component::clear): Clear widthtype and prectype.
+ * staptree.cxx (print_format::components_to_string): Handle dynamic width and precision.
+ Handle conv_memory.
+ (print_format::string_to_components): Parse dynamic width and precision specifiers.
+ Set widthtype and prectype. Parse %m format specifier.
+ * elaborate.h (typeresolution_info::check_arg_type): New method.
+ * elaborate.cxx (typeresolution_info::visit_print_format): Account for dynamic width
+ and precision when computing the expected number of arguments. Check the types of
+ arguments for dynamic width and precision. Use check_arg_type to check the types of
+ all arguments. Handle print_format::conv_memory.
+ (typeresolution_info::check_arg_type): New method.
+ * NEWS: Describe the enhancements above.
+
+2008-02-27 David Smith <dsmith@redhat.com>
+
+ PR5729
+ * systemtap.spec.in: Adds examples to the testsuite rpm so that
+ systemtap.samples/examples.exp works correctly.
+
+2008-02-26 Dave Brolley <brolley@redhat.com>
+
+ PR5018
+ * staprun.8.in: Escape dashes ('-') as appropriate.
+
2008-02-26 Srinivasa DS <srinivasa@in.ibm.com>
PR5772
* tapset/syscall2.stp: Modify wait4,waitid argument list
@@ -286,6 +319,16 @@
rcu_dereferences of engine->data to resync with kernel.org
builds.
+2008-01-18 Srinivasa DS <srinivasa@in.ibm.com>
+
+ PR 5549
+ * buildrun.cxx : Verify whether kernel has register rename patch
+ through autoconf files.
+ * runtime/(loc2c-runtime.h, procfs.c, regs.c, regs.h,
+ stack-i386.c, autoconf-x86-uniregs.c, autoconf-nameidata.c) : Use
+ appropriate register name at runtime, based on whether kernel has
+ register rename patch or not.
+
2008-01-18 Jim Keniston <jkenisto@us.ibm.com>
* runtime/uprobes/uprobes.c: Added static copy of
@@ -296,6 +339,12 @@
* configure.ac, systemtap.spec.in: Update version to 0.6.1
* configure: Regenerated.
+2008-01-17 Srinivasa DS <srinivasa@in.ibm.com>
+
+ PR 5483
+ * tapsets.cxx : Possible fix for making systemtap compatible with
+ the elfutils-0.131
+
2008-01-17 Frank Ch. Eigler <fche@elastic.org>
PR 4935.
diff --git a/NEWS b/NEWS
index df7e27b4..cd9c72db 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,34 @@
* What's new in version 0.6 / 0.6.1
+- There is a new format specifier, %m, for the printf family of
+ functions. It functions like %s, except that it does not stop when
+ a nul ('\0') byte is encountered. The number of bytes output is
+ determined by the precision specifier. The default precision is 1.
+ For example:
+
+ printf ("%m", "My String") // prints one character: M
+ printf ("%.5", myString) // prints 5 bytes beginning at the start
+ // of myString
+
+- The %b format specifier for the printf family of functions has been enhanced
+ as follows:
+
+ 1) When the width and precision are both unspecified, the default is %8.8b.
+ 2) When only one of the width or precision is specified, the other defaults
+ to the same value. For example, %4b == %.4b == %4.4b
+ 3) Nul ('\0') bytes are used for field width padding. For example,
+
+ printf ("%b", 0x1111deadbeef2222) // prints all eight bytes
+ printf ("%4.2b", 0xdeadbeef) // prints \0\0\xbe\xef
+
+- Dynamic width and precision are now supported for all printf family format
+ specifiers. For example:
+
+ four = 4
+ two = 2
+ printf ("%*.*b", four, two, 0xdeadbbeef) // prints \0\0\xbe\xef
+ printf ("%*d", four, two) // prints <space><space><space>2
+
- Preprocessor conditional expressions can now include wildcard style
matches on kernel versions.
%( kernel_vr != "*xen" %? foo %: bar %)
diff --git a/elaborate.cxx b/elaborate.cxx
index bc0d1489..7f4ccf35 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -2854,6 +2854,7 @@ typeresolution_info::visit_print_format (print_format* e)
// First we extract the subsequence of formatting components
// which are conversions (not just literal string components)
+ unsigned expected_num_args = 0;
std::vector<print_format::format_component> components;
for (size_t i = 0; i < e->components.size(); ++i)
{
@@ -2864,19 +2865,39 @@ typeresolution_info::visit_print_format (print_format* e)
|| e->components[i].type == print_format::conv_size)
continue;
components.push_back(e->components[i]);
+ ++expected_num_args;
+ if (e->components[i].widthtype == print_format::width_dynamic)
+ ++expected_num_args;
+ if (e->components[i].prectype == print_format::prec_dynamic)
+ ++expected_num_args;
}
// Then we check that the number of conversions and the number
// of args agree.
- if (components.size() != e->args.size())
+ if (expected_num_args != e->args.size())
throw semantic_error ("Wrong number of args to formatted print operator",
e->tok);
// Then we check that the types of the conversions match the types
// of the args.
+ unsigned argno = 0;
for (size_t i = 0; i < components.size(); ++i)
{
+ // Check the dynamic width, if specified
+ if (components[i].widthtype == print_format::width_dynamic)
+ {
+ check_arg_type (pe_long, e->args[argno]);
+ ++argno;
+ }
+
+ // Check the dynamic precision, if specified
+ if (components[i].prectype == print_format::prec_dynamic)
+ {
+ check_arg_type (pe_long, e->args[argno]);
+ ++argno;
+ }
+
exp_type wanted = pe_unknown;
switch (components[i].type)
@@ -2898,24 +2919,14 @@ typeresolution_info::visit_print_format (print_format* e)
break;
case print_format::conv_string:
+ case print_format::conv_memory:
wanted = pe_string;
break;
}
assert (wanted != pe_unknown);
-
- t = wanted;
- e->args[i]->visit (this);
-
- if (e->args[i]->type == pe_unknown)
- {
- e->args[i]->type = wanted;
- resolved (e->args[i]->tok, wanted);
- }
- else if (e->args[i]->type != wanted)
- {
- mismatch (e->args[i]->tok, e->args[i]->type, wanted);
- }
+ check_arg_type (wanted, e->args[argno]);
+ ++argno;
}
}
else
@@ -2976,6 +2987,24 @@ typeresolution_info::visit_hist_op (hist_op* e)
void
+typeresolution_info::check_arg_type (exp_type wanted, expression* arg)
+{
+ t = wanted;
+ arg->visit (this);
+
+ if (arg->type == pe_unknown)
+ {
+ arg->type = wanted;
+ resolved (arg->tok, wanted);
+ }
+ else if (arg->type != wanted)
+ {
+ mismatch (arg->tok, arg->type, wanted);
+ }
+}
+
+
+void
typeresolution_info::unresolved (const token* tok)
{
num_still_unresolved ++;
diff --git a/elaborate.h b/elaborate.h
index 607f8689..fc8fbbcb 100644
--- a/elaborate.h
+++ b/elaborate.h
@@ -54,6 +54,7 @@ struct typeresolution_info: public visitor
functiondecl* current_function;
derived_probe* current_probe;
+ void check_arg_type (exp_type wanted, expression* arg);
void mismatch (const token* tok, exp_type t1, exp_type t2);
void unresolved (const token* tok);
void resolved (const token* tok, exp_type t);
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index b501c1ef..512fa061 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,10 @@
+2008-02-27 Dave Brolley <brolley@redhat.com>
+
+ PR5189
+ * vsprintf.c (_stp_vsnprintf): Extract arguments of type int64_t for
+ dynamic width and precision. Implement width and precision correctly for
+ the %b format specifier. Implement the %m specifier.
+
2008-02-06 Masami Hiramatsu <mhiramat@redhat.com>
* stack-ia64.c (__stp_show_stack_sym): Skip printing symbol if (ip ==
diff --git a/runtime/vsprintf.c b/runtime/vsprintf.c
index 061aba3f..f8283e5c 100644
--- a/runtime/vsprintf.c
+++ b/runtime/vsprintf.c
@@ -1,6 +1,6 @@
/* -*- linux-c -*-
* vsprintf.c
- * Copyright (C) 2006 Red Hat Inc.
+ * Copyright (C) 2006, 2008 Red Hat Inc.
* Based on code from the Linux kernel
* Copyright (C) 1991, 1992 Linus Torvalds
*
@@ -115,6 +115,22 @@ static char * number(char * buf, char * end, uint64_t num, int base, int size, i
return buf;
}
+static int check_binary_precision (int precision) {
+ /* precision can be unspecified (-1) or one of 1, 2, 4 or 8. */
+ switch (precision) {
+ case -1:
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ break;
+ default:
+ precision = -1;
+ break;
+ }
+ return precision;
+}
+
int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
int len;
@@ -164,7 +180,7 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
- field_width = va_arg(args, int);
+ field_width = va_arg(args, int64_t);
if (field_width < 0) {
field_width = -field_width;
flags |= STP_LEFT;
@@ -180,7 +196,7 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
- precision = va_arg(args, int);
+ precision = va_arg(args, int64_t);
}
if (precision < 0)
precision = 0;
@@ -203,7 +219,36 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
switch (*fmt) {
case 'b':
num = va_arg(args, int64_t);
- switch(field_width) {
+
+ /* Only certain values are valid for the precision. */
+ precision = check_binary_precision (precision);
+
+ /* Unspecified field width defaults to the specified
+ precision and vice versa. If neither is specified,
+ then both default to 8. */
+ if (field_width == -1) {
+ if (precision == -1) {
+ field_width = 8;
+ precision = 8;
+ }
+ else
+ field_width = precision;
+ }
+ else if (precision == -1) {
+ precision = check_binary_precision (field_width);
+ if (precision == -1)
+ precision = 8;
+ }
+
+ len = precision;
+ if (!(flags & STP_LEFT)) {
+ while (len < field_width--) {
+ if (str <= end)
+ *str = '\0';
+ ++str;
+ }
+ }
+ switch(precision) {
case 1:
if(str <= end)
*(int8_t *)str = (int8_t)num;
@@ -214,26 +259,37 @@ int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
*(int16_t *)str = (int16_t)num;
str+=2;
break;
- case 8:
- if((str + 7) <= end)
- *(int64_t *)str = num;
- str+=8;
- break;
case 4:
- default: // "%4b" by default
if((str + 3) <= end)
*(int32_t *)str = num;
str+=4;
break;
+ default: // "%.8b" by default
+ case 8:
+ if((str + 7) <= end)
+ *(int64_t *)str = num;
+ str+=8;
+ break;
+ }
+ while (len < field_width--) {
+ if (str <= end)
+ *str = '\0';
+ ++str;
}
continue;
case 's':
+ case 'm':
s = va_arg(args, char *);
if ((unsigned long)s < PAGE_SIZE)
s = "<NULL>";
- len = strnlen(s, precision);
+ if (*fmt == 's')
+ len = strnlen(s, precision);
+ else if (precision > 0)
+ len = precision;
+ else
+ len = 1;
if (!(flags & STP_LEFT)) {
while (len < field_width--) {
diff --git a/staprun.8.in b/staprun.8.in
index fe52f170..c1678f69 100644
--- a/staprun.8.in
+++ b/staprun.8.in
@@ -73,7 +73,7 @@ Attach to loaded systemtap module.
.B MODULE
is either a module path or a module name. If it is a module name,
the module will be looked for in the following directory
-(where 'VERSION' is the output of "uname -r"):
+(where 'VERSION' is the output of "uname \-r"):
.IP
/lib/modules/VERSION/systemtap
.PP
@@ -95,7 +95,7 @@ to compile a script. The
program will report the pathname to the resulting module.
.PP
.Vb 1
-\& $ stap -p4 -e 'probe begin { printf("Hello World!\\n"); exit() }'
+\& $ stap \-p4 \-e 'probe begin { printf("Hello World!\\n"); exit() }'
.br
\& /home/user/.systemtap/cache/85/stap_8553d83f78c_265.ko
.PP
diff --git a/staptree.cxx b/staptree.cxx
index 36ef04f5..63c1fcf7 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -442,10 +442,14 @@ print_format::components_to_string(vector<format_component> const & components)
if (i->flags & static_cast<unsigned long>(fmt_flag_special))
oss << '#';
- if (i->width > 0)
+ if (i->widthtype == width_dynamic)
+ oss << '*';
+ else if (i->widthtype != width_unspecified && i->width > 0)
oss << i->width;
- if (i->precision > 0)
+ if (i->prectype == prec_dynamic)
+ oss << ".*";
+ else if (i->prectype != prec_unspecified && i->precision > 0)
oss << '.' << i->precision;
switch (i->type)
@@ -482,6 +486,10 @@ print_format::components_to_string(vector<format_component> const & components)
oss << 's';
break;
+ case conv_memory:
+ oss << 'm';
+ break;
+
case conv_size:
oss << 'n';
break;
@@ -574,14 +582,27 @@ print_format::string_to_components(string const & str)
break;
}
+ if (i == str.end())
+ break;
+
// Parse optional width
-
- while (i != str.end() && isdigit(*i))
+ if (*i == '*')
{
- curr.width *= 10;
- curr.width += (*i - '0');
+ curr.widthtype = width_dynamic;
++i;
}
+ else if (isdigit(*i))
+ {
+ curr.widthtype = width_static;
+ curr.width = 0;
+ do
+ {
+ curr.width *= 10;
+ curr.width += (*i - '0');
+ ++i;
+ }
+ while (i != str.end() && isdigit(*i));
+ }
if (i == str.end())
break;
@@ -592,12 +613,23 @@ print_format::string_to_components(string const & str)
++i;
if (i == str.end())
break;
- while (i != str.end() && isdigit(*i))
+ if (*i == '*')
{
- curr.precision *= 10;
- curr.precision += (*i - '0');
+ curr.prectype = prec_dynamic;
++i;
}
+ else if (isdigit(*i))
+ {
+ curr.prectype = prec_static;
+ curr.precision = 0;
+ do
+ {
+ curr.precision *= 10;
+ curr.precision += (*i - '0');
+ ++i;
+ }
+ while (i != str.end() && isdigit(*i));
+ }
}
if (i == str.end())
@@ -615,6 +647,10 @@ print_format::string_to_components(string const & str)
curr.type = conv_string;
break;
+ case 'm':
+ curr.type = conv_memory;
+ break;
+
case 'd':
case 'i':
curr.type = conv_signed_decimal;
diff --git a/staptree.h b/staptree.h
index 8235a535..acb56719 100644
--- a/staptree.h
+++ b/staptree.h
@@ -287,31 +287,48 @@ struct print_format: public expression
conv_unsigned_uppercase_hex,
conv_unsigned_lowercase_hex,
conv_string,
+ conv_memory,
conv_literal,
conv_binary,
conv_size
};
+ enum width_type
+ {
+ width_unspecified,
+ width_static,
+ width_dynamic
+ };
+
+ enum precision_type
+ {
+ prec_unspecified,
+ prec_static,
+ prec_dynamic
+ };
+
struct format_component
{
unsigned long flags;
unsigned width;
unsigned precision;
+ width_type widthtype;
+ precision_type prectype;
conversion_type type;
std::string literal_string;
bool is_empty() const
{
return flags == 0
- && width == 0
- && precision == 0
+ && widthtype == width_unspecified
+ && prectype == prec_unspecified
&& type == conv_unspecified
&& literal_string.empty();
}
void clear()
{
flags = 0;
- width = 0;
- precision = 0;
+ widthtype = width_unspecified;
+ prectype = prec_unspecified;
type = conv_unspecified;
literal_string.clear();
}
diff --git a/systemtap.spec.in b/systemtap.spec.in
index 789f219f..7d0579f2 100644
--- a/systemtap.spec.in
+++ b/systemtap.spec.in
@@ -145,6 +145,8 @@ chmod 755 $RPM_BUILD_ROOT%{_bindir}/staprun
# Copy over the testsuite
cp -rp testsuite $RPM_BUILD_ROOT%{_datadir}/systemtap
+mkdir $RPM_BUILD_ROOT%{_datadir}/%{name}/src
+cp -rp examples $RPM_BUILD_ROOT%{_datadir}/%{name}/src
%clean
rm -rf ${RPM_BUILD_ROOT}
@@ -163,9 +165,9 @@ exit 0
%{_mandir}/man1/*
%{_mandir}/man5/*
-%dir %{_datadir}/systemtap
-%{_datadir}/systemtap/runtime
-%{_datadir}/systemtap/tapset
+%dir %{_datadir}/%{name}
+%{_datadir}/%{name}/runtime
+%{_datadir}/%{name}/tapset
%if %{with_bundled_elfutils} || %{with_crash}
%dir %{_libdir}/%{name}
@@ -180,14 +182,15 @@ exit 0
%files runtime
%defattr(-,root,root)
%attr(4111,root,root) %{_bindir}/staprun
-%{_libexecdir}/systemtap
+%{_libexecdir}/%{name}
%{_mandir}/man8/*
%doc README AUTHORS NEWS COPYING
%files testsuite
%defattr(-,root,root)
-%{_datadir}/systemtap/testsuite
+%{_datadir}/%{name}/src
+%{_datadir}/%{name}/testsuite
%changelog
diff --git a/tapset/ChangeLog b/tapset/ChangeLog
index 94071f07..e198b9e5 100644
--- a/tapset/ChangeLog
+++ b/tapset/ChangeLog
@@ -1,3 +1,8 @@
+2008-02-27 Masami Hiramatsu <mhiramat@redhat.com>
+
+ * x86_64/syscalls.stp (syscall.iopl): Use new_iopl instead of level
+ on xen kernel.
+
2008-01-25 Will Cohen <wcohen@redhat.com>
PR5554
diff --git a/tapset/x86_64/syscalls.stp b/tapset/x86_64/syscalls.stp
index 1b39e04e..418aaf23 100644
--- a/tapset/x86_64/syscalls.stp
+++ b/tapset/x86_64/syscalls.stp
@@ -23,8 +23,12 @@ probe syscall.arch_prctl.return = kernel.function("sys_arch_prctl").return {
#
probe syscall.iopl = kernel.function("sys_iopl") {
name = "iopl"
+%( kernel_vr == "*xen" %?
+ level = $new_iopl
+%:
level = $level
- argstr = sprint($level)
+%)
+ argstr = sprint(level)
}
probe syscall.iopl.return = kernel.function("sys_iopl").return {
name = "iopl"
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index addab719..aee14fe6 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,13 @@
+2008-02-27 Dave Brolley <brolley@redhat.com>
+
+ PR5189
+ * systemtap.printf/bin6.{exp,stp}: New test case.
+ * systemtap.printf/memory1.{exp,stp}: New test case.
+
+2008-02-27 David Smith <dsmith@redhat.com>
+
+ * systemtap.base/marker.exp: Added better path to Module.markers.
+
2008-02-25 Frank Ch. Eigler <fche@elastic.org>
PR5792.
diff --git a/testsuite/systemtap.base/marker.exp b/testsuite/systemtap.base/marker.exp
index 513ddcd6..857fa5d2 100644
--- a/testsuite/systemtap.base/marker.exp
+++ b/testsuite/systemtap.base/marker.exp
@@ -59,8 +59,7 @@ set kernel_format_script {"probe kernel.mark(\"%s\").format(\"%s\") { }"}
# Try to read in the marker list from the Module.markers file.
set uname [exec /bin/uname -r]
-set arch [exec arch]
-set path "/usr/src/kernels/$uname-$arch/Module.markers"
+set path "/lib/modules/$uname/build/Module.markers"
if {! [catch {open $path RDONLY} fl]} {
while {[gets $fl s] >= 0} {
# This regexp only picks up markers that contain arguments.
diff --git a/testsuite/systemtap.printf/bin6.exp b/testsuite/systemtap.printf/bin6.exp
new file mode 100644
index 00000000..0de41e78
--- /dev/null
+++ b/testsuite/systemtap.printf/bin6.exp
Binary files differ
diff --git a/testsuite/systemtap.printf/bin6.stp b/testsuite/systemtap.printf/bin6.stp
new file mode 100644
index 00000000..a281d5a3
--- /dev/null
+++ b/testsuite/systemtap.printf/bin6.stp
@@ -0,0 +1,40 @@
+# test of width and precision on binary prints
+
+probe begin {
+ one = 1;
+ two = 2;
+ four = 4;
+ eight = 8;
+ deadbeef = big_endian8 (0x6465616462656566);
+
+ printf ("Binary default width default precision\t:%b:\n", deadbeef);
+
+ printf ("Binary static width default precision\t:%1b:\n", deadbeef);
+ printf ("Binary static width default precision\t:%2b:\n", deadbeef);
+ printf ("Binary static width default precision\t:%4b:\n", deadbeef);
+ printf ("Binary static width default precision\t:%8b:\n", deadbeef);
+ printf ("Binary dynamic width default precision\t:%*b:\n", one, deadbeef);
+ printf ("Binary dynamic width default precision\t:%*b:\n", two, deadbeef);
+ printf ("Binary dynamic width default precision\t:%*b:\n", four, deadbeef);
+ printf ("Binary dynamic width default precision\t:%*b:\n", eight, deadbeef);
+
+ printf ("Binary default width static precision\t:%.8b:\n", deadbeef);
+ printf ("Binary default width static precision\t:%.4b:\n", deadbeef);
+ printf ("Binary default width static precision\t:%.2b:\n", deadbeef);
+ printf ("Binary default width static precision\t:%.1b:\n", deadbeef);
+ printf ("Binary default width dynamic precision\t:%.*b:\n", eight, deadbeef);
+ printf ("Binary default width dynamic precision\t:%.*b:\n", four, deadbeef);
+ printf ("Binary default width dynamic precision\t:%.*b:\n", two, deadbeef);
+ printf ("Binary default width dynamic precision\t:%.*b:\n", one, deadbeef);
+
+ printf ("Binary static width static precision\t:%1.8b:\n", deadbeef);
+ printf ("Binary static width static precision\t:%2.4b:\n", deadbeef);
+ printf ("Binary static width static precision\t:%4.2b:\n", deadbeef);
+ printf ("Binary static width static precision\t:%8.1b:\n", deadbeef);
+ printf ("Binary dynamic width dynamic precision\t:%*.*b:\n", one, eight, deadbeef);
+ printf ("Binary dynamic width dynamic precision\t:%*.*b:\n", two, four, deadbeef);
+ printf ("Binary dynamic width dynamic precision\t:%*.*b:\n", four, two, deadbeef);
+ printf ("Binary dynamic width dynamic precision\t:%*.*b:\n", eight, one, deadbeef);
+
+ exit ();
+}
diff --git a/testsuite/systemtap.printf/memory1.exp b/testsuite/systemtap.printf/memory1.exp
new file mode 100644
index 00000000..2389cdc5
--- /dev/null
+++ b/testsuite/systemtap.printf/memory1.exp
@@ -0,0 +1,18 @@
+set test "memory1"
+set ::result_string {Memory default width and precision :m:
+Memory static precision smaller than input :my st:
+Memory dynamic precision smaller than input :my st:
+Memory static precision equal to input :my string:
+Memory dynamic precision equal to input :my string:
+Memory static width default precision : m:
+Memory dynamic width default precision : m:
+Memory static width smaller than static precision :my string:
+Memory static width larger than static precision : my string:
+Memory dynamic width smaller than static precision :my string:
+Memory dynamic width larger than static precision : my string:
+Memory static width smaller than dynamic precision :my string:
+Memory static width larger than dynamic precision : my string:
+Memory dynamic width smaller than dynamic precision :my string:
+Memory dynamic width larger than dynamic precision : my string:
+}
+stap_run2 $srcdir/$subdir/$test.stp
diff --git a/testsuite/systemtap.printf/memory1.stp b/testsuite/systemtap.printf/memory1.stp
new file mode 100644
index 00000000..3b4d6d5e
--- /dev/null
+++ b/testsuite/systemtap.printf/memory1.stp
@@ -0,0 +1,27 @@
+probe begin {
+ five = 5;
+ nine = 9;
+ fifteen = 15;
+ s = "my string";
+
+ printf ("Memory default width and precision\t:%m:\n", s);
+
+ printf ("Memory static precision smaller than input\t:%.5m:\n", s);
+ printf ("Memory dynamic precision smaller than input\t:%.*m:\n", five, s);
+ printf ("Memory static precision equal to input\t:%.9m:\n", s);
+ printf ("Memory dynamic precision equal to input\t:%.*m:\n", nine, s);
+
+ printf ("Memory static width default precision\t:%5m:\n", s);
+ printf ("Memory dynamic width default precision\t:%*m:\n", five, s);
+
+ printf ("Memory static width smaller than static precision\t:%5.9m:\n", s);
+ printf ("Memory static width larger than static precision\t:%15.9m:\n", s);
+ printf ("Memory dynamic width smaller than static precision\t:%*.9m:\n", five, s);
+ printf ("Memory dynamic width larger than static precision\t:%*.9m:\n", fifteen, s);
+ printf ("Memory static width smaller than dynamic precision\t:%5.*m:\n", nine, s);
+ printf ("Memory static width larger than dynamic precision\t:%15.*m:\n", nine, s);
+ printf ("Memory dynamic width smaller than dynamic precision\t:%*.*m:\n", five, nine, s);
+ printf ("Memory dynamic width larger than dynamic precision\t:%*.*m:\n", fifteen, nine, s);
+
+ exit()
+}