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]

[Bug translator/6851] New: printf %c


This may be multiple bugs, but I suspect it's just one bug with an
incomplete fix.

The primary bug is that the translator doesn't support the %c printf
conversion specifier.  (All this is on an i686 system.)  Given the
following script...
----- bug.stp -----
probe process("bug").function("echo_char"),
    process("nobug").function("echo_char")
{
	printf("%s:%s(%c/%#x)\n", execname(), probefunc(), $c, $c)
}
probe process("bug").function("echo_char"),
    process("nobug").function("echo_char")
{
	printf("%s:%s(%#x)\n", execname(), probefunc(), $c)
}
-----
... stap -v bug.stp reports
parse error: invalid or missing conversion specifier
	saw: string '%s:%s(%c/%#x)\n' at bug.stp:4:9
parse error: expected statement
	saw: keyword at bug.stp:6:1
parse error: expected statement
	saw: bug.stp EOF
3 parse error(s).
Pass 1: parsed user script and 45 library script(s) in 460usr/20sys/557real ms.
Pass 1: parse failed.  Try again with more '-v' (verbose) options.

I made what seemed to be the obvious changes to the translator to add %c
support:
----- printf_c.patch -----
diff -ur old/elaborate.cxx new/elaborate.cxx
--- old/elaborate.cxx	2008-08-08 17:09:28.000000000 -0700
+++ new/elaborate.cxx	2008-08-08 17:09:28.000000000 -0700
@@ -3623,6 +3623,7 @@
 	    case print_format::conv_unsigned_uppercase_hex:
 	    case print_format::conv_unsigned_lowercase_hex:
 	    case print_format::conv_binary:
+	    case print_format::conv_char:
 	    case print_format::conv_memory:
 	      wanted = pe_long;
 	      break;
diff -ur old/staptree.cxx new/staptree.cxx
--- old/staptree.cxx	2008-08-08 17:09:28.000000000 -0700
+++ new/staptree.cxx	2008-08-08 17:13:27.000000000 -0700
@@ -458,6 +458,10 @@
 	      oss << "b";
 	      break;
 
+	    case conv_char:
+	      oss << "llc";
+	      break;
+
 	    case conv_signed_decimal:
 	      oss << "lld";
 	      break;
@@ -635,14 +639,18 @@
       if (i == str.end())
 	break;
 
-      // Parse the actual conversion specifier (sdiouxX)
+      // Parse the actual conversion specifier (bcsmdioupxXn)
       switch (*i)
 	{
 	  // Valid conversion types
 	case 'b':
 	  curr.type = conv_binary;
 	  break;
-	  
+
+	case 'c':
+	  curr.type = conv_char;
+	  break;
+
 	case 's':
 	  curr.type = conv_string;
 	  break;
diff -ur old/staptree.h new/staptree.h
--- old/staptree.h	2008-08-08 17:09:28.000000000 -0700
+++ new/staptree.h	2008-08-08 17:09:28.000000000 -0700
@@ -287,6 +287,7 @@
       conv_unsigned_uppercase_hex,
       conv_unsigned_lowercase_hex,
       conv_string,
+      conv_char,
       conv_memory,
       conv_literal,
       conv_binary,
----- end of patch -----
Now stap accepts the %c conversion specifier, but the generated code
is wrong.  Given the following...
----- echo_chars.c -----
#include <stdio.h>

#ifdef BUG
void echo_char(char c)
#else
void echo_char(int c)
#endif
{
	asm volatile("");	// defeat inlining
	printf("%c", c);
}

main()
{
	echo_char('s');
	echo_char('t');
	echo_char('a');
	echo_char('p');
	printf("\n");
}
----- Makefile -----
all: bug nobug

bug: echo_chars.c
	$(CC) -g -DBUG echo_chars.c -o bug

nobug: echo_chars.c
	$(CC) -g echo_chars.c -o nobug

clean:
	rm -f bug nobug
-----
... if you run
	$ stap -v bug.stp
in one window and
	$ ./bug
	$ ./nobug
in another window, stap reports:
Pass 1: parsed user script and 45 library script(s) in 450usr/20sys/594real ms.
Pass 2: analyzed script: 4 probe(s), 4 function(s), 0 embed(s), 0 global(s) in
10usr/10sys/11real ms.
Pass 3: translated to C into
"/tmp/stapoq2MDW/stap_baf6e71039a9725fc5cb2616250691db_3376.c" in
20usr/20sys/46real ms.
Pass 4: compiled C into "stap_baf6e71039a9725fc5cb2616250691db_3376.ko" in
3230usr/300sys/6758real ms.
Pass 5: starting run.
bug:echo_char(,/0x2c00000000)
bug:echo_char(0x2c)
bug:echo_char(s/0x7300000000)
bug:echo_char(0x73)
bug:echo_char(t/0x7400000000)
bug:echo_char(0x74)
bug:echo_char(a/0x6100000000)
bug:echo_char(0x61)
nobug:echo_char(s/0x7300000000)
nobug:echo_char(0x73)
nobug:echo_char(t/0x7400000000)
nobug:echo_char(0x74)
nobug:echo_char(a/0x6100000000)
nobug:echo_char(0x61)
nobug:echo_char(p/0x7000000000)
nobug:echo_char(0x70)
Pass 5: run completed in 0usr/50sys/31160real ms.

Tracing ./nobug, where the arg is declared as an int, stap at least reports
the %c value correctly (i.e., [s t a p]).  Tracing ./bug, where the arg is
declared as a char, stap reports these same values as [, s t a].

But in both cases, the %#x specifier following the %c specifier in the
same format string gets it wrong -- the byte order is reversed.  Given
the same value, %#x alone gets it right.

So ./nobug is a misnomer, but at least it demonstrates one less error than
./bug.

-- 
           Summary: printf %c
           Product: systemtap
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: translator
        AssignedTo: systemtap at sources dot redhat dot com
        ReportedBy: jkenisto at us dot ibm dot com


http://sourceware.org/bugzilla/show_bug.cgi?id=6851

------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.


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