]> sourceware.org Git - systemtap.git/commitdiff
2006-02-23 Frank Ch. Eigler <fche@elastic.org>
authorfche <fche>
Thu, 23 Feb 2006 22:35:40 +0000 (22:35 +0000)
committerfche <fche>
Thu, 23 Feb 2006 22:35:40 +0000 (22:35 +0000)
PR 1304
* parse.cxx (lexer): Take systemtap_session argument.
(lexer::scan): Support $1..$NNNN and @1...@NNNN expansion.
* stap.1.in: Document this.
* testsuite/semok/args.stp: New test.
* translate.cxx (var::init, emit_global): Emit code to allow
named module parameters to initialize global string/number scalars.
* stap.1.in: Don't document this yet.

PR 2334
* main.cxx (main): Clarify "-v" option repeatibility.
* stap.1.in: Ditto.

ChangeLog
main.cxx
parse.cxx
parse.h
runtime/stpd/ChangeLog
runtime/stpd/librelay.c
runtime/stpd/stpd.c
stap.1.in
tapsets.cxx
testsuite/semok/args.stp [new file with mode: 0755]
translate.cxx

index 469c43b7741e1bad60347fa664644f87d493f83a..ea9c44d794364e13c2e5749b421645fb8f466584 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2006-02-23  Frank Ch. Eigler  <fche@elastic.org>
+
+       PR 1304 
+       * parse.cxx (lexer): Take systemtap_session argument.
+       (lexer::scan): Support $1..$NNNN and @1...@NNNN expansion.
+       * stap.1.in: Document this.
+       * testsuite/semok/args.stp: New test.
+       * translate.cxx (var::init, emit_global): Emit code to allow
+       named module parameters to initialize global string/number scalars.
+       * stap.1.in: Don't document this yet.
+       
+       PR 2334
+       * main.cxx (main): Clarify "-v" option repeatibility.
+       * stap.1.in: Ditto.
+
 2006-02-23  Roland McGrath  <roland@redhat.com>
 
        * Makefile.am (AUTOMAKE_OPTIONS): New variable, set dist-bzip2.
index 127e667d8d9c6f18f568218693c9afade5cbf92a..27e0cdd451073c8bb1f57f6e15c68d87d4749e9d 100644 (file)
--- a/main.cxx
+++ b/main.cxx
@@ -1,5 +1,5 @@
 // systemtap translator/driver
-// Copyright (C) 2005 Red Hat Inc.
+// Copyright (C) 2005-2006 Red Hat Inc.
 // Copyright (C) 2005 IBM Corp.
 //
 // This file is part of systemtap, and is free software.  You can
@@ -405,7 +405,7 @@ main (int argc, char * const argv [])
 
   if (rc)
     cerr << "Pass 1: parse failed.  "
-         << (s.verbose ? "" : "Try again with '-v' (verbose) option.")
+         << "Try again with more '-v' (verbose) options."
          << endl;
 
   if (rc || s.last_pass == 1) goto cleanup;
@@ -486,7 +486,7 @@ main (int argc, char * const argv [])
 
   if (rc)
     cerr << "Pass 2: analysis failed.  "
-         << (s.verbose ? "" : "Try again with '-v' (verbose) option.")
+         << "Try again with more '-v' (verbose) options."
          << endl;
 
   if (rc || s.last_pass == 2) goto cleanup;
@@ -516,7 +516,7 @@ main (int argc, char * const argv [])
 
   if (rc)
     cerr << "Pass 3: translation failed.  "
-         << (s.verbose ? "" : "Try again with '-v' (verbose) option.")
+         << "Try again with more '-v' (verbose) options."
          << endl;
 
   if (rc || s.last_pass == 3) goto cleanup;
@@ -536,7 +536,7 @@ main (int argc, char * const argv [])
 
   if (rc)
     cerr << "Pass 4: compilation failed.  "
-         << (s.verbose ? "" : "Try again with '-v' (verbose) option.")
+         << "Try again with more '-v' (verbose) options."
          << endl;
 
   // XXX: what to do if rc==0 && last_pass == 4?  dump .ko file to stdout? 
@@ -558,7 +558,7 @@ main (int argc, char * const argv [])
 
   if (rc)
     cerr << "Pass 5: run failed.  "
-         << (s.verbose ? "" : "Try again with '-v' (verbose) option.")
+         << "Try again with more '-v' (verbose) options."
          << endl;
 
   // if (rc) goto cleanup;
