summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--NEWS6
-rw-r--r--elaborate.cxx59
-rw-r--r--elaborate.h2
-rw-r--r--runtime/ChangeLog6
-rw-r--r--runtime/stack-i386.c2
-rw-r--r--runtime/stack-x86_64.c2
-rw-r--r--runtime/stack.c7
-rw-r--r--stap.1.in42
-rwxr-xr-xtestsuite/semko/typemismatch.stp8
10 files changed, 134 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 1f44c6de..435421c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/NEWS b/NEWS
index 12e44323..280b6fb2 100644
--- a/NEWS
+++ b/NEWS
@@ -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;
diff --git a/stap.1.in b/stap.1.in
index cde049a3..6e4df024 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -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