From a7c9924bca8c69998b237047ec03a8faf9638a94 Mon Sep 17 00:00:00 2001 From: fche Date: Tue, 18 Apr 2006 19:19:35 +0000 Subject: 2006-04-18 Frank Ch. Eigler PR 2220 * translate.cxx (visit_statement): Tolerate 0 first argument. (visit_for_loop, visit_foreach_loop): Call it thusly for condition expression. (visit_embededcode, visit_block, visit_null_statement): Don't call visit_statement() at all. 2006-04-18 Frank Ch. Eigler * conversions.stp (string, hex_string): Use snprintf for safety. 2006-04-18 Frank Ch. Eigler * systemtap.samples/control_limits.stp: Adapt to new action counting. --- ChangeLog | 9 ++++++++ tapset/ChangeLog | 4 ++++ tapset/conversions.stp | 4 ++-- translate.cxx | 60 +++++++++++++++++++++++++++++++++++++++----------- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0726efef..baaf936c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-04-18 Frank Ch. Eigler + + PR 2220 + * translate.cxx (visit_statement): Tolerate 0 first argument. + (visit_for_loop, visit_foreach_loop): Call it thusly for condition + expression. + (visit_embededcode, visit_block, visit_null_statement): Don't + call visit_statement() at all. + 2006-04-18 Martin Hunt * Makefile.am (install-data-local): Tweak previous fix. diff --git a/tapset/ChangeLog b/tapset/ChangeLog index 7d5ce509..9c05f71b 100644 --- a/tapset/ChangeLog +++ b/tapset/ChangeLog @@ -1,3 +1,7 @@ +2006-04-18 Frank Ch. Eigler + + * conversions.stp (string, hex_string): Use snprintf for safety. + 2006-04-18 Martin Hunt * conversions.stp (user_string): Reenable error message. diff --git a/tapset/conversions.stp b/tapset/conversions.stp index d46f8c18..b05d7a8e 100644 --- a/tapset/conversions.stp +++ b/tapset/conversions.stp @@ -7,11 +7,11 @@ // later version. function hexstring:string (num:long) %{ - sprintf (THIS->__retvalue, "0x%llx", (long long) THIS->num); + snprintf (THIS->__retvalue, MAXSTRINGLEN, "0x%llx", (long long) THIS->num); %} function string:string (num:long) %{ - sprintf (THIS->__retvalue, "%lld", (long long) THIS->num); + snprintf (THIS->__retvalue, MAXSTRINGLEN, "%lld", (long long) THIS->num); %} function kernel_string:string (addr:long) %{ diff --git a/translate.cxx b/translate.cxx index 6e915465..08be0f34 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1834,19 +1834,23 @@ void c_unparser::visit_statement (statement *s, unsigned actions) { // For some constructs, it is important to avoid an error branch - // right to the bottom of the probe/function. The foreach() locking - // construct is one example. Instead, if we are nested within a - // loop, we branch merely to its "break" label. The next statement - // will branch one level higher, and so on, until we can go straight - // "out". + // right to the bottom of the probe/function. The foreach() + // iteration construct is one example. Instead, if we are nested + // within a loop, we branch merely to its "break" label. The next + // statement will branch one level higher, and so on, until we can + // go straight "out". string outlabel = "out"; unsigned loops = loop_break_labels.size(); if (loops > 0) outlabel = loop_break_labels[loops-1]; - o->newline() << "if (unlikely (c->last_error)) goto " << outlabel << ";"; - assert (s->tok); - o->newline() << "c->last_stmt = " << lex_cast_qstring(*s->tok) << ";"; + if (s) + { + o->newline() << "if (unlikely (c->last_error)) goto " << outlabel << ";"; + assert (s->tok); + o->newline() << "c->last_stmt = " << lex_cast_qstring(*s->tok) << ";"; + } + if (actions > 0) { o->newline() << "c->actioncount += " << actions << ";"; @@ -1864,7 +1868,13 @@ c_unparser::visit_block (block *s) { o->newline() << "{"; o->indent (1); - visit_statement (s, 0); + + // visit_statement (s, 0); + // + // NB: this is not necessary, since the last_error can be handled + // just as easily by the first real body statement, and the + // last_stmt won't be used since this nesting structure cannot + // itself cause an error. for (unsigned i=0; istatements.size(); i++) { @@ -1885,7 +1895,12 @@ c_unparser::visit_block (block *s) void c_unparser::visit_embeddedcode (embeddedcode *s) { - visit_statement (s, 1); + // visit_statement (s, 1); + // + // NB: this is not necessary, since this can occur only at the top + // level of a function (so no errors can be pending), and the + // action-count is already incremented at the point of call. + o->newline() << "{"; o->newline(1) << s->code; o->newline(-1) << "}"; @@ -1895,7 +1910,12 @@ c_unparser::visit_embeddedcode (embeddedcode *s) void c_unparser::visit_null_statement (null_statement *s) { - visit_statement (s, 0); + // visit_statement (s, 0); + // + // NB: this is not necessary, since the last_error can be handled just as + // easily by the next statement, and the last_stmt won't be used since this + // statement cannot cause an error. + o->newline() << "/* null */;"; } @@ -1976,7 +1996,14 @@ c_unparser::visit_for_loop (for_loop *s) // condition o->newline(-1) << toplabel << ":"; - o->newline(1) << "if (! ("; + + // Emit an explicit actioncount increment here to cover the act of + // iteration. Equivalently, it can stand for the evaluation of the + // condition expression. + o->indent(1); + visit_statement (0, 1); + + o->newline() << "if (! ("; if (s->cond->type != pe_long) throw semantic_error ("expected numeric type", s->cond->tok); s->cond->visit (this); @@ -2141,7 +2168,14 @@ c_unparser::visit_foreach_loop (foreach_loop *s) // condition o->newline(-1) << toplabel << ":"; - o->newline(1) << "if (! (" << iv << ")) goto " << breaklabel << ";"; + + // Emit an explicit actioncount increment here to cover the act of + // iteration. Equivalently, it can stand for the evaluation of the + // condition expression. + o->indent(1); + visit_statement (0, 1); + + o->newline() << "if (! (" << iv << ")) goto " << breaklabel << ";"; // body loop_break_labels.push_back (breaklabel); -- cgit