index dcdb726033c3d030b25a632f2b3cbb007c5c3c07..04e01ebc09265100c965e5b719abbdd07cfa1d19 100644 (file)
--- a/parse.cxx
+++ b/parse.cxx
@@ -1,5 +1,5 @@
 // recursive descent parser for systemtap scripts
-// Copyright (C) 2005 Red Hat Inc.
+// Copyright (C) 2005-2006 Red Hat Inc.
 //
 // This file is part of systemtap, and is free software.  You can
 // redistribute it and/or modify it under the terms of the GNU General
@@ -28,14 +28,14 @@ using namespace std;
 parser::parser (systemtap_session& s, istream& i, bool p):
   session (s),
   input_name ("<input>"), free_input (0),
-  input (i, input_name), privileged (p),
+  input (i, input_name, s), privileged (p),
   last_t (0), next_t (0), num_errors (0)
 { }
 
 parser::parser (systemtap_session& s, const string& fn, bool p):
   session (s),
   input_name (fn), free_input (new ifstream (input_name.c_str(), ios::in)),
-  input (* free_input, input_name), privileged (p),
+  input (* free_input, input_name, s), privileged (p),
   last_t (0), next_t (0), num_errors (0)
 { }
 
@@ -397,8 +397,8 @@ parser::peek_kw (std::string const & kw)
 
 
 
-lexer::lexer (istream& i, const string& in):
-  input (i), input_name (in), cursor_line (1), cursor_column (1)
+lexer::lexer (istream& i, const string& in, systemtap_session& s):
+  input (i), input_name (in), cursor_line (1), cursor_column (1), session(s)
 { }
 
 
@@ -472,6 +472,31 @@ lexer::scan ()
          else
            break;
        }
+
+      // Expand command line arguments to literals.  $1 .. $999 as
+      // numbers and @1 .. @999 as strings.
+      if (n->content[0] == '@' || n->content[0] == '$')
+        {
+          string idxstr = n->content.substr(1);
+          const char* startp = idxstr.c_str();
+          char *endp;
+          errno = 0;
+          unsigned long idx = strtoul (startp, &endp, 10);
+          if (endp == startp)
+            ; // no numbers at all - leave alone as identifier 
+          else
+            {
+              // Use @1/$1 as the base, not @0/$0.  Thus the idx-1.
+              if (errno == ERANGE || errno == EINVAL || *endp != '\0' ||
+                  idx == 0 || idx-1 >= session.args.size ())
+                throw parse_error ("command line argument index invalid or out of range");
+              
+              string arg = session.args[idx-1];
+              n->type = (n->content[0] == '@') ? tok_string : tok_number;
+              n->content = arg;
+            }
+        }
+
       return n;
     }
 
diff --git a/parse.h b/parse.h
index 81544eb9fe708c34a71614a0effbb5695bb94c84..b9d56152791c119a872a2e7efe468380e673e70f 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -57,7 +57,7 @@ class lexer
 {
 public:
   token* scan ();
-  lexer (std::istream&, const std::string&);
+  lexer (std::istream&, const std::string&, systemtap_session&);
 
 private:
   int input_get ();
@@ -67,6 +67,7 @@ private:
   std::vector<int> lookahead;
   unsigned cursor_line;
   unsigned cursor_column;
+  systemtap_session& session;
 };
 
 
index e72ec4d045007fa436d1881293964f6f93d08051..1695cf6ec8b3ac87cd0a0e7942313d8db599acf3 100644 (file)
@@ -1,3 +1,10 @@
+2006-02-23  Frank Ch. Eigler  <fche@elastic.org>
+
+       PR 1304
+       * stpd.c (mdooptions): New array.
+       (main): Populate it with leftover arguments.
+       * librelay.c (init_stp): Pass it to execve().
+
 2005-12-08  Frank Ch. Eigler  <fche@elastic.org>
 
        PR 1937
index e2beece2d1059a01fb5ef0c489b1b6dc4733ac92..719f026d1feb479cdda277dce8216892a9254b7c 100644 (file)
@@ -83,6 +83,7 @@ extern int print_only, quiet, merge, verbose;
 extern unsigned int buffer_size;
 extern char *modname;
 extern char *modpath;
+extern char *modoptions[];
 extern int target_pid;
 extern int driver_pid;
 extern char *target_cmd;
