diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | stap.1 | 25 | ||||
-rwxr-xr-x | stp_check.in | 1 | ||||
-rw-r--r-- | systemtap.spec.in | 7 | ||||
-rw-r--r-- | tapsets.cxx | 2 | ||||
-rwxr-xr-x | testsuite/buildok/one.stp | 11 | ||||
-rw-r--r-- | translate.cxx | 46 |
7 files changed, 78 insertions, 30 deletions
@@ -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, @@ -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 |