From 3bd0d4df7ccfd9afe7771441b26d8baaaf180e29 Mon Sep 17 00:00:00 2001 From: Rajan Arora Date: Wed, 11 Mar 2009 18:44:21 -0400 Subject: PR 7071: Optional $context variables fix * tapsets.cxx (dwarf_var_expanding_visitor::visit_target_symbol): Substitute erroneous target symbol with literal 0 if session level flag, skip_badvars is set. * session.h (struct systemtap_session): New flag: skip_badvars. * main.cxx: Command line argument --skip-badvars added. * stap.1.in: Entry for new option --skip-badvars. * NEWS: Added blurb for new option now available. * testsuite/semok/badvar.stp: Test case to check added functionality. --- NEWS | 5 +++++ main.cxx | 7 +++++++ session.h | 3 +++ stap.1.in | 3 +++ tapsets.cxx | 37 +++++++++++++++++++++++++------------ testsuite/semok/badvar.stp | 7 +++++++ 6 files changed, 50 insertions(+), 12 deletions(-) create mode 100755 testsuite/semok/badvar.stp diff --git a/NEWS b/NEWS index 08705c81..74fd1df5 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,10 @@ * What's new +- Variables unavailable in current context may be skipped by setting a + session level flag with command line option --skip-badvars now available. + This will simply substitute the otherwise error causing variable with a + literal 0 and print a warning message when the substitution has been made. + * What's new in version 0.9 - Typecasting is now supported using the @cast operator. A script can diff --git a/main.cxx b/main.cxx index b494ba2b..890f65bc 100644 --- a/main.cxx +++ b/main.cxx @@ -134,6 +134,8 @@ usage (systemtap_session& s, int exitcode) #endif // Formerly present --ignore-{vmlinux,dwarf} options are for testsuite use // only, and don't belong in the eyesight of a plain user. + << " --skip-badvars" << endl + << " overlook context of bad $ variables" << endl << endl ; @@ -431,12 +433,14 @@ main (int argc, char * const argv []) #define LONG_OPT_IGNORE_VMLINUX 3 #define LONG_OPT_IGNORE_DWARF 4 #define LONG_OPT_VERBOSE_PASS 5 +#define LONG_OPT_SKIP_BADVARS 6 // NB: also see find_hash(), usage(), switch stmt below, stap.1 man page static struct option long_options[] = { { "kelf", 0, &long_opt, LONG_OPT_KELF }, { "kmap", 2, &long_opt, LONG_OPT_KMAP }, { "ignore-vmlinux", 0, &long_opt, LONG_OPT_IGNORE_VMLINUX }, { "ignore-dwarf", 0, &long_opt, LONG_OPT_IGNORE_DWARF }, + { "skip-badvars", 0, &long_opt, LONG_OPT_SKIP_BADVARS }, { "vp", 1, &long_opt, LONG_OPT_VERBOSE_PASS }, { NULL, 0, NULL, 0 } }; @@ -698,6 +702,9 @@ main (int argc, char * const argv []) // NB: we don't do this: s.last_pass = strlen(optarg); break; } + case LONG_OPT_SKIP_BADVARS: + s.skip_badvars = true; + break; default: cerr << "Internal error parsing command arguments." << endl; usage(s, 1); diff --git a/session.h b/session.h index bc99385b..ec6c2e3e 100644 --- a/session.h +++ b/session.h @@ -123,6 +123,9 @@ struct systemtap_session bool ignore_vmlinux; bool ignore_dwarf; + // Skip bad $ vars + bool skip_badvars; + // temporary directory for module builds etc. // hazardous - it is "rm -rf"'d at exit std::string tmpdir; diff --git a/stap.1.in b/stap.1.in index 546bebb8..5a2e35f9 100644 --- a/stap.1.in +++ b/stap.1.in @@ -230,6 +230,9 @@ nor the kernel debugging information can be found. .TP .B \-\-ignore\-dwarf For testing, act as though vmlinux and modules lack debugging information. +.TP +.B \-\-skip\-badvars +Ignore out of context variables and substitute with literal 0. .SH ARGUMENTS diff --git a/tapsets.cxx b/tapsets.cxx index b1d0b04e..dce73534 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -4842,18 +4842,31 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) } catch (const semantic_error& er) { - // We suppress this error message, and pass the unresolved - // target_symbol to the next pass. We hope that this value ends - // up not being referenced after all, so it can be optimized out - // quietly. - provide (e); - semantic_error* saveme = new semantic_error (er); // copy it - saveme->tok1 = e->tok; // XXX: token not passed to q.dw code generation routines - // NB: we can have multiple errors, since a $target variable - // may be expanded in several different contexts: - // function ("*") { $var } - saveme->chain = e->saved_conversion_error; - e->saved_conversion_error = saveme; + if (!q.sess.skip_badvars) + { + // We suppress this error message, and pass the unresolved + // target_symbol to the next pass. We hope that this value ends + // up not being referenced after all, so it can be optimized out + // quietly. + provide (e); + semantic_error* saveme = new semantic_error (er); // copy it + saveme->tok1 = e->tok; // XXX: token not passed to q.dw code generation routines + // NB: we can have multiple errors, since a $target variable + // may be expanded in several different contexts: + // function ("*") { $var } + saveme->chain = e->saved_conversion_error; + e->saved_conversion_error = saveme; + } + else + { + // Upon user request for ignoring context, the symbol is replaced + // with a literal 0 and a warning message displayed + literal_number* ln_zero = new literal_number (0); + ln_zero->tok = e->tok; + provide (ln_zero); + q.sess.print_warning ("Bad variable being substituted with literal 0", + e->tok); + } delete fdecl; delete ec; return; diff --git a/testsuite/semok/badvar.stp b/testsuite/semok/badvar.stp new file mode 100755 index 00000000..b3bd2d67 --- /dev/null +++ b/testsuite/semok/badvar.stp @@ -0,0 +1,7 @@ +#! stap --skip-badvars + +probe syscall.read { + if ($foo == 0) + printf ("Voila! It works..\n") + exit () +} -- cgit