@@ -460,11 +461,16 @@ int init_stp(const char *relay_filebase, int print_summary)
 
        /* insert module */
        sprintf(buf, "_stp_pid=%d", (int)getpid());
+        modoptions[0] = "insmod";
+        modoptions[1] = modpath;
+        modoptions[2] = buf;
+        /* modoptions[3...N] set by command line parser. */
+
        if ((pid = vfork()) < 0) {
                perror ("vfork");
                exit(-1);
        } else if (pid == 0) {
-               if (execl("/sbin/insmod",  "insmod", modpath, buf, NULL) < 0)
+               if (execvp("/sbin/insmod",  modoptions) < 0)
                        exit(-1);
        }
        if (waitpid(pid, &rstatus, 0) < 0) {
index c12ca0969ed1ac0eaab83478b2fd15682cc7f299..c6cc913d4040d3685e704ddfa9fa550b413345bf 100644 (file)
@@ -15,8 +15,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * Copyright (C) IBM Corporation, 2005
- * Copyright (C) Red Hat Inc, 2005
+ * Copyright (C) 2005 IBM Corporation
+ * Copyright (C) 2005-2006 Red Hat, Inc.
  *
  */
 
@@ -41,6 +41,8 @@ int driver_pid = 0;
 unsigned int buffer_size = 0;
 char *modname = NULL;
 char *modpath = NULL;
+#define MAXMODOPTIONS 64
+char *modoptions[MAXMODOPTIONS];
 char *target_cmd = NULL;
 char *outfile_name = NULL;
 
@@ -59,7 +61,8 @@ char *stp_check="stp_check";
 
 static void usage(char *prog)
 {
-       fprintf(stderr, "\n%s [-m] [-p] [-q] [-r] [-c cmd ] [-t pid] [-b bufsize] [-o FILE] kmod-name\n", prog);
+       fprintf(stderr, "\n%s [-m] [-p] [-q] [-r] [-c cmd ] [-t pid]\n"
+                "\t[-b bufsize] [-o FILE] kmod-name [kmod-options]\n", prog);
        fprintf(stderr, "-m  Don't merge per-cpu files.\n");
        fprintf(stderr, "-p  Print only.  Don't log to files.\n");
        fprintf(stderr, "-q  Quiet. Don't display trace to stdout.\n");
@@ -68,8 +71,8 @@ static void usage(char *prog)
        fprintf(stderr, "   _stp_target will contain the pid for the command.\n");
        fprintf(stderr, "-t pid.  Sets _stp_target to pid.\n");
        fprintf(stderr, "-d pid.  Pass the systemtap driver's pid.\n");
-       fprintf(stderr, "-b buffer size. The systemtap module will specify a buffer size.\n");
        fprintf(stderr, "-o FILE. Send output to FILE.\n");
+       fprintf(stderr, "-b buffer size. The systemtap module will specify a buffer size.\n");
        fprintf(stderr, "   Setting one here will override that value. The value should be\n");
        fprintf(stderr, "   an integer between 1 and 64 which be assumed to be the\n");
        fprintf(stderr, "   buffer size in MB. That value will be per-cpu if relayfs is used.\n");
@@ -143,6 +146,16 @@ int main(int argc, char **argv)
             else
               modname++; /* skip over / */
           }
+
+        if (optind < argc)
+          {
+            unsigned start_idx = 3; /* reserve three slots in modoptions[] */
+            while (optind < argc && start_idx+1 < MAXMODOPTIONS)
+              modoptions[start_idx++] = argv[optind++];
+            /* Redundantly ensure that there is a NULL pointer at the end
+               of modoptions[]. */
+            modoptions[start_idx] = NULL;
+          }
   
        if (!modname) {
                fprintf (stderr, "Cannot invoke daemon without probe module\n");
index 48fc7dcb8e7f0c2dca4fb1794284d83cebae6c9a..c3ce07257389cedf91a4e612cf5b4585d616b8d1 100644 (file)
--- a/stap.1.in
+++ b/stap.1.in
@@ -24,18 +24,27 @@ stap \- systemtap script translator/driver
 .I OPTIONS
 ]
 .I FILENAME
+[
+.I ARGUMENTS
+]
 .br
 .B stap
 [
 .I OPTIONS
 ]
 .B \-
+[
+.I ARGUMENTS
+]
 .br
 .B stap
 [
 .I OPTIONS
 ]
 .BI \-e " SCRIPT"
+[
+.I ARGUMENTS
+]
 
 .SH DESCRIPTION
 
@@ -72,7 +81,8 @@ prints a list of supported options.
 .\" -t test mode
 .TP
 .B \-v
-Increase verbosity.  Produce more informative output.
+Increase verbosity.  Produce a larger volume of informative (?) output
+each time option repeated.
 .TP
 .B \-h
 Show help message.
@@ -133,6 +143,11 @@ Start the probes, run CMD, and exit when CMD finishes.
 Sets target() to PID. This allows scripts to be written that filter on 
 a specific process.
 
+.SH ARGUMENTS
+
+Any additional arguments on the command line are passed to the script
+parser for substitution.  See below.
+
 .SH SCRIPT LANGUAGE
 
 The systemtap script language resembles 
@@ -158,6 +173,15 @@ are limited in length to some reasonable value (a few hundred bytes).
 Integers are 64-bit signed quantities, although the parser also accepts
 (and wraps around) values above positive 2**63.
 .PP
+In addition, script arguments given at the end of the command line may
+be expanded as literals.  Use
+.B $1 ... $<NN>
+for casting as a numberic literal and
+.B @1 ... @<NN>
+for casting as string literal.  These may be used in all contexts
+where literals are accepted.  Reference to an argument number beyond
+what was actually given is an error.
+.PP
 A simple conditional preprocessing stage is run as a part of parsing.
 The general form is similar to the 
 .RB cond " ? " exp1 " : " exp2
index 31b2515a0a33fd05ac7efdf04e596764a0c90510..2e2c933eab5eea4f0c940678058d337914d4baf0 100644 (file)
@@ -137,7 +137,7 @@ derived_probe::emit_probe_epilogue (translator_output* o)
   o->newline(-1) << "}";
   
   o->newline() << "atomic_dec (&c->busy);";
-  o->newline(-1) << "probe_epilogue: ;";
+  o->newline(-1) << "probe_epilogue:";
   o->newline(1) << "local_irq_restore (flags);";
 }
 
