summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--stap.125
-rwxr-xr-xstp_check.in1
-rw-r--r--systemtap.spec.in7
-rw-r--r--tapsets.cxx2
-rwxr-xr-xtestsuite/buildok/one.stp11
-rw-r--r--translate.cxx46
7 files changed, 78 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index be864cd3..d0138162 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2005-08-05 Frank Ch. Eigler <fche@elastic.org>
+
+ PR translator/1175
+ * translate.cxx (*): Added unlikely() markers to most emitted error
+ checks.
+ (mapvar::get,set): Handle NULL<->"" impedance mismatch.
+ (itervar::get_key): Ditto. Use base index=1 for keys.
+ * testsuite/buildok/one.stp: Extend. And it runs with -p5 too.
+ * stap.1: Document use of ";" statament as mechanism for grammar
+ ambiguity resolution.
+ * stp_check.in: Set $prefix.
+ * systemtap.spec.in: Prereq kernel-devel, kernel-debuginfo,
+ and not tcl.
+ * tapsets.cxx: Make slightly less verbose.
+ * translate.cxx
+
2005-08-03 Graydon Hoare <graydon@redhat.com>
* tapsets.cxx (dwflpp): Fix address calculation logic a bit,
diff --git a/stap.1 b/stap.1
index b436976e..230f7a9b 100644
--- a/stap.1
+++ b/stap.1
@@ -7,21 +7,21 @@ stap \- systemtap script translator/driver
.br
.B stap
[
-.IR OPTIONS
+.I OPTIONS
]
.I FILENAME
.br
.B stap
[
-.IR OPTIONS
+.I OPTIONS
]
-.BI \-
+.B \-
.br
.B stap
[
.I OPTIONS
]
-.BI \-e " SCRIPT "
+.BI \-e " SCRIPT"
.SH DESCRIPTION
@@ -64,24 +64,24 @@ kernel object.
Guru mode. Enables parsing of unsafe expert-level constructs like
embedded C.
.TP
-.BI \-p NUM
+.BI \-p " NUM"
Stop after pass NUM. The passes are numbered 1-5: parse, elaborate,
translate, compile, run. See the
.B PROCESSING
section for details.
.TP
-.BI \-I DIR
+.BI \-I " DIR"
Add the given directory to the tapset search directory. See the
description of pass 2 for details.
.TP
-.BI \-R DIR
+.BI \-R " DIR"
Look for the systemtap runtime sources in the given directory.
.TP
-.BI \-m MODULE
+.BI \-m " MODULE"
Use the given name for the generated kernel object module, instead
of a unique randomized name.
.TP
-.BI \-o FILE
+.BI \-o " FILE"
Send standard output to named file.
.SH SCRIPT LANGUAGE
@@ -151,12 +151,13 @@ Execute the string- or integer-valued expression and throw away
the value.
.TP
.BR { " STMT1 STMT2 ... " }
-Execute each statement in sequence in this block. Note that no
-separators or terminators are necessary between statements.
+Execute each statement in sequence in this block. Note that
+separators or terminators are generally not necessary between statements.
.TP
.BR ;
Null statement, do nothing. It is useful as an optional separator between
-statements to improve the display of syntax-error reports.
+statements to improve syntax-error detection and to handle certain
+grammar ambiguities.
.TP
.BR if " (EXP) STMT1 [ " else " STMT2 ]"
Compare integer-valued EXP to zero. Execute the first (non-zero)
diff --git a/stp_check.in b/stp_check.in
index 2b9bd0e0..78aabebf 100755
--- a/stp_check.in
+++ b/stp_check.in
@@ -30,6 +30,7 @@ load_module()
fi
}
+prefix=@prefix@
VAR_DIR=@localstatedir@/cache/systemtap
RELAYFS=`grep " relayfs_poll" /boot/System.map-\`uname -r\``
diff --git a/systemtap.spec.in b/systemtap.spec.in
index eb282db2..3359fdab 100644
--- a/systemtap.spec.in
+++ b/systemtap.spec.in
@@ -15,8 +15,11 @@ ExclusiveArch: %{ix86} x86_64
BuildRoot: %{_tmppath}/%{name}-root
Requires: kernel >= 2.6.9-11
-Requires: tcl gcc make
-BuildRequires: doxygen
+Requires: kernel-devel
+# or is that kernel-smp-devel?
+Requires: kernel-debuginfo
+Requires: gcc make
+# Requires: tcl
%if %{bundled_elfutils}
Source1: elfutils-%{elfutils_version}.tar.gz
diff --git a/tapsets.cxx b/tapsets.cxx
index e5ae7f05..cd3764f0 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -279,7 +279,7 @@ dwflpp
Dwarf_Addr bias;
assert(dwfl);
get_module_dwarf();
- if (sess.verbose)
+ if (false && sess.verbose)
clog << "focusing on cu containing global addr " << a << endl;
focus_on_cu(dwfl_module_addrdie(module, a, &bias));
assert(bias == module_bias);
diff --git a/testsuite/buildok/one.stp b/testsuite/buildok/one.stp
index 1f4f8f9b..491d059e 100755
--- a/testsuite/buildok/one.stp
+++ b/testsuite/buildok/one.stp
@@ -1,15 +1,24 @@
#! stap -p4
-global foo, bar
+global foo, bar, baz
probe begin
{
x = 10
foo["hello"] = 25
foo["hello"]++
+ foo["hello"] = 0;
++foo["hello"]
x = foo["hello"]
foo["yo"] *= bar[x, foo["hello"], "goodbye"]++;
+ bar[0, 0, ""] = 0
+
+ foreach ([m, o, p] in bar) baz[m] = p
+
+ # empty string treatment
+ baz[10] = ""
+ q = baz[223]
+
printk("hello from systemtap")
}
diff --git a/translate.cxx b/translate.cxx
index 85dfc925..0bb56815 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -239,7 +239,7 @@ public:
{
if (ty == pe_long)
{
- c.o->newline() << "if (" << qname() << " == 0) {";
+ c.o->newline() << "if (unlikely (" << qname() << " == 0)) {";
c.o->newline(1) << "c->errorcount++;";
c.o->newline() << qname() << " = 1;";
c.o->newline(-1) << "}";
@@ -344,13 +344,25 @@ struct mapvar
string get () const
{
- return "_stp_map_get_" + shortname(type()) + " (" + qname() + ")";
+ // see also itervar::get_key
+ if (type() == pe_string)
+ // impedance matching: NULL -> empty strings
+ return "({ char *v = "
+ "_stp_map_get_" + shortname(type()) + " (" + qname() + "); "
+ "if (!v) v = \"\"; v; })";
+ else // long?
+ return "_stp_map_get_" + shortname(type()) + " (" + qname() + ")";
}
string set (tmpvar const & tmp) const
{
- return ("_stp_map_set_" + shortname(type()) + " (" + qname()
- + ", " + tmp.qname() + ")");
+ // impedance matching: empty strings -> NULL
+ if (type() == pe_string)
+ return ("_stp_map_set_" + shortname(type()) + " (" + qname()
+ + ", (" + tmp.qname() + "[0] ? " + tmp.qname() + " : NULL))");
+ else
+ return ("_stp_map_set_" + shortname(type()) + " (" + qname()
+ + ", " + tmp.qname() + ")");
}
string mangled_indices() const
@@ -420,12 +432,18 @@ public:
string get_key (exp_type ty, unsigned i) const
{
+ // bug translator/1175: runtime uses base index 1 for the first dimension
+ // see also mapval::get
switch (ty)
{
case pe_long:
- return "_stp_key_get_int64 ("+ qname() + ", " + stringify(i) + ")";
+ return "_stp_key_get_int64 ("+ qname() + ", " + stringify(i+1) + ")";
case pe_string:
- return "_stp_key_get_str ("+ qname() + ", " + stringify(i) + ")";
+ // impedance matching: NULL -> empty strings
+ return "({ char *v = "
+ "_stp_key_get_str ("+ qname() + ", " + stringify(i+1) + "); "
+ "if (! v) v = \"\"; "
+ "v; })";
default:
throw semantic_error("illegal key type");
}
@@ -624,7 +642,7 @@ c_unparser::emit_module_init ()
o->newline() << "/* register " << i << " */";
session->probes[i]->emit_registrations (o, i);
- o->newline() << "if (rc) {";
+ o->newline() << "if (unlikely (rc)) {";
// In case it's just a lower-layer (kprobes) error that set rc
// but not session_state, do that here to prevent any other BEGIN
// probe from attempting to run.
@@ -1203,14 +1221,14 @@ c_unparser::visit_block (block *s)
o->newline() << "{";
o->indent (1);
o->newline() << "c->actioncount += " << s->statements.size() << ";";
- o->newline() << "if (c->actioncount > MAXACTION) goto out;";
+ o->newline() << "if (unlikely (c->actioncount > MAXACTION)) goto out;";
for (unsigned i=0; i<s->statements.size(); i++)
{
try
{
// XXX: it's probably not necessary to check this so frequently
- o->newline() << "if (c->errorcount) goto out;";
+ o->newline() << "if (unlikely (c->errorcount)) goto out;";
s->statements[i]->visit (this);
o->newline();
}
@@ -1278,7 +1296,7 @@ c_unparser::visit_for_loop (for_loop *s)
o->newline() << contlabel << ":";
o->newline() << "c->actioncount ++;";
- o->newline() << "if (c->actioncount > MAXACTION) goto out;";
+ o->newline() << "if (unlikely (c->actioncount > MAXACTION)) goto out;";
o->newline() << "if (! (";
if (s->cond->type != pe_long)
@@ -1843,7 +1861,7 @@ c_unparser::visit_arrayindex (arrayindex* e)
// reentrancy issues that pop up with nested expressions:
// e.g. a[a[c]=5] could deadlock
- o->newline() << "if (c->errorcount) goto out;";
+ o->newline() << "if (unlikely (c->errorcount)) goto out;";
{
mapvar mvar = getmap (e->referent, e->tok);
@@ -1919,7 +1937,7 @@ c_unparser_assignment::visit_arrayindex (arrayindex *e)
// reentrancy issues that pop up with nested expressions:
// e.g. ++a[a[c]=5] could deadlock
- o->newline() << "if (c->errorcount) goto out;";
+ o->newline() << "if (unlikely (c->errorcount)) goto out;";
prepare_rvalue (op, rvar, e->tok);
@@ -1982,9 +2000,9 @@ c_unparser::visit_functioncall (functioncall* e)
}
o->newline();
- o->newline() << "if (c->nesting+2 >= MAXNESTING) goto out;";
+ o->newline() << "if (unlikely (c->nesting+2 >= MAXNESTING)) goto out;";
o->newline() << "c->actioncount ++;";
- o->newline() << "if (c->actioncount > MAXACTION) goto out;";
+ o->newline() << "if (unlikely (c->actioncount > MAXACTION)) goto out;";
o->newline();
// copy in actual arguments