<< TIMESPRINT
<< endl;
}
- if (rc && !s.listing_mode && !s.dump_functions)
+ if (rc && !s.dump_mode)
{
clog << _("Passes: via server failed. Try again with another '-v' option.") << endl;
}
{
throw semantic_error(e);
}
- // Only output in listing if -vv is supplied:
- else if ((!s.listing_mode && !s.dump_functions) || (s.verbose > 1))
+ // Only output in dump mode if -vv is supplied:
+ else if (!s.dump_mode || (s.verbose > 1))
{
// print this one manually first because it's more important than
// the optional errs
{
symresolution_info sym (s);
- // NB: s.files can grow during this iteration, so size() can
- // return gradually increasing numbers.
- s.files.push_back (s.user_file);
-
// If we're listing functions, then we need to include all the files. Probe
// aliases won't be visited/derived so all we gain are the functions, global
// variables, and any real probes (e.g. begin probes). NB: type resolution for
// a specific function arg may fail if it could only be determined from a
// function call in one of the skipped aliases.
- if (s.dump_functions)
+ if (s.dump_mode == systemtap_session::dump_functions)
{
s.files.insert(s.files.end(), s.library_files.begin(),
s.library_files.end());
}
+ else if (s.user_file)
+ {
+ // Normal run: seed s.files with user_file and let it grow through the
+ // find_* functions. NB: s.files can grow during this iteration, so
+ // size() can return gradually increasing numbers.
+ s.files.push_back (s.user_file);
+ }
for (unsigned i = 0; i < s.files.size(); i++)
{
// Keep unread global variables for probe end value display.
void add_global_var_display (systemtap_session& s)
{
- // Don't generate synthetic end probes when in listings mode;
- // it would clutter up the list of probe points with "end ...".
- // Also don't bother in function dump mode, since it'll never be used.
- if (s.listing_mode || s.dump_functions) return;
+ // Don't generate synthetic end probes when in listing mode; it would clutter
+ // up the list of probe points with "end ...". In fact, don't bother in any
+ // dump mode at all, since it'll never be used.
+ if (s.dump_mode) return;
varuse_collecting_visitor vut(s);
if (rc == 0) rc = semantic_pass_stats (s);
if (rc == 0) embeddedcode_info_pass (s);
- if (s.num_errors() == 0 && s.probes.size() == 0 && !s.listing_mode)
+ if (s.num_errors() == 0 && s.probes.size() == 0 && !s.dump_mode)
throw SEMANTIC_ERROR (_("no probes found"));
}
catch (const semantic_error& e)
// PR11443
// NB: listing mode only cares whether we have any probes,
// so all previous error conditions are disregarded.
- if (s.listing_mode)
+ if (s.dump_mode == systemtap_session::dump_matched_probes ||
+ s.dump_mode == systemtap_session::dump_matched_probes_vars)
rc = s.probes.empty();
// If we're dumping functions, only error out if no functions were found
- if (s.dump_functions)
+ if (s.dump_mode == systemtap_session::dump_functions)
rc = s.functions.empty();
return rc;
functiondecl* fd = it->second;
if (ftv.traversed.find(fd) == ftv.traversed.end())
{
- if (fd->tok->location.file->name == s.user_file->name && ! fd->synthetic)// !tapset
+ if (! fd->synthetic && s.user_file &&
+ fd->tok->location.file->name == s.user_file->name) // !tapset
s.print_warning (_F("Eliding unused function '%s'", fd->name.c_str()), fd->tok);
// s.functions.erase (it); // NB: can't, since we're already iterating upon it
new_unused_functions.push_back (fd);
if (vut.read.find (l) == vut.read.end() &&
vut.written.find (l) == vut.written.end())
{
- if (l->tok->location.file->name == s.user_file->name) // !tapset
+ if (s.user_file &&
+ l->tok->location.file->name == s.user_file->name) // !tapset
s.print_warning (_F("Eliding unused variable '%s'", l->name.c_str()), l->tok);
if (s.tapset_compile_coverage) {
s.probes[i]->unused_locals.push_back
if (vut.read.find (l) == vut.read.end() &&
vut.written.find (l) == vut.written.end())
{
- if (l->tok->location.file->name == s.user_file->name) // !tapset
+ if (s.user_file &&
+ l->tok->location.file->name == s.user_file->name) // !tapset
s.print_warning (_F("Eliding unused variable '%s'", l->name.c_str()), l->tok);
if (s.tapset_compile_coverage) {
fd->unused_locals.push_back (fd->locals[j]);
if (vut.read.find (l) == vut.read.end() &&
vut.written.find (l) == vut.written.end())
{
- if (l->tok->location.file->name == s.user_file->name) // !tapset
+ if (s.user_file &&
+ l->tok->location.file->name == s.user_file->name) // !tapset
s.print_warning (_F("Eliding unused variable '%s'", l->name.c_str()), l->tok);
if (s.tapset_compile_coverage) {
s.unused_globals.push_back(s.globals[i]);
session.print_warning("eliding write-only ", *e->left->tok);
else
*/
- if (e->left->tok->location.file->name == session.user_file->name) // !tapset
+ if (session.user_file &&
+ e->left->tok->location.file->name == session.user_file->name) // !tapset
session.print_warning(_F("Eliding assignment to '%s'", leftvar->name.c_str()), e->tok);
provide (e->right); // goodbye assignment*
relaxed_p = false;
session.print_warning("eliding never-assigned ", *s->value->tok);
else
*/
- if (s->value->tok->location.file->name == session.user_file->name) // not tapset
+ if (session.user_file &&
+ s->value->tok->location.file->name == session.user_file->name) // not tapset
session.print_warning("Eliding side-effect-free expression ", s->tok);
// NB: this 0 pointer is invalid to leave around for any length of
static void
printscript(systemtap_session& s, ostream& o)
{
- if (s.listing_mode)
+ if (s.dump_mode == systemtap_session::dump_matched_probes ||
+ s.dump_mode == systemtap_session::dump_matched_probes_vars)
{
// We go through some heroic measures to produce clean output.
// Record the alias and probe pointer as <name, set<derived_probe *> >
o << it->first; // probe name or alias
// Print the locals and arguments for -L mode only
- if (s.listing_mode_vars)
+ if (s.dump_mode == systemtap_session::dump_matched_probes_vars)
{
map<string,unsigned> var_count; // format <"name:type",count>
map<string,unsigned> arg_count;
// PASS 1b: PARSING USER SCRIPT
PROBE1(stap, pass1b__start, &s);
- if (s.script_file == "-")
- {
- s.user_file = parse (s, cin, s.guru_mode, false /* errs_as_warnings */);
- }
- else if (s.script_file != "")
+ // Only try to parse a user script if the user provided one, or if we have to
+ // make one (as is the case for listing mode). Otherwise, s.user_script
+ // remains NULL.
+ if (!s.script_file.empty() ||
+ !s.cmdline_script.empty() ||
+ s.dump_mode == systemtap_session::dump_matched_probes ||
+ s.dump_mode == systemtap_session::dump_matched_probes_vars)
{
- s.user_file = parse (s, s.script_file, s.guru_mode, false /* errs_as_warnings */);
- }
- else
- {
- istringstream ii (s.cmdline_script);
- s.user_file = parse (s, ii, s.guru_mode, false /* errs_as_warnings */);
- }
- if (s.user_file == 0)
- {
- // Syntax errors already printed.
- rc ++;
+ if (s.script_file == "-")
+ {
+ s.user_file = parse (s, cin, s.guru_mode,
+ false /* errs_as_warnings */);
+ }
+ else if (s.script_file != "")
+ {
+ s.user_file = parse (s, s.script_file, s.guru_mode,
+ false /* errs_as_warnings */);
+ }
+ else if (s.cmdline_script != "")
+ {
+ istringstream ii (s.cmdline_script);
+ s.user_file = parse (s, ii, s.guru_mode,
+ false /* errs_as_warnings */);
+ }
+ else // listing mode
+ {
+ istringstream ii ("probe " + s.dump_matched_pattern + " {}");
+ s.user_file = parse (s, ii, s.guru_mode,
+ false /* errs_as_warnings */);
+ }
+ if (s.user_file == 0)
+ {
+ // Syntax errors already printed.
+ rc ++;
+ }
}
// Dump a list of probe aliases picked up, if requested
- if (s.dump_probe_aliases)
+ if (s.dump_mode == systemtap_session::dump_probe_aliases)
{
set<string> aliases;
vector<stapfile*>::const_iterator file;
<< endl;
}
- if (rc && !s.listing_mode)
+ if (rc && !s.dump_mode)
cerr << _("Pass 1: parse failed. [man error::pass1]") << endl;
PROBE1(stap, pass1__end, &s);
assert_no_interrupts();
- if (rc || s.last_pass == 1) return rc;
+ if (rc || s.last_pass == 1 ||
+ s.dump_mode == systemtap_session::dump_probe_aliases)
+ return rc;
times (& tms_before);
gettimeofday (&tv_before, NULL);
rc = semantic_pass (s);
// Dump a list of known probe point types, if requested.
- if (s.dump_probe_types)
+ if (s.dump_mode == systemtap_session::dump_probe_types)
s.pattern_root->dump (s);
-
// Dump a list of functions we picked up, if requested.
- if (s.dump_functions)
+ else if (s.dump_mode == systemtap_session::dump_functions)
{
map<string,functiondecl*>::const_iterator func;
for (func = s.functions.begin();
}
}
// Dump the whole script if requested, or if we stop at 2
- else if (s.listing_mode || (rc == 0 && s.last_pass == 2))
+ else if (s.dump_mode == systemtap_session::dump_matched_probes ||
+ s.dump_mode == systemtap_session::dump_matched_probes_vars ||
+ (rc == 0 && s.last_pass == 2))
printscript(s, cout);
times (& tms_after);
<< TIMESPRINT
<< endl;
- if (rc && !s.listing_mode && !s.dump_functions && !s.try_server ())
+ if (rc && !s.dump_mode && !s.try_server ())
cerr << _("Pass 2: analysis failed. [man error::pass2]") << endl;
PROBE1(stap, pass2__end, &s);
assert_no_interrupts();
- // NB: listing_mode or dump_functions mode set last_pass to 2
- if (rc || s.last_pass == 2) return rc;
+ // NB: none of the dump modes need to go beyond pass-2. If this changes, break
+ // into individual modes here.
+ if (rc || s.last_pass == 2 || s.dump_mode)
+ return rc;
rc = prepare_translate_pass (s);
assert_no_interrupts();
manage_server_trust (ss);
#endif
- // Run the passes only if a script has been specified. The requirement for
- // a script has already been checked in systemtap_session::check_options.
- // Run the passes also if a dump of supported probe types has been requested via a server.
- if (ss.have_script || (ss.dump_probe_types && ! s.specified_servers.empty ()))
+ // Run the passes only if a script has been specified or if we're
+ // dumping something. The requirement for a script has already been
+ // checked in systemtap_session::check_options.
+ if (ss.have_script || ss.dump_mode)
{
// Run passes 0-4 for each unique session,
// either locally or using a compile-server.
if (rc || s.perpass_verbose[0] >= 1)
s.explain_auto_options ();
}
- else if (ss.dump_probe_types)
- {
- // Dump a list of known probe point types, if requested.
- register_standard_tapsets(ss);
- ss.pattern_root->dump (ss);
- }
}
// Run pass 5, if requested
[
.I ARGUMENTS
]
+.br
+.B stap
+[
+.I OPTIONS
+]
+.B \-\-dump-probe-types
+.br
+.B stap
+[
+.I OPTIONS
+]
+.B \-\-dump-probe-aliases
+.br
+.B stap
+[
+.I OPTIONS
+]
+.B \-\-dump-functions
.SH DESCRIPTION
.TP
.BI \-\-dump-probe-types
-Dumps a list of supported probe types. If
+Dumps a list of supported probe types and exits. If
.IR \-\-privilege=stapusr
is also specified, the list will be limited to probe types available to unprivileged users.
unoptimized = false;
suppress_warnings = false;
panic_warnings = false;
- listing_mode = false;
- listing_mode_vars = false;
- dump_probe_types = false;
- dump_probe_aliases = false;
- dump_functions = false;
+ dump_mode = systemtap_session::dump_none;
+ dump_matched_pattern = "";
#ifdef ENABLE_PROLOGUES
prologue_searching = true;
unoptimized = other.unoptimized;
suppress_warnings = other.suppress_warnings;
panic_warnings = other.panic_warnings;
- listing_mode = other.listing_mode;
- listing_mode_vars = other.listing_mode_vars;
- dump_probe_types = other.dump_probe_types;
- dump_probe_aliases = other.dump_probe_aliases;
- dump_functions = other.dump_functions;
+ dump_mode = other.dump_mode;
+ dump_matched_pattern = other.dump_matched_pattern;
prologue_searching = other.prologue_searching;
version ();
clog
<< endl
- << _F("Usage: stap [options] FILE Run script in file.\n"
- " or: stap [options] - Run script on stdin.\n"
- " or: stap [options] -e SCRIPT Run given script.\n"
- " or: stap [options] -l PROBE List matching probes.\n"
- " or: stap [options] -L PROBE List matching probes and local variables.\n\n"
+ << _F(
+ "Usage: stap [options] FILE Run script in file.\n"
+ " or: stap [options] - Run script on stdin.\n"
+ " or: stap [options] -e SCRIPT Run given script.\n"
+ " or: stap [options] -l PROBE List matching probes.\n"
+ " or: stap [options] -L PROBE List matching probes and local variables.\n"
+ " or: stap [options] --dump-probe-types List available probe types.\n"
+ " or: stap [options] --dump-probe-aliases List available probe aliases.\n"
+ " or: stap [options] --dump-functions List available functions.\n\n"
"Options (in %s/rc and on command line):\n"
" -- end of translator options, script options follow\n"
" -h --help show help\n"
cerr << _("Invalid pass number (should be 1-5).") << endl;
return 1;
}
- if (listing_mode && last_pass != 2)
- {
- cerr << _("Listing (-l) mode implies pass 2.") << endl;
- return 1;
- }
server_args.push_back (string ("-") + (char)grc + optarg);
break;
break;
case 'L':
- listing_mode_vars = true;
- unoptimized = true; // This causes retention of variables for listing_mode
- // fallthrough
+ if (dump_mode)
+ {
+ cerr << _("ERROR: only one of the -l/-L/--dump-* "
+ "switches may be specified") << endl;
+ return 1;
+ }
+ server_args.push_back (string ("-") + (char)grc + optarg);
+ dump_mode = systemtap_session::dump_matched_probes_vars;
+ dump_matched_pattern = optarg;
+ unoptimized = true; // This causes retention of vars for listing
+ suppress_warnings = true;
+ break;
+
case 'l':
- suppress_warnings = true;
- listing_mode = true;
- last_pass = 2;
- if (have_script)
+ if (dump_mode)
{
- cerr << _("Only one script can be given on the command line.")
- << endl;
- return 1;
+ cerr << _("ERROR: only one of the -l/-L/--dump-* "
+ "switches may be specified") << endl;
+ return 1;
}
- server_args.push_back (string ("-") + (char)grc + optarg);
- cmdline_script = string("probe ") + string(optarg) + " {}";
- have_script = true;
+ server_args.push_back (string ("-") + (char)grc + optarg);
+ dump_mode = systemtap_session::dump_matched_probes;
+ dump_matched_pattern = optarg;
+ suppress_warnings = true;
break;
case 'F':
systemtap_v_check = true;
break;
- case LONG_OPT_DUMP_PROBE_TYPES:
- server_args.push_back ("--dump-probe-types");
- dump_probe_types = true;
- break;
+ case LONG_OPT_DUMP_PROBE_TYPES:
+ if (dump_mode)
+ {
+ cerr << _("ERROR: only one of the -l/-L/--dump-* "
+ "switches may be specified") << endl;
+ return 1;
+ }
+ server_args.push_back ("--dump-probe-types");
+ dump_mode = systemtap_session::dump_probe_types;
+ break;
- case LONG_OPT_DUMP_PROBE_ALIASES:
- server_args.push_back ("--dump-probe-aliases");
- suppress_warnings = true;
- dump_probe_aliases = true;
- last_pass = 1;
- if (have_script)
- {
- cerr << _("Only one script can be given on the command line.")
- << endl;
- return 1;
- }
- cmdline_script = string("probe begin {}");
- have_script = true;
- break;
+ case LONG_OPT_DUMP_PROBE_ALIASES:
+ if (dump_mode)
+ {
+ cerr << _("ERROR: only one of the -l/-L/--dump-* "
+ "switches may be specified") << endl;
+ return 1;
+ }
+ server_args.push_back ("--dump-probe-aliases");
+ suppress_warnings = true;
+ dump_mode = systemtap_session::dump_probe_aliases;
+ break;
- case LONG_OPT_DUMP_FUNCTIONS:
- dump_functions = true;
- suppress_warnings = true;
- unoptimized = true; // so we keep never-called functions
- last_pass = 2;
- server_args.push_back ("--dump-functions");
- if (have_script)
- {
- cerr << _("Only one script can be given on the command line.")
- << endl;
- return 1;
- }
- cmdline_script = string("probe begin {}");
- have_script = true;
- break;
+ case LONG_OPT_DUMP_FUNCTIONS:
+ if (dump_mode)
+ {
+ cerr << _("ERROR: only one of the -l/-L/--dump-* "
+ "switches may be specified") << endl;
+ return 1;
+ }
+ server_args.push_back ("--dump-functions");
+ suppress_warnings = true;
+ dump_mode = systemtap_session::dump_functions;
+ unoptimized = true; // Keep unused functions (which is all of them)
+ break;
case LONG_OPT_SUPPRESS_HANDLER_ERRORS:
suppress_handler_errors = true;
args.push_back (string (argv[i]));
}
- // We don't need a script with --list-servers, --trust-servers, or --dump-probe-types.
- bool need_script = server_status_strings.empty () && server_trust_spec.empty () && ! dump_probe_types;
+ // We don't need a script with --list-servers, --trust-servers, or any dump mode
+ bool need_script = server_status_strings.empty () &&
+ server_trust_spec.empty () &&
+ !dump_mode;
if (benchmark_sdt_loops > 0 || benchmark_sdt_threads > 0)
{
cerr << _("A script must be specified.") << endl;
usage(1);
}
+ if (dump_mode && have_script)
+ {
+ cerr << _("Cannot specify a script with -l/-L/--dump-* switches.") << endl;
+ usage(1);
+ }
+ if (dump_mode && last_pass != 5)
+ {
+ cerr << _("Cannot specify -p with -l/-L/--dump-* switches.") << endl;
+ usage(1);
+ }
#if ! HAVE_NSS
if (client_options)
systemtap_session::register_library_aliases()
{
vector<stapfile*> files(library_files);
- files.push_back(user_file);
+ if (user_file) // May be NULL, e.g. in dump modes
+ files.push_back(user_file);
for (unsigned f = 0; f < files.size(); ++f)
{
systemtap_session::print_error (const semantic_error& se)
{
// skip error message printing for listing mode with low verbosity
- if ((this->listing_mode || this->dump_functions) && this->verbose <= 1)
+ if (this->dump_mode && this->verbose <= 1)
{
seen_errors[se.errsrc_chain()]++; // increment num_errors()
return;
bool modname_given;
bool keep_tmpdir;
bool guru_mode;
- bool listing_mode;
- bool listing_mode_vars;
bool bulk_mode;
bool unoptimized;
bool suppress_warnings;
bool privilege_set;
bool systemtap_v_check;
bool tmpdir_opt_set;
- bool dump_probe_types;
- bool dump_probe_aliases;
- bool dump_functions;
+
+ enum
+ { dump_none, // no dumping requested
+ dump_probe_types, // dump standard tapset probes
+ dump_probe_aliases, // dump tapset probe aliases
+ dump_functions, // dump tapset functions
+ dump_matched_probes, // dump matching probes (-l)
+ dump_matched_probes_vars // dump matching probes and their variables (-L)
+ } dump_mode;
+
+ // Pattern to match against in listing mode (-l/-L)
+ std::string dump_matched_pattern;
+
int download_dbinfo;
bool suppress_handler_errors;
bool suppress_time_limits;
}
// Save the local variables for listing mode. If the scope_die is null,
// local vars aren't accessible, so no need to invoke saveargs (PR10820).
- if (!null_die(scope_die) && q.sess.listing_mode_vars)
- saveargs(q, scope_die, dwfl_addr);
+ if (!null_die(scope_die) &&
+ q.sess.dump_mode == systemtap_session::dump_matched_probes_vars)
+ saveargs(q, scope_die, dwfl_addr);
}
// Reset the sole element of the "locations" vector as a