diff --git a/testsuite/semok/args.stp b/testsuite/semok/args.stp
new file mode 100755 (executable)
index 0000000..0047562
--- /dev/null
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+./stap -p2 -e 'probe begin { log (@1 . string($2)) }' hello 0xdeadbeef
index becb7bcd7b10a791239e17e2b6ad0fac3dbdef93..1b08af99afe8df4bb92bb4b1a7d9534a7526dc78 100644 (file)
@@ -371,7 +371,10 @@ public:
       case pe_string:
        return qname() + "[0] = '\\0';";
       case pe_long:
-       return qname() + " = 0;";
+        if (! local)
+          return qname() + " = (int64_t) init_" + qname() + ";"; // module_param
+        else
+          return qname() + " = 0;";
       case pe_stats:
        switch (sd.type)
          {
@@ -887,24 +890,44 @@ c_unparser::emit_common_header ()
 void
 c_unparser::emit_global (vardecl *v)
 {
+  string vn = c_varname (v->name);
+
   if (v->arity == 0)
     o->newline() << "static "
                 << c_typename (v->type)
                 << " "
-                << "global_" << c_varname (v->name)
+                << "global_" << vn
                 << ";";
   else if (v->type == pe_stats)
     {
       o->newline() << "static PMAP global_" 
-                  << c_varname(v->name) << ";";
+                  << vn << ";";
     }
   else
     {
       o->newline() << "static MAP global_" 
-                  << c_varname(v->name) << ";";
+                  << vn << ";";
     }
   o->newline() << "static rwlock_t "
-               << "global_" << c_varname (v->name) << "_lock;";
+               << "global_" << vn << "_lock;";
+
+  // Emit module_params for this global, if its type is convenient.
+  if (v->arity == 0 && v->type == pe_long)
+    {
+      // XXX: moduleparam.h does not have a 64-bit type, so let's just
+      // take a plain long here, and manually copy/widen during
+      // initialization.  See var::init().
+      o->newline() << "long init_global_" << vn << ";";
+      o->newline() << "module_param_named (" << vn << ", "
+                   << "init_global_" << vn << ", long, 0);";
+    }
+  else if (v->arity == 0 && v->type == pe_string)
+    {
+      // NB: no special copying is needed.
+      o->newline() << "module_param_string (" << vn << ", "
+                   << "global_" << vn
+                   << ", MAXSTRINGLEN, 0);";
+    }
 }
 
 
This page took 0.057465 seconds and 5 git commands to generate.