diff options
-rwxr-xr-x | dtrace | 79 | ||||
-rw-r--r-- | includes/sys/sdt.h | 408 | ||||
-rw-r--r-- | tapsets.cxx | 230 | ||||
-rw-r--r-- | testsuite/systemtap.base/sdt.exp | 37 | ||||
-rw-r--r-- | testsuite/systemtap.base/sdt_types.stp | 4 | ||||
-rw-r--r-- | testsuite/systemtap.base/static_uprobes.exp | 99 |
6 files changed, 557 insertions, 300 deletions
@@ -12,54 +12,75 @@ # Public License (GPL); either version 2, or (at your option) any # later version. -import os,posix,sys +import os,posix,string,sys from subprocess import call from tempfile import mkstemp class provider: - def open(self, provider, header): + def typedef_append(self, typedefs,this_probe,arg,c): + if (add_typedefs): + split_arg = arg.rsplit(None,1) + type_name = " %s_arg%d" % (this_probe.replace("__","_"),c) + if (len(split_arg) > 1): + typedefs += ("typedef " + arg.replace(" " + split_arg[1].split("[")[0].lstrip("*"),type_name).strip() + "; ") + typedefs += (type_name + type_name + "_v;\n") + else: + typedefs += ("typedef " + arg.strip() + type_name + "; ") + typedefs += (type_name + type_name + "_v;\n") + return typedefs + def generate(self, provider, header, add_typedefs): have_provider = False self.f = open(provider) self.h = open(header,mode='w') self.h.write("/* Generated by the Systemtap dtrace wrapper */\n") self.h.write("\n#include <sys/sdt.h>\n\n") in_comment = False + typedefs = "" while (True): line = self.f.readline() if (line == ""): break - if (line.find("/*") >= 0): + if (line.find("/*") != -1): in_comment = True - if (line.find("*/") >= 0): + if (line.find("*/") != -1): in_comment = False continue if (in_comment): continue - if (line.find("provider") >= 0): + if (line.find("provider") != -1): tokens = line.split() have_provider = True self.provider = tokens[1] - elif (have_provider and line.find("probe ") > 0): + elif (not have_provider): + if (add_typedefs): + self.h.write (line) + elif (have_provider and line.find("probe ") != -1): while (line.find(")") < 0): line += self.f.readline() this_probe = line[line.find("probe ")+5:line.find("(")].strip() this_probe_canon = self.provider.upper() + "_" + this_probe.replace("__","_").upper() args = (line[line.find("(")+1:line.find(")")]) - new_args = "" + args_string = "" + arg = "" i = 0 c = 0 while (i < len(args)): if (args[i:i+1] == ","): - new_args = ('%s%s' % (new_args, args[i])) + args_string = ('%s %s,' % (args_string, arg.strip())) c += 1 + typedefs = self.typedef_append (typedefs,this_probe,arg,c) + arg = "" else: - new_args = new_args + args[i] + arg = arg + args[i] i += 1 - if (len(new_args) == 0): + if (i != 0): + args_string = ('%s %s' % (args_string, arg.strip())) + if (len(args_string) == 0): c = 0 stap_str = "STAP_PROBE(provider,%s" % (this_probe) else: c += 1 + typedefs = self.typedef_append (typedefs,this_probe,arg,c) stap_str = "STAP_PROBE%d(provider,%s" % (c,this_probe) define_str = "#define %s(" % (this_probe_canon) i = 1 @@ -69,13 +90,28 @@ class provider: define_str = define_str + "arg%s" % (i); stap_str = stap_str + ",arg%s" % (i); i += 1 - self.h.write ('/* %s (%s) */\n' % (this_probe_canon,new_args)) + self.h.write ('/* %s (%s) */\n' % (this_probe_canon,args_string)) self.h.write ('#define %s_ENABLED() 1\n' % this_probe_canon) self.h.write (define_str + ") \\\n") self.h.write (stap_str + ")\n\n") + elif (line.find("}") != -1 and have_provider): + have_provider = False + if (add_typedefs): + self.h.write (typedefs) + self.h.close() + def usage (): - print "Usage " + sys.argv[0] + " [-h | -G] -s File.d -o File {Files}" + print "Usage " + sys.argv[0] + " [--help] [-h | -G] -s File.d [-o File]" + +def help (): + usage() + print "Where -h builds a systemtap header file from the .d file" + print " -o specifies an explicit output file name," + print " The default for -G is file.o and -h is file.h" + print " -s specifies the name of the .d input file" + print " -G builds a stub file.o from file.d," + print " which is required by some packages that use dtrace." sys.exit(1) def open_file (arg): @@ -95,10 +131,12 @@ def open_file (arg): if (len (sys.argv) < 2): usage() + sys.exit(1) i = 1 build_header = False build_source = False +add_typedefs = False filename = "" while (i < len (sys.argv)): if (sys.argv[i] == "-o"): @@ -110,7 +148,12 @@ while (i < len (sys.argv)): elif (sys.argv[i] == "-h"): build_header = True elif (sys.argv[i] == "-G"): + build_header = True build_source = True + elif (sys.argv[i] == "--types"): + add_typedefs = True + elif (sys.argv[i] == "--help"): + help() i += 1 if (build_header == False and build_source == False): usage() @@ -120,23 +163,19 @@ if (filename == ""): if (s_filename != ""): (filename,ext) = os.path.splitext(s_filename) filename = os.path.basename(filename) - if (build_header): - filename = filename + ".h" - elif (build_source): - filename = filename + ".o" else: usage sys.exit(1) if (build_header): providers = provider() - providers.open(s_filename, filename) -elif (build_source): + providers.generate(s_filename, filename + ".h", add_typedefs) +if (build_source): (basename,ext) = os.path.splitext(s_filename) basename = os.path.basename(basename) (d,fn) = mkstemp(suffix=".c",prefix=basename) f = open(fn,mode='w') - f.write("static __dtrace () {}\n") + f.write("#include \"" + filename + ".h\"\nstatic __dtrace () {}\n") f.close() - call(["gcc", "-fPIC", "-c", fn, "-o", filename], shell=False) + call(["gcc", "-fPIC", "-I.", "-g", "-c", fn, "-o", filename + ".o"], shell=False) os.remove(fn) diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index fd2c55fb..10639d9c 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -12,6 +12,8 @@ #include <string.h> #include <sys/types.h> +#include <errno.h> + #ifdef __LP64__ #define STAP_PROBE_ADDR "\t.quad " @@ -20,20 +22,22 @@ #endif /* An allocated section .probes that holds the probe names and addrs. */ -#define STAP_PROBE_DATA_(probe) \ +#define STAP_PROBE_DATA_(probe,guard,arg) \ __asm__ volatile (".section .probes, \"a\"\n" \ - "\t.align 8\n" \ + "\t.align 8\n" \ "1:\n\t.asciz " #probe "\n" \ - "\t.align 4\n" \ - "\t.int 0x31425250\n" \ - "\t.align 8\n" \ - STAP_PROBE_ADDR "1b\n" \ - "\t.align 8\n" \ - STAP_PROBE_ADDR "2f\n" \ + "\t.align 4\n" \ + "\t.int " #guard "\n" \ + "\t.align 8\n" \ + STAP_PROBE_ADDR "1b\n" \ + "\t.align 8\n" \ + STAP_PROBE_ADDR #arg "\n" \ "\t.previous\n") -#define STAP_PROBE_DATA(probe) \ - STAP_PROBE_DATA_(#probe) +#define STAP_PROBE_DATA(probe, guard, arg) \ + STAP_PROBE_DATA_(#probe,guard,arg) + +#if ! (defined EXPERIMENTAL_UTRACE_SDT || defined EXPERIMENTAL_KPROBE_SDT) /* These baroque macros are used to create a unique label. */ #define STAP_CONCAT(a,b) a ## b @@ -59,174 +63,331 @@ #define STAP_UNINLINE_LABEL(label) \ __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label -#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) +#if defined __x86_64__ || defined __i386__ || defined __powerpc__ #define STAP_NOP "\tnop " #else #define STAP_NOP "\tnop 0 " #endif +#define STAP_UPROBE_GUARD 0x31425250 + #define STAP_PROBE_(probe) \ do { \ - STAP_PROBE_DATA(probe); \ + STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f); \ __asm__ volatile ("2:\n" \ STAP_NOP); \ } while (0) -#define STAP_PROBE1_(probe,label,parm1) \ -do { \ - STAP_UNINLINE_LABEL(label); \ - volatile __typeof__((parm1)) arg1 = parm1; \ - STAP_UNINLINE; \ - STAP_PROBE_DATA(probe); \ +#define STAP_PROBE1_(probe,label,parm1) \ +do { \ + STAP_UNINLINE_LABEL(label); \ + volatile __typeof__((parm1)) arg1 = parm1; \ + STAP_UNINLINE; \ + STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f); \ label: \ - __asm__ volatile ("2:\n" \ + __asm__ volatile ("2:\n" \ STAP_NOP "/* %0 */" :: "g"(arg1)); \ } while (0) -#define STAP_PROBE2_(probe,label,parm1,parm2) \ -do { \ - STAP_UNINLINE_LABEL(label); \ - volatile __typeof__((parm1)) arg1 = parm1; \ - volatile __typeof__((parm2)) arg2 = parm2; \ - STAP_UNINLINE; \ - STAP_PROBE_DATA(probe); \ - label: \ +#define STAP_PROBE2_(probe,label,parm1,parm2) \ +do { \ + STAP_UNINLINE_LABEL(label); \ + volatile __typeof__((parm1)) arg1 = parm1; \ + volatile __typeof__((parm2)) arg2 = parm2; \ + STAP_UNINLINE; \ + STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f); \ + label: \ __asm__ volatile ("2:\n" \ STAP_NOP "/* %0 %1 */" :: "g"(arg1), "g"(arg2)); \ } while (0) -#define STAP_PROBE3_(probe,label,parm1,parm2,parm3) \ -do { \ - STAP_UNINLINE_LABEL(label); \ - volatile __typeof__((parm1)) arg1 = parm1; \ - volatile __typeof__((parm2)) arg2 = parm2; \ - volatile __typeof__((parm3)) arg3 = parm3; \ - STAP_UNINLINE; \ - STAP_PROBE_DATA(probe); \ - label: \ +#define STAP_PROBE3_(probe,label,parm1,parm2,parm3) \ +do { \ + STAP_UNINLINE_LABEL(label); \ + volatile __typeof__((parm1)) arg1 = parm1; \ + volatile __typeof__((parm2)) arg2 = parm2; \ + volatile __typeof__((parm3)) arg3 = parm3; \ + STAP_UNINLINE; \ + STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f); \ + label: \ __asm__ volatile ("2:\n" \ STAP_NOP "/* %0 %1 %2 */" :: "g"(arg1), "g"(arg2), "g"(arg3)); \ } while (0) -#define STAP_PROBE4_(probe,label,parm1,parm2,parm3,parm4) \ -do { \ - STAP_UNINLINE_LABEL(label); \ - volatile __typeof__((parm1)) arg1 = parm1; \ - volatile __typeof__((parm2)) arg2 = parm2; \ - volatile __typeof__((parm3)) arg3 = parm3; \ - volatile __typeof__((parm4)) arg4 = parm4; \ - STAP_UNINLINE; \ - STAP_PROBE_DATA(probe); \ - label: \ +#define STAP_PROBE4_(probe,label,parm1,parm2,parm3,parm4) \ +do { \ + STAP_UNINLINE_LABEL(label); \ + volatile __typeof__((parm1)) arg1 = parm1; \ + volatile __typeof__((parm2)) arg2 = parm2; \ + volatile __typeof__((parm3)) arg3 = parm3; \ + volatile __typeof__((parm4)) arg4 = parm4; \ + STAP_UNINLINE; \ + STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f); \ + label: \ __asm__ volatile ("2:\n" \ STAP_NOP "/* %0 %1 %2 %3 */" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4)); \ } while (0) -#define STAP_PROBE5_(probe,label,parm1,parm2,parm3,parm4,parm5) \ -do { \ - STAP_UNINLINE_LABEL(label); \ - volatile __typeof__((parm1)) arg1 = parm1; \ - volatile __typeof__((parm2)) arg2 = parm2; \ - volatile __typeof__((parm3)) arg3 = parm3; \ - volatile __typeof__((parm4)) arg4 = parm4; \ - volatile __typeof__((parm5)) arg5 = parm5; \ - STAP_UNINLINE; \ - STAP_PROBE_DATA(probe); \ - label: \ +#define STAP_PROBE5_(probe,label,parm1,parm2,parm3,parm4,parm5) \ +do { \ + STAP_UNINLINE_LABEL(label); \ + volatile __typeof__((parm1)) arg1 = parm1; \ + volatile __typeof__((parm2)) arg2 = parm2; \ + volatile __typeof__((parm3)) arg3 = parm3; \ + volatile __typeof__((parm4)) arg4 = parm4; \ + volatile __typeof__((parm5)) arg5 = parm5; \ + STAP_UNINLINE; \ + STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f); \ + label: \ __asm__ volatile ("2:\n" \ STAP_NOP "/* %0 %1 %2 %3 %4 */" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5)); \ } while (0) #define STAP_PROBE6_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6) \ -do { \ - STAP_UNINLINE_LABEL(label); \ - volatile __typeof__((parm1)) arg1 = parm1; \ - volatile __typeof__((parm2)) arg2 = parm2; \ - volatile __typeof__((parm3)) arg3 = parm3; \ - volatile __typeof__((parm4)) arg4 = parm4; \ - volatile __typeof__((parm5)) arg5 = parm5; \ - volatile __typeof__((parm6)) arg6 = parm6; \ - STAP_UNINLINE; \ - STAP_PROBE_DATA(probe); \ - label: \ +do { \ + STAP_UNINLINE_LABEL(label); \ + volatile __typeof__((parm1)) arg1 = parm1; \ + volatile __typeof__((parm2)) arg2 = parm2; \ + volatile __typeof__((parm3)) arg3 = parm3; \ + volatile __typeof__((parm4)) arg4 = parm4; \ + volatile __typeof__((parm5)) arg5 = parm5; \ + volatile __typeof__((parm6)) arg6 = parm6; \ + STAP_UNINLINE; \ + STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f); \ + label: \ __asm__ volatile ("2:\n" \ STAP_NOP "/* %0 %1 %2 %3 %4 %5 */" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6)); \ } while (0) -#define STAP_PROBE7_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ -do { \ - STAP_UNINLINE_LABEL(label); \ - volatile __typeof__((parm1)) arg1 = parm1; \ - volatile __typeof__((parm2)) arg2 = parm2; \ - volatile __typeof__((parm3)) arg3 = parm3; \ - volatile __typeof__((parm4)) arg4 = parm4; \ - volatile __typeof__((parm5)) arg5 = parm5; \ - volatile __typeof__((parm6)) arg6 = parm6; \ - volatile __typeof__((parm7)) arg7 = parm7; \ - STAP_UNINLINE; \ - STAP_PROBE_DATA(probe); \ - label: \ +#define STAP_PROBE7_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ +do { \ + STAP_UNINLINE_LABEL(label); \ + volatile __typeof__((parm1)) arg1 = parm1; \ + volatile __typeof__((parm2)) arg2 = parm2; \ + volatile __typeof__((parm3)) arg3 = parm3; \ + volatile __typeof__((parm4)) arg4 = parm4; \ + volatile __typeof__((parm5)) arg5 = parm5; \ + volatile __typeof__((parm6)) arg6 = parm6; \ + volatile __typeof__((parm7)) arg7 = parm7; \ + STAP_UNINLINE; \ + STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f); \ + label: \ __asm__ volatile ("2:\n" \ STAP_NOP "/* %0 %1 %2 %3 %4 %5 %6 */" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6), "g"(arg7)); \ } while (0) #define STAP_PROBE8_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ -do { \ - STAP_UNINLINE_LABEL(label); \ - volatile __typeof__((parm1)) arg1 = parm1; \ - volatile __typeof__((parm2)) arg2 = parm2; \ - volatile __typeof__((parm3)) arg3 = parm3; \ - volatile __typeof__((parm4)) arg4 = parm4; \ - volatile __typeof__((parm5)) arg5 = parm5; \ - volatile __typeof__((parm6)) arg6 = parm6; \ - volatile __typeof__((parm7)) arg7 = parm7; \ - volatile __typeof__((parm8)) arg8 = parm8; \ - STAP_UNINLINE; \ - STAP_PROBE_DATA(probe); \ - label: \ +do { \ + STAP_UNINLINE_LABEL(label); \ + volatile __typeof__((parm1)) arg1 = parm1; \ + volatile __typeof__((parm2)) arg2 = parm2; \ + volatile __typeof__((parm3)) arg3 = parm3; \ + volatile __typeof__((parm4)) arg4 = parm4; \ + volatile __typeof__((parm5)) arg5 = parm5; \ + volatile __typeof__((parm6)) arg6 = parm6; \ + volatile __typeof__((parm7)) arg7 = parm7; \ + volatile __typeof__((parm8)) arg8 = parm8; \ + STAP_UNINLINE; \ + STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f); \ + label: \ __asm__ volatile ("2:\n" \ STAP_NOP "/* %0 %1 %2 %3 %4 %5 %6 %7 */" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6), "g"(arg7), "g"(arg8)); \ } while (0) #define STAP_PROBE9_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ -do { \ - STAP_UNINLINE_LABEL(label); \ - volatile __typeof__((parm1)) arg1 = parm1; \ - volatile __typeof__((parm2)) arg2 = parm2; \ - volatile __typeof__((parm3)) arg3 = parm3; \ - volatile __typeof__((parm4)) arg4 = parm4; \ - volatile __typeof__((parm5)) arg5 = parm5; \ - volatile __typeof__((parm6)) arg6 = parm6; \ - volatile __typeof__((parm7)) arg7 = parm7; \ - volatile __typeof__((parm8)) arg8 = parm8; \ - volatile __typeof__((parm9)) arg9 = parm9; \ - STAP_UNINLINE; \ - STAP_PROBE_DATA(probe); \ - label: \ +do { \ + STAP_UNINLINE_LABEL(label); \ + volatile __typeof__((parm1)) arg1 = parm1; \ + volatile __typeof__((parm2)) arg2 = parm2; \ + volatile __typeof__((parm3)) arg3 = parm3; \ + volatile __typeof__((parm4)) arg4 = parm4; \ + volatile __typeof__((parm5)) arg5 = parm5; \ + volatile __typeof__((parm6)) arg6 = parm6; \ + volatile __typeof__((parm7)) arg7 = parm7; \ + volatile __typeof__((parm8)) arg8 = parm8; \ + volatile __typeof__((parm9)) arg9 = parm9; \ + STAP_UNINLINE; \ + STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f); \ + label: \ __asm__ volatile ("2:\n" \ STAP_NOP "/* %0 %1 %2 %3 %4 %5 %6 %7 %8 */" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6), "g"(arg7), "g"(arg8), "g"(arg9)); \ } while (0) #define STAP_PROBE10_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ -do { \ - STAP_UNINLINE_LABEL(label); \ - volatile __typeof__((parm1)) arg1 = parm1; \ - volatile __typeof__((parm2)) arg2 = parm2; \ - volatile __typeof__((parm3)) arg3 = parm3; \ - volatile __typeof__((parm4)) arg4 = parm4; \ - volatile __typeof__((parm5)) arg5 = parm5; \ - volatile __typeof__((parm6)) arg6 = parm6; \ - volatile __typeof__((parm7)) arg7 = parm7; \ - volatile __typeof__((parm8)) arg8 = parm8; \ - volatile __typeof__((parm9)) arg9 = parm9; \ - volatile __typeof__((parm10)) arg10 = parm10; \ - STAP_UNINLINE; \ - STAP_PROBE_DATA(probe); \ - label: \ +do { \ + STAP_UNINLINE_LABEL(label); \ + volatile __typeof__((parm1)) arg1 = parm1; \ + volatile __typeof__((parm2)) arg2 = parm2; \ + volatile __typeof__((parm3)) arg3 = parm3; \ + volatile __typeof__((parm4)) arg4 = parm4; \ + volatile __typeof__((parm5)) arg5 = parm5; \ + volatile __typeof__((parm6)) arg6 = parm6; \ + volatile __typeof__((parm7)) arg7 = parm7; \ + volatile __typeof__((parm8)) arg8 = parm8; \ + volatile __typeof__((parm9)) arg9 = parm9; \ + volatile __typeof__((parm10)) arg10 = parm10; \ + STAP_UNINLINE; \ + STAP_PROBE_DATA(probe,STAP_UPROBE_GUARD,2f); \ + label: \ __asm__ volatile ("2:\n" \ STAP_NOP "/* %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 */" :: "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6), "g"(arg7), "g"(arg8), "g"(arg9), "g"(arg10)); \ } while (0) +#else /* ! (defined EXPERIMENTAL_UTRACE_SDT || defined EXPERIMENTAL_KPROBE_SDT) */ +#include <unistd.h> +#include <sys/syscall.h> +# if defined (__USE_ANSI) +extern long int syscall (long int __sysno, ...) __THROW; +# endif +# if defined EXPERIMENTAL_KPROBE_SDT +# define STAP_SYSCALL __NR_getegid +# define STAP_GUARD 0x32425250 +# define GETTID 0 +# elif defined EXPERIMENTAL_UTRACE_SDT +# define STAP_SYSCALL 0xbead +# define STAP_GUARD 0x33425250 +# define GETTID syscall(SYS_gettid) +# endif + +#include <sys/syscall.h> + +#define STAP_PROBE_(probe) \ +do { \ + STAP_PROBE_DATA(probe,STAP_SYSCALL,0); \ + syscall (STAP_SYSCALL, #probe, GETTID); \ + } while (0) + +#define STAP_PROBE1_(probe,label,parm1) \ +do { \ + STAP_PROBE_DATA(probe,STAP_GUARD,1); \ + syscall (STAP_SYSCALL, #probe, GETTID, parm1); \ + } while (0) + +#define STAP_PROBE2_(probe,label,parm1,parm2) \ +do { \ + __extension__ struct {size_t arg1 __attribute__((aligned(8))); \ + size_t arg2 __attribute__((aligned(8)));} \ + stap_probe2_args = {(size_t)parm1, (size_t)parm2}; \ + STAP_PROBE_DATA(probe,STAP_GUARD,2); \ + syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe2_args); \ + } while (0) + +#define STAP_PROBE3_(probe,label,parm1,parm2,parm3) \ +do { \ + __extension__ struct {size_t arg1 __attribute__((aligned(8))); \ + size_t arg2 __attribute__((aligned(8))); \ + size_t arg3 __attribute__((aligned(8)));} \ + stap_probe3_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3}; \ + STAP_PROBE_DATA(probe,STAP_GUARD,3); \ + syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe3_args); \ + } while (0) + +#define STAP_PROBE4_(probe,label,parm1,parm2,parm3,parm4) \ +do { \ + __extension__ struct {size_t arg1 __attribute__((aligned(8))); \ + size_t arg2 __attribute__((aligned(8))); \ + size_t arg3 __attribute__((aligned(8))); \ + size_t arg4 __attribute__((aligned(8)));} \ + stap_probe4_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4}; \ + STAP_PROBE_DATA(probe,STAP_GUARD,4); \ + syscall (STAP_SYSCALL, #probe, GETTID,&stap_probe4_args); \ + } while (0) + +#define STAP_PROBE5_(probe,label,parm1,parm2,parm3,parm4,parm5) \ +do { \ + __extension__ struct {size_t arg1 __attribute__((aligned(8))); \ + size_t arg2 __attribute__((aligned(8))); \ + size_t arg3 __attribute__((aligned(8))); \ + size_t arg4 __attribute__((aligned(8))); \ + size_t arg5 __attribute__((aligned(8)));} \ + stap_probe5_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ + (size_t)parm5}; \ + STAP_PROBE_DATA(probe,STAP_GUARD,5); \ + syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe5_args); \ + } while (0) + +#define STAP_PROBE6_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6) \ +do { \ + __extension__ struct {size_t arg1 __attribute__((aligned(8))); \ + size_t arg2 __attribute__((aligned(8))); \ + size_t arg3 __attribute__((aligned(8))); \ + size_t arg4 __attribute__((aligned(8))); \ + size_t arg5 __attribute__((aligned(8))); \ + size_t arg6 __attribute__((aligned(8)));} \ + stap_probe6_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ + (size_t)parm5, (size_t)parm6}; \ + STAP_PROBE_DATA(probe,STAP_GUARD,6); \ + syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe6_args); \ + } while (0) + +#define STAP_PROBE7_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ +do { \ + __extension__ struct {size_t arg1 __attribute__((aligned(8))); \ + size_t arg2 __attribute__((aligned(8))); \ + size_t arg3 __attribute__((aligned(8))); \ + size_t arg4 __attribute__((aligned(8))); \ + size_t arg5 __attribute__((aligned(8))); \ + size_t arg6 __attribute__((aligned(8))); \ + size_t arg7 __attribute__((aligned(8)));} \ + stap_probe7_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ + (size_t)parm5, (size_t)parm6, (size_t)parm7}; \ + STAP_PROBE_DATA(probe,STAP_GUARD,7); \ + syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe7_args); \ + } while (0) + +#define STAP_PROBE8_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ +do { \ + __extension__ struct {size_t arg1 __attribute__((aligned(8))); \ + size_t arg2 __attribute__((aligned(8))); \ + size_t arg3 __attribute__((aligned(8))); \ + size_t arg4 __attribute__((aligned(8))); \ + size_t arg5 __attribute__((aligned(8))); \ + size_t arg6 __attribute__((aligned(8))); \ + size_t arg7 __attribute__((aligned(8))); \ + size_t arg8 __attribute__((aligned(8)));} \ + stap_probe8_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ + (size_t)parm5, (size_t)parm6, (size_t)parm7, (size_t)parm8}; \ + STAP_PROBE_DATA(probe,STAP_GUARD,8); \ + syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe8_args); \ + } while (0) + +#define STAP_PROBE9_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ +do { \ + __extension__ struct {size_t arg1 __attribute__((aligned(8))); \ + size_t arg2 __attribute__((aligned(8))); \ + size_t arg3 __attribute__((aligned(8))); \ + size_t arg4 __attribute__((aligned(8))); \ + size_t arg5 __attribute__((aligned(8))); \ + size_t arg6 __attribute__((aligned(8))); \ + size_t arg7 __attribute__((aligned(8))); \ + size_t arg8 __attribute__((aligned(8))); \ + size_t arg9 __attribute__((aligned(8)));} \ + stap_probe9_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ + (size_t)parm5, (size_t)parm6, (size_t)parm7, (size_t)parm8, (size_t)parm9}; \ + STAP_PROBE_DATA(probe,STAP_GUARD,9); \ + syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe9_args); \ + } while (0) + +#define STAP_PROBE10_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ +do { \ + __extension__ struct {size_t arg1 __attribute__((aligned(8))); \ + size_t arg2 __attribute__((aligned(8))); \ + size_t arg3 __attribute__((aligned(8))); \ + size_t arg4 __attribute__((aligned(8))); \ + size_t arg5 __attribute__((aligned(8))); \ + size_t arg6 __attribute__((aligned(8))); \ + size_t arg7 __attribute__((aligned(8))); \ + size_t arg8 __attribute__((aligned(8))); \ + size_t arg9 __attribute__((aligned(8))); \ + size_t arg10 __attribute__((aligned(8)));} \ + stap_probe10_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ + (size_t)parm5, (size_t)parm6, (size_t)parm7, (size_t)parm8, (size_t)parm9, (size_t)parm10}; \ + STAP_PROBE_DATA(probe,STAP_GUARD,10); \ + syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe10_args); \ + } while (0) + +#endif + #define STAP_PROBE(provider,probe) \ STAP_PROBE_(probe) #define STAP_PROBE1(provider,probe,parm1) \ @@ -270,5 +431,6 @@ STAP_PROBE7(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7) STAP_PROBE8(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) #define DTRACE_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ STAP_PROBE9(provider,probe,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) + #endif /* sys/sdt.h */ diff --git a/tapsets.cxx b/tapsets.cxx index 79a7aa93..0da61d9e 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -672,6 +672,8 @@ struct dwarf_builder: public derived_probe_builder string probe_name; probe_table(string & mark_name, systemtap_session & sess, dwflpp * dw); bool get_next_probe(); + void convert_probe(probe *new_base); + void convert_location(probe *new_base, probe_point *new_location); private: bool have_probes; @@ -800,6 +802,113 @@ dwarf_builder::probe_table::get_next_probe() return false; } + +void +dwarf_builder::probe_table::convert_probe (probe *new_base) +{ + block *b = ((block*)(new_base->body)); + if (probe_type == utrace_type) + { + // Generate: if ($syscall != 0xbead) next; + if_statement *issc = new if_statement; + issc->thenblock = new next_statement; + issc->elseblock = NULL; + issc->tok = new_base->body->tok; + comparison *besc = new comparison; + besc->op = "!="; + besc->tok = new_base->body->tok; + functioncall* n = new functioncall; + n->tok = new_base->body->tok; + n->function = "_utrace_syscall_nr"; + n->referent = 0; + besc->left = n; + literal_number* fake_syscall = new literal_number(0xbead); + fake_syscall->tok = new_base->body->tok; + besc->right = fake_syscall; + issc->condition = besc; + b->statements.insert(b->statements.begin(),(statement*) issc); + + // Generate: if (ulong_arg(2) != task_tid(task_current())) next; + if_statement *istid = new if_statement; + istid->thenblock = new next_statement; + istid->elseblock = NULL; + istid->tok = new_base->body->tok; + comparison *betid = new comparison; + betid->op = "!="; + betid->tok = new_base->body->tok; + functioncall* task_tid = new functioncall; + task_tid->tok = new_base->body->tok; + task_tid->function = "task_tid"; + task_tid->referent = 0; + functioncall* task_current = new functioncall; + task_current->tok = new_base->body->tok; + task_current->function = "task_current"; + task_current->referent = 0; + task_tid->args.push_back(task_current); + betid->left = task_tid; + functioncall *arg2tid = new functioncall; + arg2tid->tok = new_base->body->tok; + arg2tid->function = "ulong_arg"; + arg2tid->tok = new_base->body->tok; + literal_number* littid = new literal_number(2); + littid->tok = new_base->body->tok; + arg2tid->args.push_back(littid); + + betid->right = arg2tid; + istid->condition = betid; + b->statements.insert(b->statements.begin(),(statement*) istid); + } + + // Generate: if (arg1 != mark("label")) next; + functioncall *fc = new functioncall; + fc->function = "ulong_arg"; + fc->tok = new_base->body->tok; + literal_number* num = new literal_number(1); + num->tok = new_base->body->tok; + fc->args.push_back(num); + + functioncall *fcus = new functioncall; + fcus->function = "user_string"; + fcus->type = pe_string; + fcus->tok = new_base->body->tok; + fcus->args.push_back(fc); + + if_statement *is = new if_statement; + is->thenblock = new next_statement; + is->elseblock = NULL; + is->tok = new_base->body->tok; + comparison *be = new comparison; + be->op = "!="; + be->tok = new_base->body->tok; + be->left = fcus; + be->right = new literal_string(mark_name); + is->condition = be; + b->statements.insert(b->statements.begin(),(statement*) is); +} + + +void +dwarf_builder::probe_table::convert_location (probe *new_base, + probe_point *new_location) +{ + if (probe_type == kprobe_type) + { + new_location->components[0]->functor = "kernel"; + new_location->components[0]->arg = NULL; + new_location->components[1]->functor = "function"; + new_location->components[1]->arg = new literal_string("*getegid*"); + new_base->locations.push_back(new_location); + } + else if (probe_type == utrace_type) + { + // process("executable").syscall + new_location->components[1]->functor = "syscall"; + new_location->components[1]->arg = NULL; + new_base->locations.push_back(new_location); + } +} + + dwarf_query::dwarf_query(systemtap_session & sess, probe * base_probe, probe_point * base_loc, @@ -3234,12 +3343,13 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) bool lvalue = is_active_lvalue(e); functioncall *fc = new functioncall; - if (arg_count < 6) + // First two args are hidden: 1. pointer to probe name 2. task id + if (arg_count < 2) { fc->function = "ulong_arg"; fc->type = pe_long; fc->tok = e->tok; - literal_number* num = new literal_number(argno + 1); + literal_number* num = new literal_number(argno + 2); num->tok = e->tok; fc->args.push_back(num); } @@ -3252,7 +3362,7 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) functioncall *get_arg1 = new functioncall; get_arg1->function = "pointer_arg"; get_arg1->tok = e->tok; - literal_number* num = new literal_number(2); + literal_number* num = new literal_number(3); num->tok = e->tok; get_arg1->args.push_back(num); @@ -3365,62 +3475,8 @@ dwarf_builder::build(systemtap_session & sess, return; } - else if (probe_table.probe_type == probe_table.kprobe_type) - { - do - { - probe *new_base = new probe; - *new_base = *base; - - new_base->body = deep_copy_visitor::deep_copy(base->body); - probe_point *new_location = new probe_point; - *new_location = *location; - new_base->locations.clear(); - - block *b = ((block*)(new_base->body)); - functioncall *fc = new functioncall; - fc->function = "ulong_arg"; - fc->tok = new_base->body->tok; - literal_number* num = new literal_number(1); - num->tok = new_base->body->tok; - fc->args.push_back(num); - - functioncall *fcus = new functioncall; - fcus->function = "user_string"; - fcus->type = pe_string; - fcus->tok = new_base->body->tok; - fcus->args.push_back(fc); - - // Generate: if (arg1 != mark("label")) next; - if_statement *is = new if_statement; - is->thenblock = new next_statement; - is->elseblock = NULL; - is->tok = new_base->body->tok; - comparison *be = new comparison; - be->op = "!="; - be->tok = new_base->body->tok; - be->left = fcus; - be->right = new literal_string(probe_table.mark_name); - is->condition = be; - b->statements.insert(b->statements.begin(),(statement*) is); - - // Now expand the local variables in the probe body - sdt_var_expanding_visitor svv (module_name, probe_table.mark_name, - probe_table.probe_arg, true); - new_base->body = svv.require (new_base->body); - new_location->components[0]->functor = "kernel"; - new_location->components[0]->arg = NULL; - new_location->components[1]->functor = "function"; - new_location->components[1]->arg = new literal_string("*getegid*"); - new_base->locations.push_back(new_location); - - derive_probes(sess, new_base, finished_results); - } - while (probe_table.get_next_probe()); - return; - } - - else if (probe_table.probe_type == probe_table.utrace_type) + else if (probe_table.probe_type == probe_table.kprobe_type + || probe_table.probe_type == probe_table.utrace_type) { do { @@ -3432,63 +3488,13 @@ dwarf_builder::build(systemtap_session & sess, *new_location = *location; new_base->locations.clear(); - block *b = ((block*)(new_base->body)); - - // Generate: if ($syscall != 0xbead) next; - if_statement *issc = new if_statement; - issc->thenblock = new next_statement; - issc->elseblock = NULL; - issc->tok = new_base->body->tok; - comparison *besc = new comparison; - besc->op = "!="; - besc->tok = new_base->body->tok; - functioncall* n = new functioncall; - n->tok = new_base->body->tok; - n->function = "_utrace_syscall_nr"; - n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session - besc->left = n; - literal_number* fake_syscall = new literal_number(0xbead); - fake_syscall->tok = new_base->body->tok; - besc->right = fake_syscall; - issc->condition = besc; - b->statements.insert(b->statements.begin(),(statement*) issc); - - functioncall *fc = new functioncall; - fc->function = "ulong_arg"; - fc->tok = new_base->body->tok; - literal_number* num = new literal_number(1); - num->tok = new_base->body->tok; - fc->args.push_back(num); - - functioncall *fcus = new functioncall; - fcus->function = "user_string"; - fcus->type = pe_string; - fcus->tok = new_base->body->tok; - fcus->args.push_back(fc); - - // Generate: if (arg1 != mark("label")) next; - if_statement *is = new if_statement; - is->thenblock = new next_statement; - is->elseblock = NULL; - is->tok = new_base->body->tok; - comparison *be = new comparison; - be->op = "!="; - be->tok = new_base->body->tok; - be->left = fcus; - be->right = new literal_string(probe_table.mark_name); - is->condition = be; - b->statements.insert(b->statements.begin(),(statement*) is); + probe_table.convert_probe(new_base); - // Now expand the local variables in the probe body + // Expand the local variables in the probe body sdt_var_expanding_visitor svv (module_name, probe_table.mark_name, probe_table.probe_arg, true); new_base->body = svv.require (new_base->body); - - // process("executable").syscall - new_location->components[1]->functor = "syscall"; - new_location->components[1]->arg = NULL; - new_base->locations.push_back(new_location); - + probe_table.convert_location(new_base, new_location); derive_probes(sess, new_base, finished_results); } while (probe_table.get_next_probe()); diff --git a/testsuite/systemtap.base/sdt.exp b/testsuite/systemtap.base/sdt.exp index d24093e0..ea025391 100644 --- a/testsuite/systemtap.base/sdt.exp +++ b/testsuite/systemtap.base/sdt.exp @@ -12,6 +12,14 @@ set ::result_string {1 set extra_flags {{""} {additional_flags=-std=gnu89} {additional_flags=-ansi} {additional_flags=-pedantic} {additional_flags=-ansi additional_flags=-pedantic} {additional_flags=-O2} {additional_flags="-O3"}} +set pbtype_flags {{""} {additional_flags=-DEXPERIMENTAL_UTRACE_SDT} {additional_flags=-DEXPERIMENTAL_KPROBE_SDT}} +set pbtype_mssgs {{uprobe} {utrace} {kprobe}} + +# Iterate pbtype_flags +for {set p 0} {$p < [llength $pbtype_flags]} {incr p} { +set pbtype_flag [lindex $pbtype_flags $p] +set pbtype_mssg [lindex $pbtype_mssgs $p] + # Iterate extra_flags, trying each with C and C++ for {set i 0} {$i < [llength $extra_flags]} {incr i} { set extra_flag [lindex $extra_flags $i] @@ -22,24 +30,24 @@ set test_flags "additional_flags=-g" set test_flags "$test_flags additional_flags=-I$srcdir/../includes/sys" set test_flags "$test_flags additional_flags=-Wall" set test_flags "$test_flags additional_flags=-Wextra" -set test_flags "$test_flags additional_flags=-Werror" +set test_flags "$test_flags additional_flags=-Werror $pbtype_flag" set saveidx 0 set res [target_compile $srcdir/$subdir/$test.c $testprog executable "$test_flags $extra_flag"] if { $res != "" } { verbose "target_compile failed: $res" 2 - fail "compiling $test.c $extra_flag" - untested "$test $extra_flag" + fail "compiling $test.c $extra_flag $pbtype_mssg" + untested "$test $extra_flag $pbtype_mssg" continue } else { - pass "compiling $test.c $extra_flag" + pass "compiling $test.c $extra_flag $pbtype_mssg" } if {[installtest_p] && [utrace_p]} { - stap_run3 "$test $extra_flag" $srcdir/$subdir/$test.stp $testprog -c ./$testprog + stap_run3 "$test $extra_flag $pbtype_mssg" $srcdir/$subdir/$test.stp $testprog -c ./$testprog } else { - untested "$test $extra_flag" + untested "$test $extra_flag $pbtype_mssg" } catch {exec rm -f $testprog} @@ -50,22 +58,27 @@ set test_flags "additional_flags=-g" set test_flags "$test_flags additional_flags=-I$srcdir/../includes/sys" set test_flags "$test_flags additional_flags=-Wall" set test_flags "$test_flags additional_flags=-Werror" -set test_flags "$test_flags additional_flags=-x additional_flags=c++" +set test_flags "$test_flags additional_flags=-x additional_flags=c++ $pbtype_flag" set res [target_compile $srcdir/$subdir/$test.c $testprog executable "$test_flags $extra_flag"] if { $res != "" } { verbose "target_compile failed: $res" 2 - fail "compiling $test.c c++ $extra_flag" - untested "$test $extra_flag" + fail "compiling $test.c c++ $extra_flag $pbtype_mssg" + untested "$test $extra_flag $pbtype_mssg" continue } else { - pass "compiling $test.c c++ $extra_flag" + pass "compiling $test.c c++ $extra_flag $pbtype_mssg" } if {[installtest_p] && [utrace_p]} { - stap_run3 "$test c++ $extra_flag" $srcdir/$subdir/$test.stp $testprog -c ./$testprog + stap_run3 "$test c++ $extra_flag $pbtype_mssg" $srcdir/$subdir/$test.stp $testprog -c ./$testprog } else { - untested "$test c++ $extra_flag" + untested "$test c++ $extra_flag $pbtype_mssg $pbtype_mssg" } catch {exec rm -f $testprog} + +# for {set i 0} {$i < [llength $extra_flags]} +} + +# for {set i 0} {$i < [llength $pbtype_flags]} } diff --git a/testsuite/systemtap.base/sdt_types.stp b/testsuite/systemtap.base/sdt_types.stp index 654b0d18..5f9ebcab 100644 --- a/testsuite/systemtap.base/sdt_types.stp +++ b/testsuite/systemtap.base/sdt_types.stp @@ -68,9 +68,9 @@ probe process(@1).mark("short_int_var") probe process(@1).mark("const_short_int_var") { - if ($arg1 != -32767) + if ($arg1 != -32767) printf("FAIL: const_short_int_var\n") - else + else printf("PASS: const_short_int_var\n") } diff --git a/testsuite/systemtap.base/static_uprobes.exp b/testsuite/systemtap.base/static_uprobes.exp index 1e53d5d3..41dc3ec0 100644 --- a/testsuite/systemtap.base/static_uprobes.exp +++ b/testsuite/systemtap.base/static_uprobes.exp @@ -1,21 +1,21 @@ -set test "static_uprobes" +set test "static_user_markers" # Test miscellaneous features of .mark probes # Compile a C program to use as the user-space probing target -set sup_srcpath "[pwd]/static_uprobes.c" -set sup_exepath "[pwd]/static_uprobes.x" -set supcplus_exepath "[pwd]/static_uprobes_cplus.x" +set sup_srcpath "[pwd]/static_user_markers.c" +set sup_exepath "[pwd]/static_user_markers.x" +set supcplus_exepath "[pwd]/static_user_markers_cplus.x" set fp [open $sup_srcpath "w"] puts $fp " #include <stdlib.h> #define USE_STAP_PROBE 1 -#include \"static_uprobes.h\" +#include \"static_user_markers_.h\" void bar (int i) { - STATIC_UPROBES_TEST_PROBE_2(i); + STATIC_USER_MARKERS_TEST_PROBE_2(i); if (i == 0) i = 1000; STAP_PROBE1(static_uprobes,test_probe_2,i); @@ -27,7 +27,7 @@ baz (int i, char* s) STAP_PROBE1(static_uprobes,test_probe_0,i); if (i == 0) i = 1000; - STATIC_UPROBES_TEST_PROBE_3(i,s); + STATIC_USER_MARKERS_TEST_PROBE_3(i,s); } void @@ -35,7 +35,7 @@ buz (int parm) { if (parm == 0) parm = 1000; - DTRACE_PROBE1(static_uprobes,test_probe_4,parm); + DTRACE_PROBE1(static_user_markers,test_probe_4,parm); } int @@ -48,33 +48,33 @@ main () " close $fp -set sup_stppath "[pwd]/static_uprobes.stp" +set sup_stppath "[pwd]/static_user_markers.stp" set fp [open $sup_stppath "w"] puts $fp " -probe process(\"static_uprobes.x\").mark(\"test_probe_0\") +probe process(\"static_user_markers.x\").mark(\"test_probe_0\") { printf(\"In test_probe_0 probe %#x\\n\", \$arg1) } -probe process(\"static_uprobes.x\").mark(\"test_probe_2\") +probe process(\"static_user_markers.x\").mark(\"test_probe_2\") { printf(\"In test_probe_2 probe %#x\\n\", \$arg1) } -probe process(\"static_uprobes.x\").mark(\"test_probe_3\") +probe process(\"static_user_markers.x\").mark(\"test_probe_3\") { printf(\"In test_probe_3 probe %#x %#x\\n\", \$arg1, \$arg2) } -probe process(\"static_uprobes.x\").mark(\"test_probe_4\") +probe process(\"static_user_markers.x\").mark(\"test_probe_4\") { printf(\"In test_probe_4 dtrace probe %#x\\n\", \$arg1) } " close $fp -set sup_dpath "[pwd]/static_uprobes.d" -set sup_hpath "[pwd]/static_uprobes.h" +set sup_dpath "[pwd]/static_user_markers_.d" +set sup_hpath "[pwd]/static_user_markers_.h" set fp [open $sup_dpath "w"] puts $fp " -provider static_uprobes { +provider static_user_markers { probe test_probe_1 (); probe test_probe_2 (int i); probe test_probe_3 (int i, char* x); @@ -97,7 +97,9 @@ if {[file exists $sup_hpath]} then { pass "$test dtrace" } else { fail "$test dtrace" + if { $verbose == 0 } { catch {exec rm -f $sup_srcpath $sup_hpath $sup_stppath} + } return } @@ -107,25 +109,38 @@ if {[installtest_p]} { set sdtdir $srcdir/../includes } +set pbtype_flags {{""} {additional_flags=-DEXPERIMENTAL_UTRACE_SDT} {additional_flags=-DEXPERIMENTAL_KPROBE_SDT}} +set pbtype_mssgs {{uprobe} {utrace} {kprobe}} + +# Iterate pbtype_flags +for {set i 0} {$i < [llength $pbtype_flags]} {incr i} { +set pbtype_flag [lindex $pbtype_flags $i] +set pbtype_mssg [lindex $pbtype_mssgs $i] +set testprog "sdt.c.exe.$i" + set sup_flags "additional_flags=-I$srcdir/../includes/sys" set sup_flags "$sup_flags additional_flags=-I$sdtdir" set sup_flags "$sup_flags additional_flags=-g" set sup_flags "$sup_flags additional_flags=-O" -set sup_flags "$sup_flags additional_flags=-I." +set sup_flags "$sup_flags additional_flags=-I. $pbtype_flag" set res [target_compile $sup_srcpath $sup_exepath executable $sup_flags] if { $res != "" } { verbose "target_compile failed: $res" 2 - fail "$test compiling C -g" + fail "$test compiling -g $pbtype_mssg" + if { $verbose == 0 } { catch {exec rm -f $sup_srcpath $sup_hpath $sup_stppath} + } return } else { - pass "$test compiling C -g" + pass "$test compiling -g $pbtype_mssg" } if {![installtest_p]} {untested $test; return} if {![utrace_p]} { untested "$test" + if { $verbose == 0 } { catch {exec rm -f $sup_srcpath} + } return } @@ -141,24 +156,33 @@ expect { -re {In test_probe_0 probe 0x3} { incr ok; exp_continue } -re {In test_probe_3 probe 0x3 0x[0-9a-f][0-9a-f]} { incr ok; exp_continue } -re {In test_probe_4 dtrace probe 0x4} { incr ok; exp_continue } - timeout { fail "$test C (timeout)" } + timeout { fail "$test (timeout)" } eof { } } wait -if {$ok == 5} { pass "$test C" } { fail "$test C ($ok)" } +if {$ok == 5} { + pass "$test $pbtype_mssg" +} else { + if { $pbtype_mssg == "uprobe" } { + fail "$test ($ok) $pbtype_mssg" + } else { + # probe fires multiple times + xfail "$test ($ok) $pbtype_mssg" + } +} # Test passing various C types to .mark probes -set sup_flags "$sup_flags additional_flags=-O0" +set sup_flags "$sup_flags additional_flags=-O0 $pbtype_flag" set res [target_compile $srcdir/$subdir/sdt_types.c sdt_types.x executable $sup_flags] if { $res != "" } { verbose "target_compile failed: $res" 2 - fail "$test compiling types -g" + fail "$test compiling types -g $pbtype_mssg" return } else { - pass "$test compiling types -g" + pass "$test compiling types -g $pbtype_mssg" } set ok 0 @@ -169,16 +193,22 @@ expect { -timeout 180 -re {FAIL: [a-z_]+var} { regexp " .*$" $expect_out(0,string) s; incr ok; set fail "$fail $s"; exp_continue } - timeout { fail "$test C (timeout)" } + timeout { fail "$test (timeout) } eof { } } wait -if { $ok != 0 } { - fail "$test $fail" +set pbtype_mssgs {{uprobe} {utrace} {kprobe}} +if { $ok != 0} { + if { $pbtype_mssg == "uprobe" } { + fail "$test $fail $pbtype_mssg" + } else { + # (needs cast) + xfail "$test $fail $pbtype_mssg" + } } else { - pass "$test types" + pass "$test types $pbtype_mssg" } # Test .mark probe wildcard matching @@ -188,14 +218,21 @@ spawn stap -l "process(\"./sdt_types.x\").mark(\"*\")" expect { -timeout 180 -re {mark\(\"[a-z_]+\"\)} { incr ok; exp_continue } - timeout { fail "$test C (timeout)" } + timeout { fail "$test (timeout)" } eof { } } if { $ok == 45 } { - pass "$test wildcard" + pass "$test wildcard $pbtype_mssg" } else { - fail "$test wildcard ($ok)" + if { $pbtype_mssg == "uprobe" } { + fail "$test wildcard ($ok) $pbtype_mssg" + } else { + xfail "$test wildcard ($ok) $pbtype_mssg" + } +} + +# for {set i 0} } if { $verbose == 0 } { |