summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfche <fche>2006-02-23 22:35:40 +0000
committerfche <fche>2006-02-23 22:35:40 +0000
commit213bee8fc2b826ca8467fbbe35398450449bf082 (patch)
tree7e4a637195c704109e333906b377c7060970cf23
parent5ae893a12a652a31d2f96f4e81aab78c922b6ec8 (diff)
downloadsystemtap-steved-213bee8fc2b826ca8467fbbe35398450449bf082.tar.gz
systemtap-steved-213bee8fc2b826ca8467fbbe35398450449bf082.tar.xz
systemtap-steved-213bee8fc2b826ca8467fbbe35398450449bf082.zip
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.
-rw-r--r--ChangeLog15
-rw-r--r--main.cxx12
-rw-r--r--parse.cxx35
-rw-r--r--parse.h3
-rw-r--r--runtime/stpd/ChangeLog7
-rw-r--r--runtime/stpd/librelay.c8
-rw-r--r--runtime/stpd/stpd.c21
-rw-r--r--stap.1.in26
-rw-r--r--tapsets.cxx2
-rwxr-xr-xtestsuite/semok/args.stp3
-rw-r--r--translate.cxx33
11 files changed, 141 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 469c43b7..ea9c44d7 100644
--- 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.
diff --git a/main.cxx b/main.cxx
index 127e667d..27e0cdd4 100644
--- 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;
diff --git a/parse.cxx b/parse.cxx
index dcdb7260..04e01ebc 100644
--- 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 81544eb9..b9d56152 100644
--- 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;
};
diff --git a/runtime/stpd/ChangeLog b/runtime/stpd/ChangeLog
index e72ec4d0..1695cf6e 100644
--- a/runtime/stpd/ChangeLog
+++ b/runtime/stpd/ChangeLog
@@ -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
diff --git a/runtime/stpd/librelay.c b/runtime/stpd/librelay.c
index e2beece2..719f026d 100644
--- a/runtime/stpd/librelay.c
+++ b/runtime/stpd/librelay.c
@@ -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) {
diff --git a/runtime/stpd/stpd.c b/runtime/stpd/stpd.c
index c12ca096..c6cc913d 100644
--- a/runtime/stpd/stpd.c
+++ b/runtime/stpd/stpd.c
@@ -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");
diff --git a/stap.1.in b/stap.1.in
index 48fc7dcb..c3ce0725 100644
--- 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
diff --git a/tapsets.cxx b/tapsets.cxx
index 31b2515a..2e2c933e 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -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
index 00000000..00475625
--- /dev/null
+++ b/testsuite/semok/args.stp
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+./stap -p2 -e 'probe begin { log (@1 . string($2)) }' hello 0xdeadbeef
diff --git a/translate.cxx b/translate.cxx
index becb7bcd..1b08af99 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -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);";
+ }
}