// -*- C++ -*- // Copyright (C) 2005-2019 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 // Public License (GPL); either version 2, or (at your option) any // later version. #ifndef SESSION_H #define SESSION_H #include "config.h" #if ENABLE_NLS #include #include #endif #include #include #include #include #include #include #include #include extern "C" { #include #include #include } #include "privilege.h" #include "util.h" #include "stringtable.h" /* statistical operations used with a global */ #define STAT_OP_NONE 1 << 0 #define STAT_OP_COUNT 1 << 1 #define STAT_OP_SUM 1 << 2 #define STAT_OP_MIN 1 << 3 #define STAT_OP_MAX 1 << 4 #define STAT_OP_AVG 1 << 5 #define STAT_OP_VARIANCE 1 << 6 // forward decls for all referenced systemtap types class stap_hash; class match_node; struct stapfile; struct vardecl; struct token; struct functiondecl; struct derived_probe; struct be_derived_probe_group; struct generic_kprobe_derived_probe_group; struct hwbkpt_derived_probe_group; struct perf_derived_probe_group; struct uprobe_derived_probe_group; struct utrace_derived_probe_group; struct itrace_derived_probe_group; struct task_finder_derived_probe_group; struct vma_tracker_derived_probe_group; struct timer_derived_probe_group; struct netfilter_derived_probe_group; struct profile_derived_probe_group; struct mark_derived_probe_group; struct tracepoint_derived_probe_group; struct hrtimer_derived_probe_group; struct procfs_derived_probe_group; struct dynprobe_derived_probe_group; struct python_derived_probe_group; struct embeddedcode; struct stapdfa; class translator_output; struct unparser; struct semantic_error; struct module_cache; struct update_visitor; struct compile_server_cache; class language_server; struct typeresolution_info; // XXX: a generalized form of this descriptor could be associated with // a vardecl instead of out here at the systemtap_session level. struct statistic_decl { statistic_decl(int _stat_ops = 0) : type(none), linear_low(0), linear_high(0), linear_step(0), bit_shift(0), stat_ops(_stat_ops) {} enum { none, linear, logarithmic } type; int64_t linear_low; int64_t linear_high; int64_t linear_step; int bit_shift; int stat_ops; bool operator==(statistic_decl const & other) { return type == other.type && linear_low == other.linear_low && linear_high == other.linear_high && linear_step == other.linear_step; } }; struct macrodecl; // defined in parse.h struct parse_error: public std::runtime_error { const token* tok; bool skip_some; const parse_error *chain; const std::string errsrc; ~parse_error () throw () {} parse_error (const std::string& src, const std::string& msg): runtime_error (msg), tok (0), skip_some (true), chain(0), errsrc(src) {} parse_error (const std::string& src, const std::string& msg, const token* t): runtime_error (msg), tok (t), skip_some (true), chain(0), errsrc(src) {} parse_error (const std::string& src, const std::string& msg, bool skip): runtime_error (msg), tok (0), skip_some (skip), chain(0), errsrc(src) {} std::string errsrc_chain(void) const { return errsrc + (chain ? "|" + chain->errsrc_chain() : ""); } }; struct symresolution_info; struct systemtap_session { private: // disable implicit constructors by not implementing these systemtap_session (const systemtap_session& other); systemtap_session& operator= (const systemtap_session& other); // copy constructor used by ::clone() systemtap_session (const systemtap_session& other, const std::string& arch, const std::string& kern); public: systemtap_session (); ~systemtap_session (); // To reset the tmp_dir void create_tmp_dir(); void remove_tmp_dir(); void reset_tmp_dir(); // NB: It is very important for all of the above (and below) fields // to be cleared in the systemtap_session ctor (session.cxx). void setup_kernel_release (const std::string& kstr); void insert_loaded_modules (); // command line parsing int parse_cmdline (int argc, char * const argv []); bool parse_cmdline_runtime (const std::string& opt_runtime); std::string version_string (); std::pair kernel_version_range(); void version (); void usage (int exitcode); void check_options (int argc, char * const argv []); // Mark morehelp as used, otherwise LTO might optimize // this one out, and testcases such as at_var_mark.exp // would miss it. static const char* morehelp __attribute__ ((used)); // NB: It is very important for all of the above (and below) fields // to be cleared in the systemtap_session ctor (session.cxx). // command line args std::string script_file; // FILE std::string cmdline_script; // -e PROGRAM std::vector additional_scripts; // -E SCRIPT std::stringstream stdin_script; // stdin script (stap -) bool have_script; std::vector include_path; int include_arg_start; std::vector c_macros; std::vector args; std::vector used_args; std::vector kbuildflags; // -B var=val std::vector globalopts; // -G var=val std::vector modinfos; // --modinfo tag=value std::string release; std::string kernel_release; std::string kernel_base_release; std::string kernel_build_tree; std::string kernel_source_tree; std::vector kernel_extra_cflags; std::map kernel_config; std::set kernel_exports; std::set kernel_functions; int parse_kernel_config (); int parse_kernel_exports (); int parse_kernel_functions (); std::string sysroot; std::map sysenv; bool update_release_sysroot; std::string machine; std::string architecture; bool native_build; std::string runtime_path; bool runtime_specified; std::string data_path; std::string module_name; const std::string module_filename() const; std::string stapconf_name; std::string output_file; std::string size_option; std::string cmd; std::string cmd_file(); std::string compatible; // use (strverscmp(s.compatible.c_str(), "N.M") >= 0) int target_pid; int last_pass; unsigned perpass_verbose[5]; unsigned verbose; bool timing; bool save_module; bool save_uprobes; bool modname_given; bool keep_tmpdir; bool guru_mode; bool bulk_mode; bool unoptimized; bool suppress_warnings; bool panic_warnings; int buffer_size; bool tapset_compile_coverage; bool need_uprobes; bool need_unwind; bool need_symbols; bool need_lines; std::string uprobes_path; std::string uprobes_hash; bool load_only; // flight recorder mode privilege_t privilege; bool privilege_set; bool systemtap_v_check; bool tmpdir_opt_set; bool read_stdin; bool monitor; int monitor_interval; int timeout; // in ms std::map typequery_memo; 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; bool color_errors; bool interactive_mode; bool run_example; bool no_global_var_display; bool pass_1a_complete; enum { color_never, color_auto, color_always } color_mode; enum { prologue_searching_never, prologue_searching_auto, prologue_searching_always } prologue_searching_mode; enum { kernel_runtime, dyninst_runtime, bpf_runtime } runtime_mode; bool runtime_usermode_p() const { return runtime_mode == dyninst_runtime; } bool use_bpf_raw_tracepoint; // NB: It is very important for all of the above (and below) fields // to be cleared in the systemtap_session ctor (session.cxx). // Client/server #if HAVE_NSS static bool NSPR_Initialized; // only once for all sessions void NSPR_init (); #endif bool client_options; std::string client_options_disallowed_for_unprivileged; std::vector server_status_strings; std::vector specified_servers; std::string server_trust_spec; std::vector server_args; std::string winning_server; compile_server_cache* server_cache; std::vector mok_fingerprints; std::string auto_privilege_level_msg; std::vector auto_server_msgs; bool modules_must_be_signed(); void get_mok_info(); bool module_sign_given; std::string module_sign_mok_path; // NB: It is very important for all of the above (and below) fields // to be cleared in the systemtap_session ctor (session.cxx). // Mechanism for retrying compilation with a compile server should it fail due // to lack of resources on the local host. // Once it has been decided not to try the server (e.g. syntax error), // that decision cannot be changed. int try_server_status; bool use_server_on_error; enum { try_server_unset, dont_try_server, do_try_server }; void init_try_server (); void set_try_server (int t = do_try_server); bool try_server () const { return try_server_status == do_try_server; } // HTTP client/server std::vector http_servers; // NB: It is very important for all of the above (and below) fields // to be cleared in the systemtap_session ctor (session.cxx). // Remote execution std::vector remote_uris; bool use_remote_prefix; typedef std::map, systemtap_session*> session_map_t; session_map_t subsessions; systemtap_session* clone(const std::string& arch, const std::string& release); // NB: It is very important for all of the above (and below) fields // to be cleared in the systemtap_session ctor (session.cxx). // Cache data bool use_cache; // control all caching bool use_script_cache; // control caching of pass-3/4 output bool poison_cache; // consider the cache to be write-only std::string cache_path; // usually ~/.systemtap/cache std::string hash_path; // path to the cached script module std::string stapconf_path; // path to the cached stapconf stap_hash *base_hash; // hash common to all caching // Skip bad $ vars bool skip_badvars; // NB: It is very important for all of the above (and below) fields // to be cleared in the systemtap_session ctor (session.cxx). // temporary directory for module builds etc. // hazardous - it is "rm -rf"'d at exit std::string tmpdir; std::string translated_source; // main C source code std::string symbols_source; // C source code for stap_symbols.c match_node* pattern_root; void register_library_aliases(); // data for various preprocessor library macros std::map library_macros; // parse trees for the various script files std::vector user_files; std::vector library_files; std::string script_name(); // usually user_files[0]->name std::string script_basename(); // basename of script_name() // filters to run over all code before symbol resolution // e.g. @cast expansion std::vector code_filters; // resolved globals/functions/probes for the run as a whole std::vector files; std::vector globals; std::map functions; std::map overload_count; // probe counter name -> probe associated with counter std::vector > perf_counters; std::vector probes; // see also *_probes groups below std::vector embeds; std::map stat_decls; // track things that are removed std::vector unused_globals; std::vector unused_probes; // see also *_probes groups below std::vector unused_functions; std::set empty_probes; // resolved/compiled regular expressions for the run std::map dfas; unsigned dfa_counter; // used to give unique names unsigned dfa_maxmap; // used for subexpression-tracking data structure unsigned dfa_maxtag; // ditto bool need_tagged_dfa; // triggered by /* pragma:tagged_dfa */ // Every probe in these groups must also appear in the // session.probes vector. be_derived_probe_group* be_derived_probes; generic_kprobe_derived_probe_group* generic_kprobe_derived_probes; hwbkpt_derived_probe_group* hwbkpt_derived_probes; perf_derived_probe_group* perf_derived_probes; uprobe_derived_probe_group* uprobe_derived_probes; utrace_derived_probe_group* utrace_derived_probes; itrace_derived_probe_group* itrace_derived_probes; task_finder_derived_probe_group* task_finder_derived_probes; vma_tracker_derived_probe_group* vma_tracker_derived_probes; timer_derived_probe_group* timer_derived_probes; netfilter_derived_probe_group* netfilter_derived_probes; profile_derived_probe_group* profile_derived_probes; mark_derived_probe_group* mark_derived_probes; tracepoint_derived_probe_group* tracepoint_derived_probes; hrtimer_derived_probe_group* hrtimer_derived_probes; procfs_derived_probe_group* procfs_derived_probes; dynprobe_derived_probe_group* dynprobe_derived_probes; python_derived_probe_group* python_derived_probes; // NB: It is very important for all of the above (and below) fields // to be cleared in the systemtap_session ctor (session.cxx). // unparser data translator_output* op; std::vector auxiliary_outputs; unparser* up; // some symbol addresses // XXX: these belong elsewhere; perhaps the dwflpp instance Dwarf_Addr sym_kprobes_text_start; Dwarf_Addr sym_kprobes_text_end; Dwarf_Addr sym_stext; // List of libdwfl module names to extract symbol/unwind data for. std::set unwindsym_modules; bool unwindsym_ldd; struct module_cache* module_cache; std::vector build_ids; // Secret benchmarking options unsigned long benchmark_sdt_loops; unsigned long benchmark_sdt_threads; // NB: It is very important for all of the above (and below) fields // to be cleared in the systemtap_session ctor (session.cxx). std::set seen_warnings; int suppressed_warnings; std::map seen_errors; // NB: can change to a set if threshold is 1 int suppressed_errors; int warningerr_count; // see comment in systemtap_session::print_error // Returns number of critical errors (not counting those part of warnings) unsigned num_errors () { return (seen_errors.size() // all the errors we've encountered - warningerr_count // except those considered warningerrs + (panic_warnings ? seen_warnings.size() : 0)); // plus warnings if -W given } std::set rpms_checked; // enlisted by filename+rpm_type std::set rpms_to_install; // resulting rpms translator_output* op_create_auxiliary(bool trailer_p = false); int target_namespaces_pid; unsigned suppress_costly_diagnostics; /* set during processing of optional probes */ const token* last_token; // Used during the -semantic pass- for tabulating still-unresolved counts typeresolution_info* type_res_info; void print_token (std::ostream& o, const token* tok); void print_error (const semantic_error& e); std::string build_error_msg (const semantic_error& e); void print_error_source (std::ostream&, std::string&, const token* tok); void print_error_details (std::ostream&, std::string&, const semantic_error&); void print_error (const parse_error &pe, const token* tok, const std::string &input_name, bool is_warningerr = false); std::string build_error_msg (const parse_error &pe, const token* tok, const std::string &input_name); void print_warning (const std::string& w, const token* tok = 0); void printscript(std::ostream& o); void report_suppression(); // PR25841, for early probe-derivation-time symbol resolution symresolution_info* symbol_resolver; // may be NULL bool language_server_mode; language_server* lang_server; std::string build_as; uid_t build_as_uid; gid_t build_as_gid; // NB: It is very important for all of the above (and below) fields // to be cleared in the systemtap_session ctor (session.cxx). std::string colorize(const std::string& str, const std::string& type); std::string colorize(const token* tok); std::string parse_stap_color(const std::string& type); // Some automatic options settings require explanation. void enable_auto_server (const std::string &message); void explain_auto_options(); bool is_user_file (const std::string& name); bool is_primary_probe (derived_probe *dp); void clear_script_data(); // NB: It is very important for all of the above (and below) fields // to be cleared in the systemtap_session ctor (session.cxx). }; struct exit_exception: public std::runtime_error { int rc; exit_exception (int rc): runtime_error (_F("early exit requested, rc=%d", rc)), rc(rc) {} }; // global counter of SIGINT/SIGTERM's received extern int pending_interrupts; // Interrupt exception subclass for catching // interrupts (i.e. ctrl-c). struct interrupt_exception: public std::runtime_error { interrupt_exception (): runtime_error (_("interrupt received")){} }; void assert_no_interrupts(); #endif // SESSION_H /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */