diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | elaborate.cxx | 59 | ||||
-rw-r--r-- | elaborate.h | 2 | ||||
-rw-r--r-- | runtime/ChangeLog | 6 | ||||
-rw-r--r-- | runtime/stack-i386.c | 2 | ||||
-rw-r--r-- | runtime/stack-x86_64.c | 2 | ||||
-rw-r--r-- | runtime/stack.c | 7 | ||||
-rw-r--r-- | stap.1.in | 42 | ||||
-rwxr-xr-x | testsuite/semko/typemismatch.stp | 8 |
10 files changed, 134 insertions, 11 deletions
@@ -1,3 +1,14 @@ +2009-02-18 Rajan Arora <rarora@redhat.com> + + * testuite/semko/typemismatch.stp: New test. + +2009-02-18 Rajan Arora <rarora@redhat.com> + + * elaborate.cxx (typeresolution_info::mismatch): Generate semantic + error for the token where type was resolved and add to chain + * elaborate.h (struct typeresolution_info: public visitor): New + members 'resolved_toks' and 'printed_toks' + 2009-02-18 Stan Cox <scox@redhat.com> * tapsets.cxx (dwarf_builder::build): If not found in .probes, use .label @@ -1,5 +1,11 @@ * What's new in version 0.9 +- Typecasting is now supported using the @cast operator. A script can + define a pointer type for a "long" value, and then access type members + using the same syntax as with $target variables. For example, this will + retrieve the parent pid from a kernel task_struct: + @cast(pointer, "task_struct", "kernel")->parent->pid + - process().mark() probes are now possible to trace static user space markers put in programs with the STAP_PROBE macro using the new sys/sdt.h include file. This also provides dtrace compatible markers diff --git a/elaborate.cxx b/elaborate.cxx index 02229fbe..25c52c33 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -3987,23 +3987,70 @@ typeresolution_info::invalid (const token* tok, exp_type pe) void typeresolution_info::mismatch (const token* tok, exp_type t1, exp_type t2) { + bool tok_resolved; + size_t i; + semantic_error* err1 = 0; num_still_unresolved ++; + //BZ 9719: for improving type mismatch messages, a semantic error is + //generated with the token where type was first resolved. All such + //resolved tokens, stored in a vector, are matched against their + //content. If an error for the matching token hasn't been printed out + //already, it is and the token pushed in another printed_toks vector + if (assert_resolvability) { stringstream msg; - string nm = (current_function ? current_function->name : - current_probe ? current_probe->name : - "probe condition"); - msg << nm + " with type mismatch (" << t1 << " vs. " << t2 << ")"; - session.print_error (semantic_error (msg.str(), tok)); + for (i=0; i<resolved_toks.size(); i++) + { + if (resolved_toks[i]->content == tok->content) + { + tok_resolved = true; + break; + } + } + if (!tok_resolved) + { + string nm = (current_function ? current_function->name : + current_probe ? current_probe->name : + "probe condition"); + msg << nm + " with type mismatch (" << t1 << " vs. " << t2 << ")"; + } + else + { + bool tok_printed; + for (size_t j=0; j<printed_toks.size(); j++) + { + if (printed_toks[j] == resolved_toks[i]) + { + tok_printed = true; + break; + } + } + string nm = (current_function ? current_function->name : + current_probe ? current_probe->name : + "probe condition"); + msg << nm + " with type mismatch (" << t1 << " vs. " << t2 << ")"; + if (!tok_printed) + { + //error for possible mismatch in the earlier resolved token + printed_toks.push_back (resolved_toks[i]); + stringstream type_msg; + type_msg << nm + " type first inferred here (" << t2 << ")"; + err1 = new semantic_error (type_msg.str(), resolved_toks[i]); + } + } + semantic_error err (msg.str(), tok); + err.chain = err1; + session.print_error (err); } } void -typeresolution_info::resolved (const token*, exp_type) +typeresolution_info::resolved (const token* tok, exp_type) { + resolved_toks.push_back (tok); num_newly_resolved ++; } diff --git a/elaborate.h b/elaborate.h index 715a37df..1e05444f 100644 --- a/elaborate.h +++ b/elaborate.h @@ -54,6 +54,8 @@ struct typeresolution_info: public visitor bool assert_resolvability; functiondecl* current_function; derived_probe* current_probe; + std::vector <const token*> resolved_toks; // account for type mis- + std::vector <const token*> printed_toks; // matches (BZ 9719) void check_arg_type (exp_type wanted, expression* arg); void mismatch (const token* tok, exp_type t1, exp_type t2); diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 13f17ab1..cd0c6e35 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,9 @@ +2009-02-18 Frank Ch. Eigler <fche@elastic.org> + + PR 9866 band-aid. + * stack.c, stack-i386.c, stack-x86_64.c (CONFIG_STACKTRACE): + Also make conditional on KERNEL_VERSION > 2.6.26. + 2009-02-18 Will Cohen <wcohen@redhat.com> PR 9860 diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index 3c3921ea..206801d8 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -14,7 +14,7 @@ static int _stp_valid_stack_ptr(unsigned long context, unsigned long p) } /* DWARF unwinder failed. Just dump intereting addresses on kernel stack. */ -#ifndef CONFIG_STACKTRACE +#if ! (defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) static void _stp_stack_print_fallback(unsigned long stack, int verbose, int levels) { unsigned long addr; diff --git a/runtime/stack-x86_64.c b/runtime/stack-x86_64.c index 060f370d..183de0a0 100644 --- a/runtime/stack-x86_64.c +++ b/runtime/stack-x86_64.c @@ -10,7 +10,7 @@ /* DWARF unwinder failed. Just dump intereting addresses on kernel stack. */ -#ifndef CONFIG_STACKTRACE +#if ! (defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) static void _stp_stack_print_fallback(unsigned long stack, int verbose, int levels) { unsigned long addr; diff --git a/runtime/stack.c b/runtime/stack.c index 2a133398..aa0e6d65 100644 --- a/runtime/stack.c +++ b/runtime/stack.c @@ -27,7 +27,8 @@ #define MAXBACKTRACE 20 -#ifdef CONFIG_STACKTRACE +#if defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26) +// XXX: PR9866: hacky temporarily restriction to recent kernels #include <linux/stacktrace.h> #include <asm/stacktrace.h> #endif @@ -50,7 +51,7 @@ static void _stp_stack_print_fallback(unsigned long, int, int); #error "Unsupported architecture" #endif -#ifdef CONFIG_STACKTRACE +#if defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26) struct print_stack_data { @@ -160,7 +161,7 @@ static void _stp_ustack_print(char *str) void _stp_stack_print_tsk(struct task_struct *tsk, int verbose, int levels) { -#ifdef CONFIG_STACKTRACE +#if defined(CONFIG_STACKTRACE) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26) int i; unsigned long backtrace[MAXBACKTRACE]; struct stack_trace trace; @@ -755,6 +755,46 @@ probe end { } .ESAMPLE +.SS TYPECASTING +Once a pointer has been saved into a script integer variable, the +translator loses the type information necessary to access members from +that pointer. Using the +.I @cast() +operator tells the translator how to read a pointer. +.SAMPLE +@cast(p, "type_name"[, "module"])->member +.ESAMPLE +.PP +This will interpret +.I p +as a pointer to a struct/union named +.I type_name +and dereference the +.I member +value. The optional +.I module +tells the translator where to look for information about that type. If +the module is not specified, it will default either to the probe module +for dwarf probes, or to "kernel" for functions and all other probes +types. +.PP +When in guru mode, the translator will also allow scripts to assign new +values to members of typecasted pointers. +.PP +Typecasting is also useful in the case of +.I void* +members whose type may be determinable at runtime. +.SAMPLE +probe foo { + if ($var->type == 1) { + value = @cast($var->data, "type1")->bar + } else { + value = @cast($var->data, "type2")->baz + } + print(value) +} +.ESAMPLE + .SS EMBEDDED C When in guru mode, the translator accepts embedded code in the script. Such code is enclosed between @@ -1076,6 +1116,8 @@ probe specifications that refer to inline functions .IP \(bu 4 statements that refer to $target variables .IP \(bu 4 +statements that refer to @cast() variables +.IP \(bu 4 tapset-defined variables defined using any of the above constructs. In particular, at this writing, the prologue blocks for certain aliases in the syscall tapset diff --git a/testsuite/semko/typemismatch.stp b/testsuite/semko/typemismatch.stp new file mode 100755 index 00000000..94a49d53 --- /dev/null +++ b/testsuite/semko/typemismatch.stp @@ -0,0 +1,8 @@ +#! stap -p2 + + +global noo + +probe begin { foo = 1 ; foo = "bar" ; noo = 4 } + +probe end { foo = "zoo" ; foo <<< 2 ; noo = "zoo" }
\ No newline at end of file |