]> sourceware.org Git - systemtap.git/blame - session.cxx
Fix construction of ".local" variant of the DNS name on server certificates.
[systemtap.git] / session.cxx
CommitLineData
e2012a7a 1// session functions
19ae853d 2// Copyright (C) 2010-2014 Red Hat Inc.
e2012a7a
DB
3//
4// This file is part of systemtap, and is free software. You can
5// redistribute it and/or modify it under the terms of the GNU General
6// Public License (GPL); either version 2, or (at your option) any
7// later version.
8
9#include "config.h"
10#include "session.h"
11#include "cache.h"
60cf5fae 12#include "stapregex.h"
e2012a7a 13#include "elaborate.h"
aa4d21c0
DB
14#include "translate.h"
15#include "buildrun.h"
16#include "coveragedb.h"
e2012a7a
DB
17#include "hash.h"
18#include "task_finder.h"
aa4d21c0
DB
19#include "csclient.h"
20#include "rpm_finder.h"
e2012a7a 21#include "util.h"
73f52eb4 22#include "cmdline.h"
e2012a7a 23#include "git_version.h"
e587f6ca 24#include "version.h"
e2012a7a 25
85007c04
DB
26#include <cerrno>
27#include <cstdlib>
28
e2012a7a 29extern "C" {
e2012a7a
DB
30#include <getopt.h>
31#include <limits.h>
a83cc46b 32#include <grp.h>
2dce8c42 33#include <sys/stat.h>
e2012a7a 34#include <sys/utsname.h>
878b2f3f 35#include <sys/resource.h>
e2012a7a 36#include <elfutils/libdwfl.h>
47caa991 37#include <unistd.h>
dbff9ecf 38#include <sys/wait.h>
e2012a7a
DB
39}
40
b0e5fa85
DB
41#if HAVE_NSS
42extern "C" {
43#include <nspr.h>
44}
45#endif
46
e2012a7a
DB
47#include <string>
48
49using namespace std;
50
51/* getopt variables */
52extern int optind;
53
54#define PATH_TBD string("__TBD__")
55
48e74294 56#if HAVE_NSS
44edbcd6 57bool systemtap_session::NSPR_Initialized = false;
48e74294 58#endif
44edbcd6 59
e2012a7a
DB
60systemtap_session::systemtap_session ():
61 // NB: pointer members must be manually initialized!
abc15290 62 // NB: don't forget the copy constructor too!
4441e344 63 runtime_mode(kernel_runtime),
e2012a7a
DB
64 base_hash(0),
65 pattern_root(new match_node),
66 user_file (0),
d2548fe7 67 dfa_counter (0),
60cf5fae
SM
68 dfa_maxstate (0),
69 dfa_maxtag (0),
26c2e4c2 70 need_tagged_dfa (false),
e2012a7a
DB
71 be_derived_probes(0),
72 dwarf_derived_probes(0),
73 kprobe_derived_probes(0),
74 hwbkpt_derived_probes(0),
75 perf_derived_probes(0),
76 uprobe_derived_probes(0),
77 utrace_derived_probes(0),
78 itrace_derived_probes(0),
79 task_finder_derived_probes(0),
80 timer_derived_probes(0),
8d9609f5 81 netfilter_derived_probes(0),
e2012a7a
DB
82 profile_derived_probes(0),
83 mark_derived_probes(0),
84 tracepoint_derived_probes(0),
85 hrtimer_derived_probes(0),
86 procfs_derived_probes(0),
f31a77f5 87 dynprobe_derived_probes(0),
e7d4410d 88 java_derived_probes(0),
e2012a7a
DB
89 op (0), up (0),
90 sym_kprobes_text_start (0),
91 sym_kprobes_text_end (0),
92 sym_stext (0),
93 module_cache (0),
3d0a328d
JS
94 benchmark_sdt_loops(0),
95 benchmark_sdt_threads(0),
1c1f304d 96 suppressed_warnings(0),
9e1a2390 97 suppressed_errors(0),
7ac01ea0 98 warningerr_count(0),
e2012a7a 99 last_token (0)
e2012a7a
DB
100{
101 struct utsname buf;
102 (void) uname (& buf);
103 kernel_release = string (buf.release);
104 release = kernel_release;
105 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
daa75206 106 architecture = machine = normalize_machine(buf.machine);
e2012a7a
DB
107
108 for (unsigned i=0; i<5; i++) perpass_verbose[i]=0;
2dce8c42 109 verbose = 0;
e2012a7a
DB
110
111 have_script = false;
2fad97fd
DB
112 runtime_specified = false;
113 include_arg_start = -1;
e2012a7a
DB
114 timing = false;
115 guru_mode = false;
116 bulk_mode = false;
117 unoptimized = false;
118 suppress_warnings = false;
119 panic_warnings = false;
120 listing_mode = false;
121 listing_mode_vars = false;
b82d77b4 122 dump_probe_types = false;
e2012a7a
DB
123
124#ifdef ENABLE_PROLOGUES
125 prologue_searching = true;
126#else
127 prologue_searching = false;
128#endif
129
130 buffer_size = 0;
131 last_pass = 5;
132 module_name = "stap_" + lex_cast(getpid());
133 stapconf_name = "stapconf_" + lex_cast(getpid()) + ".h";
134 output_file = ""; // -o FILE
305fac7d 135 tmpdir_opt_set = false;
e2012a7a 136 save_module = false;
5c854d7c 137 modname_given = false;
e2012a7a
DB
138 keep_tmpdir = false;
139 cmd = "";
140 target_pid = 0;
e2012a7a
DB
141 use_cache = true;
142 use_script_cache = true;
143 poison_cache = false;
144 tapset_compile_coverage = false;
145 need_uprobes = false;
08badca8 146 need_unwind = false;
8af41ec2 147 need_symbols = false;
474d17ad 148 uprobes_path = "";
e2012a7a
DB
149 load_only = false;
150 skip_badvars = false;
42e38653 151 privilege = pr_stapdev;
73f52eb4 152 privilege_set = false;
e2012a7a
DB
153 omit_werror = false;
154 compatible = VERSION; // XXX: perhaps also process GIT_SHAID if available?
155 unwindsym_ldd = false;
156 client_options = false;
eff14db3 157 server_cache = NULL;
4e78c716
DB
158 auto_privilege_level_msg = "";
159 auto_server_msgs.clear ();
3e1ec884 160 use_server_on_error = false;
44edbcd6 161 try_server_status = try_server_unset;
756cfd49 162 use_remote_prefix = false;
a07a2c28 163 systemtap_v_check = false;
ea60076d 164 download_dbinfo = 0;
7baf48e9 165 suppress_handler_errors = false;
50f2545f 166 native_build = true; // presumed
05fb3e0c
WF
167 sysroot = "";
168 update_release_sysroot = false;
152fa051 169 suppress_time_limits = false;
b8f96d36
JL
170 color_mode = color_auto;
171 color_errors = isatty(STDERR_FILENO) // conditions for coloring when
172 && strcmp(getenv("TERM") ?: "notdumb", "dumb"); // on auto
dbff9ecf 173
43179f10
FCE
174 // PR12443: put compiled-in / -I paths in front, to be preferred during
175 // tapset duplicate-file elimination
176 const char* s_p = getenv ("SYSTEMTAP_TAPSET");
177 if (s_p != NULL)
178 {
179 include_path.push_back (s_p);
180 }
181 else
182 {
183 include_path.push_back (string(PKGDATADIR) + "/tapset");
184 }
185
6ac63adf 186 /* adding in the XDG_DATA_DIRS variable path,
2dce8c42
DB
187 * this searches in conjunction with SYSTEMTAP_TAPSET
188 * to locate stap scripts, either can be disabled if
189 * needed using env $PATH=/dev/null where $PATH is the
190 * path you want disabled
191 */
6ac63adf
LB
192 const char* s_p1 = getenv ("XDG_DATA_DIRS");
193 if ( s_p1 != NULL )
194 {
195 vector<string> dirs;
196 tokenize(s_p1, dirs, ":");
197 for(vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i)
198 {
199 include_path.push_back(*i + "/systemtap/tapset");
200 }
201 }
e2012a7a 202
e2012a7a
DB
203 const char* s_r = getenv ("SYSTEMTAP_RUNTIME");
204 if (s_r != NULL)
205 runtime_path = s_r;
206 else
207 runtime_path = string(PKGDATADIR) + "/runtime";
208
209 const char* s_d = getenv ("SYSTEMTAP_DIR");
210 if (s_d != NULL)
211 data_path = s_d;
212 else
213 data_path = get_home_directory() + string("/.systemtap");
214 if (create_dir(data_path.c_str()) == 1)
215 {
216 const char* e = strerror (errno);
2713ea24 217 print_warning("failed to create systemtap data directory \"" + data_path + "\" " + e + ", disabling cache support.");
e2012a7a
DB
218 use_cache = use_script_cache = false;
219 }
220
221 if (use_cache)
222 {
223 cache_path = data_path + "/cache";
224 if (create_dir(cache_path.c_str()) == 1)
225 {
226 const char* e = strerror (errno);
2713ea24 227 print_warning("failed to create cache directory (\" " + cache_path + " \") " + e + ", disabling cache support.");
e2012a7a
DB
228 use_cache = use_script_cache = false;
229 }
230 }
231
e2012a7a
DB
232 const char* s_tc = getenv ("SYSTEMTAP_COVERAGE");
233 if (s_tc != NULL)
234 tapset_compile_coverage = true;
235
236 const char* s_kr = getenv ("SYSTEMTAP_RELEASE");
237 if (s_kr != NULL) {
238 setup_kernel_release(s_kr);
239 }
b96901b7 240 create_tmp_dir();
e2012a7a
DB
241}
242
abc15290
JS
243systemtap_session::systemtap_session (const systemtap_session& other,
244 const string& arch,
245 const string& kern):
246 // NB: pointer members must be manually initialized!
247 // NB: this needs to consider everything that the base ctor does,
248 // plus copying any wanted implicit fields (strings, vectors, etc.)
4441e344 249 runtime_mode(other.runtime_mode),
abc15290
JS
250 base_hash(0),
251 pattern_root(new match_node),
252 user_file (other.user_file),
d2548fe7 253 dfa_counter(0),
98e18a65 254 need_tagged_dfa(other.need_tagged_dfa),
abc15290
JS
255 be_derived_probes(0),
256 dwarf_derived_probes(0),
257 kprobe_derived_probes(0),
258 hwbkpt_derived_probes(0),
259 perf_derived_probes(0),
260 uprobe_derived_probes(0),
261 utrace_derived_probes(0),
262 itrace_derived_probes(0),
263 task_finder_derived_probes(0),
264 timer_derived_probes(0),
8d9609f5 265 netfilter_derived_probes(0),
abc15290
JS
266 profile_derived_probes(0),
267 mark_derived_probes(0),
268 tracepoint_derived_probes(0),
269 hrtimer_derived_probes(0),
270 procfs_derived_probes(0),
f31a77f5 271 dynprobe_derived_probes(0),
e7d4410d 272 java_derived_probes(0),
abc15290
JS
273 op (0), up (0),
274 sym_kprobes_text_start (0),
275 sym_kprobes_text_end (0),
276 sym_stext (0),
277 module_cache (0),
3d0a328d
JS
278 benchmark_sdt_loops(other.benchmark_sdt_loops),
279 benchmark_sdt_threads(other.benchmark_sdt_threads),
1c1f304d 280 suppressed_warnings(0),
9e1a2390 281 suppressed_errors(0),
7ac01ea0 282 warningerr_count(0),
ed28ad1b 283 last_token (0)
abc15290
JS
284{
285 release = kernel_release = kern;
286 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
287 architecture = machine = normalize_machine(arch);
288 setup_kernel_release(kern.c_str());
50f2545f 289 native_build = false; // assumed; XXX: could be computed as in check_options()
abc15290
JS
290
291 // These are all copied in the same order as the default ctor did above.
292
293 copy(other.perpass_verbose, other.perpass_verbose + 5, perpass_verbose);
294 verbose = other.verbose;
295
296 have_script = other.have_script;
297 runtime_specified = other.runtime_specified;
298 include_arg_start = other.include_arg_start;
299 timing = other.timing;
300 guru_mode = other.guru_mode;
301 bulk_mode = other.bulk_mode;
302 unoptimized = other.unoptimized;
303 suppress_warnings = other.suppress_warnings;
304 panic_warnings = other.panic_warnings;
305 listing_mode = other.listing_mode;
306 listing_mode_vars = other.listing_mode_vars;
b82d77b4 307 dump_probe_types = other.dump_probe_types;
abc15290
JS
308
309 prologue_searching = other.prologue_searching;
310
311 buffer_size = other.buffer_size;
312 last_pass = other.last_pass;
313 module_name = other.module_name;
314 stapconf_name = other.stapconf_name;
315 output_file = other.output_file; // XXX how should multiple remotes work?
305fac7d 316 tmpdir_opt_set = false;
abc15290 317 save_module = other.save_module;
5c854d7c 318 modname_given = other.modname_given;
abc15290
JS
319 keep_tmpdir = other.keep_tmpdir;
320 cmd = other.cmd;
321 target_pid = other.target_pid; // XXX almost surely nonsense for multiremote
322 use_cache = other.use_cache;
323 use_script_cache = other.use_script_cache;
324 poison_cache = other.poison_cache;
325 tapset_compile_coverage = other.tapset_compile_coverage;
326 need_uprobes = false;
08badca8 327 need_unwind = false;
8af41ec2 328 need_symbols = false;
abc15290 329 uprobes_path = "";
abc15290
JS
330 load_only = other.load_only;
331 skip_badvars = other.skip_badvars;
42e38653 332 privilege = other.privilege;
73f52eb4 333 privilege_set = other.privilege_set;
abc15290
JS
334 omit_werror = other.omit_werror;
335 compatible = other.compatible;
336 unwindsym_ldd = other.unwindsym_ldd;
337 client_options = other.client_options;
eff14db3 338 server_cache = NULL;
abc15290
JS
339 use_server_on_error = other.use_server_on_error;
340 try_server_status = other.try_server_status;
756cfd49 341 use_remote_prefix = other.use_remote_prefix;
abc15290 342 systemtap_v_check = other.systemtap_v_check;
ea60076d 343 download_dbinfo = other.download_dbinfo;
7baf48e9 344 suppress_handler_errors = other.suppress_handler_errors;
05fb3e0c
WF
345 sysroot = other.sysroot;
346 update_release_sysroot = other.update_release_sysroot;
347 sysenv = other.sysenv;
152fa051 348 suppress_time_limits = other.suppress_time_limits;
a8c9365c 349 color_errors = other.color_errors;
6d3599fc 350 color_mode = other.color_mode;
d5d3a90b 351
abc15290
JS
352 include_path = other.include_path;
353 runtime_path = other.runtime_path;
354
355 // NB: assuming that "other" created these already
356 data_path = other.data_path;
357 cache_path = other.cache_path;
358
359 tapset_compile_coverage = other.tapset_compile_coverage;
360
361
362 // These are fields that were left to their default ctor, but now we want to
363 // copy them from "other". In the same order as declared...
364 script_file = other.script_file;
365 cmdline_script = other.cmdline_script;
08fce398 366 c_macros = other.c_macros;
abc15290
JS
367 args = other.args;
368 kbuildflags = other.kbuildflags;
7003ac0f 369
abc15290 370 globalopts = other.globalopts;
633e5ca7 371 modinfos = other.modinfos;
abc15290 372
372c6458 373 client_options_disallowed_for_unprivileged = other.client_options_disallowed_for_unprivileged;
abc15290
JS
374 server_status_strings = other.server_status_strings;
375 specified_servers = other.specified_servers;
376 server_trust_spec = other.server_trust_spec;
377 server_args = other.server_args;
cd1418c7 378 mok_fingerprints = other.mok_fingerprints;
abc15290
JS
379
380 unwindsym_modules = other.unwindsym_modules;
4e78c716
DB
381 auto_privilege_level_msg = other.auto_privilege_level_msg;
382 auto_server_msgs = other.auto_server_msgs;
b96901b7
CM
383
384 create_tmp_dir();
abc15290
JS
385}
386
b0e5fa85
DB
387systemtap_session::~systemtap_session ()
388{
b96901b7 389 remove_tmp_dir();
ebff2ed0 390 delete_map(subsessions);
08b61232 391 delete pattern_root;
b0e5fa85
DB
392}
393
4441e344
JS
394const string
395systemtap_session::module_filename() const
396{
ac3af990 397 if (runtime_usermode_p())
4441e344
JS
398 return module_name + ".so";
399 return module_name + ".ko";
400}
401
48e74294 402#if HAVE_NSS
b0e5fa85
DB
403void
404systemtap_session::NSPR_init ()
405{
406 if (! NSPR_Initialized)
407 {
408 PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
409 NSPR_Initialized = true;
410 }
3d9dfde6 411}
48e74294 412#endif // HAVE_NSS
e2012a7a 413
ebff2ed0
JS
414systemtap_session*
415systemtap_session::clone(const string& arch, const string& release)
416{
ba0bd1be
JS
417 const string norm_arch = normalize_machine(arch);
418 if (this->architecture == norm_arch && this->kernel_release == release)
ebff2ed0
JS
419 return this;
420
ba0bd1be 421 systemtap_session*& s = subsessions[make_pair(norm_arch, release)];
ebff2ed0 422 if (!s)
ba0bd1be 423 s = new systemtap_session(*this, norm_arch, release);
ebff2ed0
JS
424 return s;
425}
426
e2012a7a
DB
427void
428systemtap_session::version ()
429{
e587f6ca 430 clog << _F("Systemtap translator/driver (version %s/%s, %s)\n"
19ae853d 431 "Copyright (C) 2005-2014 Red Hat, Inc. and others\n"
ce0f6648 432 "This is free software; see the source for copying conditions.",
e587f6ca 433 VERSION, dwfl_version(NULL), STAP_EXTENDED_VERSION) << endl;
79bc39ab 434 clog << _("enabled features:")
1ef0423a
FCE
435#ifdef HAVE_AVAHI
436 << " AVAHI"
437#endif
438#ifdef HAVE_LIBRPM
439 << " LIBRPM"
440#endif
441#ifdef HAVE_LIBSQLITE3
442 << " LIBSQLITE3"
443#endif
444#ifdef HAVE_NSS
445 << " NSS"
446#endif
447#ifdef HAVE_BOOST_SHARED_PTR_HPP
448 << " BOOST_SHARED_PTR"
449#endif
450#ifdef HAVE_TR1_UNORDERED_MAP
451 << " TR1_UNORDERED_MAP"
452#endif
453#ifdef ENABLE_PROLOGUES
454 << " PROLOGUES"
f8e53f3a
FCE
455#endif
456#ifdef ENABLE_NLS
457 << " NLS"
a3524565
JS
458#endif
459#ifdef HAVE_DYNINST
460 << " DYNINST"
d885563b
FCE
461#endif
462#ifdef HAVE_JAVA
463 << " JAVA"
c17539a5
JL
464#endif
465#ifdef HAVE_LIBVIRT
466 << " LIBVIRT"
467#endif
468#ifdef HAVE_LIBXML2
469 << " LIBXML2"
1ef0423a
FCE
470#endif
471 << endl;
e2012a7a
DB
472}
473
0d70f9d8
JS
474void
475systemtap_session::usage (int exitcode)
476{
5ec722e1
JS
477 // For error cases, just suggest --help, so we don't obscure
478 // the actual error message with all the help text.
479 if (exitcode != EXIT_SUCCESS)
480 {
481 clog << _("Try '--help' for more information.") << endl;
482 throw exit_exception(exitcode);
483 }
484
0d70f9d8
JS
485 version ();
486 clog
487 << endl
6073c3fc
LB
488 << _F("Usage: stap [options] FILE Run script in file.\n"
489 " or: stap [options] - Run script on stdin.\n"
490 " or: stap [options] -e SCRIPT Run given script.\n"
491 " or: stap [options] -l PROBE List matching probes.\n"
492 " or: stap [options] -L PROBE List matching probes and local variables.\n\n"
222e16ed 493 "Options (in %s/rc and on command line):\n"
6073c3fc
LB
494 " -- end of translator options, script options follow\n"
495 " -h --help show help\n"
496 " -V --version show version\n"
497 " -p NUM stop after pass NUM 1-5, instead of %d\n"
498 " (parse, elaborate, translate, compile, run)\n"
499 " -v add verbosity to all passes\n"
222e16ed 500 " --vp {N}+ add per-pass verbosity [", data_path.c_str(), last_pass);
0d70f9d8
JS
501 for (unsigned i=0; i<5; i++)
502 clog << (perpass_verbose[i] <= 9 ? perpass_verbose[i] : 9);
503 clog
6073c3fc
LB
504 << "]" << endl;
505 clog << _F(" -k keep temporary directory\n"
506 " -u unoptimized translation %s\n"
507 " -w suppress warnings %s\n"
508 " -W turn warnings into errors %s\n"
509 " -g guru mode %s\n"
510 " -P prologue-searching for function probes %s\n"
511 " -b bulk (percpu file) mode %s\n"
512 " -s NUM buffer size in megabytes, instead of %d\n"
513 " -I DIR look in DIR for additional .stp script files", (unoptimized ? _(" [set]") : ""),
514 (suppress_warnings ? _(" [set]") : ""), (panic_warnings ? _(" [set]") : ""),
515 (guru_mode ? _(" [set]") : ""), (prologue_searching ? _(" [set]") : ""),
516 (bulk_mode ? _(" [set]") : ""), buffer_size);
0d70f9d8
JS
517 if (include_path.size() == 0)
518 clog << endl;
519 else
520 clog << _(", in addition to") << endl;
521 for (unsigned i=0; i<include_path.size(); i++)
ce0f6648 522 clog << " " << include_path[i].c_str() << endl;
0d70f9d8 523 clog
6073c3fc
LB
524 << _F(" -D NM=VAL emit macro definition into generated C code\n"
525 " -B NM=VAL pass option to kbuild make\n"
633e5ca7
FCE
526 " --modinfo NM=VAL\n"
527 " include a MODULE_INFO(NM,VAL) in the generated C code\n"
6073c3fc 528 " -G VAR=VAL set global variable to value\n"
ce0f6648 529 //TRANSLATORS: translating 'runtime' is not advised
6073c3fc
LB
530 " -R DIR look in DIR for runtime, instead of\n"
531 " %s\n"
532 " -r DIR cross-compile to kernel with given build tree; or else\n"
533 " -r RELEASE cross-compile to kernel /lib/modules/RELEASE/build, instead of\n"
534 " %s\n"
535 " -a ARCH cross-compile to given architecture, instead of %s\n"
536 " -m MODULE set probe module name, instead of \n"
537 " %s\n"
538 " -o FILE send script output to file, instead of stdout. This supports\n"
539 " strftime(3) formats for FILE\n"
540 " -c CMD start the probes, run CMD, and exit when it finishes\n"
541 " -x PID sets target() to PID\n"
542 " -F run as on-file flight recorder with -o.\n"
543 " run as on-memory flight recorder without -o.\n"
544 " -S size[,n] set maximum of the size and the number of files.\n"
545 " -d OBJECT add unwind/symbol data for OBJECT file", runtime_path.c_str(), kernel_build_tree.c_str(), architecture.c_str(), module_name.c_str());
0d70f9d8
JS
546 if (unwindsym_modules.size() == 0)
547 clog << endl;
548 else
549 clog << _(", in addition to") << endl;
e2012a7a 550 {
0d70f9d8
JS
551 vector<string> syms (unwindsym_modules.begin(), unwindsym_modules.end());
552 for (unsigned i=0; i<syms.size(); i++)
ce0f6648 553 clog << " " << syms[i].c_str() << endl;
0d70f9d8
JS
554 }
555 clog
6073c3fc
LB
556 << _F(" --ldd add unwind/symbol data for all referenced object files.\n"
557 " --all-modules\n"
558 " add unwind/symbol data for all loaded kernel objects.\n"
559 " -t collect probe timing information\n"
0d70f9d8 560#ifdef HAVE_LIBSQLITE3
6073c3fc 561 " -q generate information on tapset coverage\n"
0d70f9d8 562#endif /* HAVE_LIBSQLITE3 */
4441e344
JS
563 " --runtime=MODE\n"
564 " set the pass-5 runtime mode, instead of kernel\n"
45402f2a
JS
565#ifdef HAVE_DYNINST
566 " --dyninst\n"
567 " shorthand for --runtime=dyninst\n"
568#endif /* HAVE_DYNINST */
f66bb29a
DB
569 " --privilege=PRIVILEGE_LEVEL\n"
570 " check the script for constructs not allowed at the given privilege level\n"
6073c3fc 571 " --unprivileged\n"
42e38653 572 " equivalent to --privilege=stapusr\n"
6073c3fc
LB
573 " --compatible=VERSION\n"
574 " suppress incompatible language/tapset changes beyond VERSION,\n"
575 " instead of %s\n"
576 " --check-version\n"
577 " displays warnings where a syntax element may be \n"
578 " version dependent\n"
579 " --skip-badvars\n"
580 " substitute zero for bad context $variables\n"
7baf48e9
FCE
581 " --suppress-handler-errors\n"
582 " catch all runtime errors, quietly skip probe handlers\n"
6073c3fc
LB
583 " --use-server[=SERVER-SPEC]\n"
584 " specify systemtap compile-servers\n"
585 " --list-servers[=PROPERTIES]\n"
4830b335
FCE
586 " report on the status of the specified compile-servers:\n"
587 " all,specified,online,trusted,signer,compatible\n"
0d70f9d8 588#if HAVE_NSS
6073c3fc 589 " --trust-servers[=TRUST-SPEC]\n"
4830b335
FCE
590 " add/revoke trust of specified compile-servers:\n"
591 " ssl,signer,all-users,revoke,no-prompt\n"
6073c3fc
LB
592 " --use-server-on-error[=yes/no]\n"
593 " retry compilation using a compile server upon compilation error\n"
0d70f9d8 594#endif
6073c3fc
LB
595 " --remote=HOSTNAME\n"
596 " run pass 5 on the specified ssh host.\n"
756cfd49
JS
597 " may be repeated for targeting multiple hosts.\n"
598 " --remote-prefix\n"
715c8369 599 " prefix each line of remote output with a host index.\n"
305fac7d 600 " --tmpdir=NAME\n"
d1242dfa 601 " specify name of temporary directory to be used.\n"
ea60076d 602 " --download-debuginfo[=OPTION]\n"
d1242dfa 603 " automatically download debuginfo using ABRT.\n"
ea60076d 604 " yes,no,ask,<timeout value>\n"
b82d77b4
DB
605 " --dump-probe-types\n"
606 " show a list of available probe types.\n"
05fb3e0c
WF
607 " --sysroot=DIR\n"
608 " specify sysroot directory where target files (executables,\n" " libraries, etc.) are located.\n"
609 " --sysenv=VAR=VALUE\n"
610 " provide an alternate value for an environment variable\n"
611 " where the value on a remote system differs. Path\n"
612 " variables (e.g. PATH, LD_LIBRARY_PATH) are assumed to be\n"
613 " relative to the sysroot.\n"
152fa051
LB
614 " --suppress-time-limits\n"
615 " disable -DSTP_NO_OVERLOAD -DMAXACTION and -DMAXTRYACTION limits\n"
756cfd49 616 , compatible.c_str()) << endl
0d70f9d8 617 ;
e2012a7a
DB
618
619 time_t now;
620 time (& now);
621 struct tm* t = localtime (& now);
622 if (t && t->tm_mon*3 + t->tm_mday*173 == 0xb6)
623 clog << morehelp << endl;
624
e2d0f787 625 throw exit_exception (exitcode);
e2012a7a
DB
626}
627
628int
629systemtap_session::parse_cmdline (int argc, char * const argv [])
630{
372c6458 631 client_options_disallowed_for_unprivileged = "";
878b2f3f 632 struct rlimit our_rlimit;
e2012a7a
DB
633 while (true)
634 {
e2012a7a 635 char * num_endptr;
73f52eb4 636 int grc = getopt_long (argc, argv, STAP_SHORT_OPTIONS, stap_long_options, NULL);
e2012a7a
DB
637
638 // NB: when adding new options, consider very carefully whether they
17874af3 639 // should be restricted from stap clients (after --client-options)!
e2012a7a
DB
640
641 if (grc < 0)
642 break;
643 switch (grc)
644 {
645 case 'V':
646 version ();
e2d0f787 647 throw exit_exception (EXIT_SUCCESS);
e2012a7a
DB
648
649 case 'v':
372c6458 650 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
651 for (unsigned i=0; i<5; i++)
652 perpass_verbose[i] ++;
2dce8c42 653 verbose ++;
e2012a7a
DB
654 break;
655
2b7d9d84
RH
656 case 'G':
657 // Make sure the global option is only composed of the
658 // following chars: [_=a-zA-Z0-9]
7a583298 659 assert_regexp_match("-G parameter", optarg, "^[a-z_][a-z0-9_]*=[a-z0-9_-]+$");
2b7d9d84 660 globalopts.push_back (string(optarg));
bb25d08f
RH
661 break;
662
e2012a7a 663 case 't':
372c6458 664 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
665 timing = true;
666 break;
667
668 case 'w':
372c6458 669 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
670 suppress_warnings = true;
671 break;
672
673 case 'W':
372c6458 674 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
675 panic_warnings = true;
676 break;
677
678 case 'p':
679 last_pass = (int)strtoul(optarg, &num_endptr, 10);
680 if (*num_endptr != '\0' || last_pass < 1 || last_pass > 5)
681 {
79bc39ab 682 cerr << _("Invalid pass number (should be 1-5).") << endl;
e2012a7a
DB
683 return 1;
684 }
685 if (listing_mode && last_pass != 2)
686 {
79bc39ab 687 cerr << _("Listing (-l) mode implies pass 2.") << endl;
e2012a7a
DB
688 return 1;
689 }
372c6458 690 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
691 break;
692
693 case 'I':
694 if (client_options)
372c6458 695 client_options_disallowed_for_unprivileged += client_options_disallowed_for_unprivileged.empty () ? "-I" : ", -I";
2fad97fd
DB
696 if (include_arg_start == -1)
697 include_arg_start = include_path.size ();
e2012a7a
DB
698 include_path.push_back (string (optarg));
699 break;
700
701 case 'd':
372c6458 702 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a 703 {
87ca81e2
MW
704 // Make sure an empty data object wasn't specified (-d "")
705 if (strlen (optarg) == 0)
706 {
707 cerr << _("Data object (-d) cannot be empty.") << endl;
708 return 1;
709 }
e2012a7a 710 // At runtime user module names are resolved through their
5bca76a8
JS
711 // canonical (absolute) path, or else it's a kernel module name.
712 unwindsym_modules.insert (resolve_path (optarg));
7f085e3f
JS
713 // NB: we used to enable_vma_tracker() here for PR10228, but now
714 // we'll leave that to pragma:vma functions which actually use it.
e2012a7a
DB
715 break;
716 }
717
718 case 'e':
719 if (have_script)
720 {
79bc39ab 721 cerr << _("Only one script can be given on the command line.")
e2012a7a
DB
722 << endl;
723 return 1;
724 }
372c6458 725 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
726 cmdline_script = string (optarg);
727 have_script = true;
728 break;
729
730 case 'o':
731 // NB: client_options not a problem, since pass 1-4 does not use output_file.
372c6458 732 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
733 output_file = string (optarg);
734 break;
735
736 case 'R':
ce0f6648 737 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-R", "--client-options") << endl; return 1; }
2fad97fd 738 runtime_specified = true;
e2012a7a
DB
739 runtime_path = string (optarg);
740 break;
741
742 case 'm':
743 if (client_options)
372c6458 744 client_options_disallowed_for_unprivileged += client_options_disallowed_for_unprivileged.empty () ? "-m" : ", -m";
e2012a7a
DB
745 module_name = string (optarg);
746 save_module = true;
5c854d7c 747 modname_given = true;
e2012a7a
DB
748 {
749 // If the module name ends with '.ko', chop it off since
750 // modutils doesn't like modules named 'foo.ko.ko'.
4441e344 751 if (endswith(module_name, ".ko") || endswith(module_name, ".so"))
e2012a7a
DB
752 {
753 module_name.erase(module_name.size() - 3);
46a1a151 754 cerr << _F("Truncating module name to '%s'", module_name.c_str()) << endl;
e2012a7a
DB
755 }
756
757 // Make sure an empty module name wasn't specified (-m "")
758 if (module_name.empty())
759 {
79bc39ab 760 cerr << _("Module name cannot be empty.") << endl;
e2012a7a
DB
761 return 1;
762 }
763
764 // Make sure the module name is only composed of the
2b7d9d84
RH
765 // following chars: [a-z0-9_]
766 assert_regexp_match("-m parameter", module_name, "^[a-z0-9_]+$");
e2012a7a
DB
767
768 // Make sure module name isn't too long.
769 if (module_name.size() >= (MODULE_NAME_LEN - 1))
770 {
771 module_name.resize(MODULE_NAME_LEN - 1);
46a1a151 772 cerr << _F("Truncating module name to '%s'", module_name.c_str()) << endl;
e2012a7a
DB
773 }
774 }
775
372c6458 776 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
777 use_script_cache = false;
778 break;
779
780 case 'r':
781 if (client_options) // NB: no paths!
782 assert_regexp_match("-r parameter from client", optarg, "^[a-z0-9_.-]+$");
372c6458 783 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
784 setup_kernel_release(optarg);
785 break;
786
787 case 'a':
788 assert_regexp_match("-a parameter", optarg, "^[a-z0-9_-]+$");
372c6458 789 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
790 architecture = string(optarg);
791 break;
792
793 case 'k':
71a522b5 794 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-k", "--client-options") << endl; return 1; }
e2012a7a
DB
795 keep_tmpdir = true;
796 use_script_cache = false; /* User wants to keep a usable build tree. */
797 break;
798
799 case 'g':
372c6458 800 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
801 guru_mode = true;
802 break;
803
804 case 'P':
372c6458 805 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
806 prologue_searching = true;
807 break;
808
809 case 'b':
372c6458 810 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
811 bulk_mode = true;
812 break;
813
814 case 'u':
372c6458 815 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
816 unoptimized = true;
817 break;
818
819 case 's':
820 buffer_size = (int) strtoul (optarg, &num_endptr, 10);
821 if (*num_endptr != '\0' || buffer_size < 1 || buffer_size > 4095)
822 {
79bc39ab 823 cerr << _("Invalid buffer size (should be 1-4095).") << endl;
e2012a7a
DB
824 return 1;
825 }
372c6458 826 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
827 break;
828
829 case 'c':
830 cmd = string (optarg);
2d363b75
FCE
831 if (cmd == "")
832 {
833 // This would mess with later code deciding to pass -c
834 // through to staprun
79bc39ab 835 cerr << _("Empty CMD string invalid.") << endl;
2d363b75
FCE
836 return 1;
837 }
372c6458 838 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
839 break;
840
841 case 'x':
842 target_pid = (int) strtoul(optarg, &num_endptr, 10);
843 if (*num_endptr != '\0')
844 {
79bc39ab 845 cerr << _("Invalid target process ID number.") << endl;
e2012a7a
DB
846 return 1;
847 }
372c6458 848 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
849 break;
850
851 case 'D':
852 assert_regexp_match ("-D parameter", optarg, "^[a-z_][a-z_0-9]*(=-?[a-z_0-9]+)?$");
853 if (client_options)
372c6458
DB
854 client_options_disallowed_for_unprivileged += client_options_disallowed_for_unprivileged.empty () ? "-D" : ", -D";
855 server_args.push_back (string ("-") + (char)grc + optarg);
08fce398 856 c_macros.push_back (string (optarg));
e2012a7a
DB
857 break;
858
859 case 'S':
860 assert_regexp_match ("-S parameter", optarg, "^[0-9]+(,[0-9]+)?$");
372c6458 861 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
862 size_option = string (optarg);
863 break;
864
865 case 'q':
ce0f6648 866 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-q", "--client-options") << endl; return 1; }
372c6458 867 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
868 tapset_compile_coverage = true;
869 break;
870
871 case 'h':
872 usage (0);
873 break;
874
875 case 'L':
876 listing_mode_vars = true;
877 unoptimized = true; // This causes retention of variables for listing_mode
68ac5d0e 878 // fallthrough
e2012a7a
DB
879 case 'l':
880 suppress_warnings = true;
881 listing_mode = true;
882 last_pass = 2;
883 if (have_script)
884 {
79bc39ab 885 cerr << _("Only one script can be given on the command line.")
e2012a7a
DB
886 << endl;
887 return 1;
888 }
372c6458 889 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
890 cmdline_script = string("probe ") + string(optarg) + " {}";
891 have_script = true;
892 break;
893
894 case 'F':
372c6458 895 server_args.push_back (string ("-") + (char)grc);
e2012a7a
DB
896 load_only = true;
897 break;
898
899 case 'B':
ce0f6648 900 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-B", "--client-options") << endl; return 1; }
372c6458 901 server_args.push_back (string ("-") + (char)grc + optarg);
e2012a7a
DB
902 kbuildflags.push_back (string (optarg));
903 break;
904
372c6458
DB
905 case LONG_OPT_VERSION:
906 version ();
e2d0f787 907 throw exit_exception (EXIT_SUCCESS);
372c6458 908
372c6458
DB
909 case LONG_OPT_VERBOSE_PASS:
910 {
911 bool ok = true;
912 if (strlen(optarg) < 1 || strlen(optarg) > 5)
913 ok = false;
914 if (ok)
bf840782
JS
915 {
916 for (unsigned i=0; i<strlen(optarg); i++)
917 if (isdigit (optarg[i]))
918 perpass_verbose[i] += optarg[i]-'0';
919 else
920 ok = false;
921 }
372c6458 922 if (! ok)
73f52eb4 923 {
372c6458
DB
924 cerr << _("Invalid --vp argument: it takes 1 to 5 digits.") << endl;
925 return 1;
73f52eb4 926 }
372c6458
DB
927 // NB: we don't do this: last_pass = strlen(optarg);
928 server_args.push_back ("--vp=" + string(optarg));
929 break;
930 }
931
932 case LONG_OPT_SKIP_BADVARS:
933 server_args.push_back ("--skip-badvars");
934 skip_badvars = true;
935 break;
936
937 case LONG_OPT_PRIVILEGE:
938 {
939 // We allow only multiple privilege-setting options if they all specify the same
940 // privilege level. The server also expects and depends on this behaviour when
941 // examining the client-side options passed to it.
942 privilege_t newPrivilege;
943 if (strcmp (optarg, "stapdev") == 0)
944 newPrivilege = pr_stapdev;
945 else if (strcmp (optarg, "stapsys") == 0)
946 newPrivilege = pr_stapsys;
947 else if (strcmp (optarg, "stapusr") == 0)
948 newPrivilege = pr_stapusr;
949 else
950 {
951 cerr << _F("Invalid argument '%s' for --privilege.", optarg) << endl;
952 return 1;
953 }
954 if (privilege_set && newPrivilege != privilege)
955 {
956 cerr << _("Privilege level may be set only once.") << endl;
957 return 1;
958 }
959 privilege = newPrivilege;
960 privilege_set = true;
961 server_args.push_back ("--privilege=" + string(optarg));
962 }
963 /* NB: for server security, it is essential that once this flag is
964 set, no future flag be able to unset it. */
965 break;
966
967 case LONG_OPT_UNPRIVILEGED:
968 // We allow only multiple privilege-setting options if they all specify the same
969 // privilege level. The server also expects and depends on this behaviour when
970 // examining the client-side options passed to it.
971 if (privilege_set && pr_unprivileged != privilege)
972 {
973 cerr << _("Privilege level may be set only once.") << endl;
974 return 1;
975 }
976 privilege = pr_unprivileged;
977 privilege_set = true;
978 server_args.push_back ("--unprivileged");
979 /* NB: for server security, it is essential that once this flag is
980 set, no future flag be able to unset it. */
981 break;
982
983 case LONG_OPT_OMIT_WERROR:
984 server_args.push_back (OMIT_WERROR_NAME);
985 omit_werror = true;
986 break;
987
988 case LONG_OPT_CLIENT_OPTIONS:
989 client_options = true;
990 break;
991
992 case LONG_OPT_TMPDIR:
993 if (client_options) {
994 cerr << _F("ERROR: %s is invalid with %s", "--tmpdir", "--client-options") << endl;
995 return 1;
996 }
997 tmpdir_opt_set = true;
998 tmpdir = optarg;
999 break;
1000
1001 case LONG_OPT_DOWNLOAD_DEBUGINFO:
1002 if(optarg)
1003 {
1004 if(strcmp(optarg, "no") == 0)
1005 download_dbinfo = 0; //Disable feature
1006 else if (strcmp(optarg, "yes") == 0)
1007 download_dbinfo = INT_MAX; //Enable, No Timeout
1008 /* NOTE: Timeout and Asking for Confirmation features below are not supported yet by abrt
1009 * in version abrt-2.0.3-1.fc15.x86_64, Bugzilla: BZ730107 (timeout), BZ726192 ('-y') */
1010 else if(atoi(optarg) > 0)
1011 download_dbinfo = atoi(optarg); //Enable, Set timeout to optarg
1012 else if (strcmp(optarg, "ask") == 0)
1013 download_dbinfo = -1; //Enable, Ask for confirmation
2dce8c42 1014 else
44edbcd6 1015 {
372c6458
DB
1016 cerr << _F("ERROR: %s is not a valid value. Use 'yes', 'no', 'ask' or a timeout value.", optarg) << endl;
1017 return 1;
44edbcd6 1018 }
372c6458
DB
1019 }
1020 else
1021 download_dbinfo = INT_MAX; //Enable, No Timeout
1022 break;
1023
1024 case LONG_OPT_USE_SERVER:
1025 if (client_options) {
1026 cerr << _F("ERROR: %s is invalid with %s", "--use-server", "--client-options") << endl;
1027 return 1;
1028 }
1029 if (optarg)
1030 specified_servers.push_back (optarg);
1031 else
1032 specified_servers.push_back ("");
1033 break;
1034
1035 case LONG_OPT_USE_SERVER_ON_ERROR:
1036 if (client_options) {
1037 cerr << _F("ERROR: %s is invalid with %s", "--use-server-on-error", "--client-options") << endl;
1038 return 1;
1039 }
1040 if (optarg)
1041 {
1042 string arg = optarg;
1043 for (unsigned i = 0; i < arg.size (); ++i)
1044 arg[i] = tolower (arg[i]);
1045 if (arg == "yes" || arg == "ye" || arg == "y")
44edbcd6 1046 use_server_on_error = true;
372c6458
DB
1047 else if (arg == "no" || arg == "n")
1048 use_server_on_error = false;
2dce8c42 1049 else
372c6458
DB
1050 cerr << _F("Invalid argument '%s' for --use-server-on-error.", optarg) << endl;
1051 }
1052 else
1053 use_server_on_error = true;
1054 break;
1055
1056 case LONG_OPT_LIST_SERVERS:
1057 if (client_options) {
1058 cerr << _F("ERROR: %s is invalid with %s", "--list-servers", "--client-options") << endl;
1059 return 1;
1060 }
1061 if (optarg)
1062 server_status_strings.push_back (optarg);
1063 else
1064 server_status_strings.push_back ("");
1065 break;
1066
1067 case LONG_OPT_TRUST_SERVERS:
1068 if (client_options) {
1069 cerr << _F("ERROR: %s is invalid with %s", "--trust-servers", "--client-options") << endl;
1070 return 1;
1071 }
1072 if (optarg)
1073 server_trust_spec = optarg;
1074 else
1075 server_trust_spec = "ssl";
1076 break;
1077
1078 case LONG_OPT_HELP:
1079 usage (0);
1080 break;
1081
1082 // The caching options should not be available to server clients
1083 case LONG_OPT_DISABLE_CACHE:
1084 if (client_options) {
1085 cerr << _F("ERROR: %s is invalid with %s", "--disable-cache", "--client-options") << endl;
1086 return 1;
1087 }
1088 use_cache = use_script_cache = false;
1089 break;
1090
1091 case LONG_OPT_POISON_CACHE:
1092 if (client_options) {
1093 cerr << _F("ERROR: %s is invalid with %s", "--poison-cache", "--client-options") << endl;
1094 return 1;
1095 }
1096 poison_cache = true;
1097 break;
1098
1099 case LONG_OPT_CLEAN_CACHE:
1100 if (client_options) {
1101 cerr << _F("ERROR: %s is invalid with %s", "--clean-cache", "--client-options") << endl;
1102 return 1;
1103 }
1104 clean_cache(*this);
e2d0f787 1105 throw exit_exception(EXIT_SUCCESS);
372c6458
DB
1106
1107 case LONG_OPT_COMPATIBLE:
1108 server_args.push_back ("--compatible=" + string(optarg));
7324e0d9
FCE
1109 if (strverscmp(optarg, VERSION) > 0) {
1110 cerr << _F("ERROR: systemtap version %s cannot be compatible with future version %s", VERSION, optarg)
1111 << endl;
1112 return 1;
1113 }
372c6458
DB
1114 compatible = optarg;
1115 break;
1116
1117 case LONG_OPT_LDD:
1118 if (client_options) {
1119 cerr << _F("ERROR: %s is invalid with %s", "--ldd", "--client-options") << endl;
1120 return 1;
1121 }
1122 unwindsym_ldd = true;
1123 break;
1124
1125 case LONG_OPT_ALL_MODULES:
1126 if (client_options) {
1127 cerr << _F("ERROR: %s is invalid with %s", "--all-modules", "--client-options") << endl;
1128 return 1;
1129 }
1130 insert_loaded_modules();
1131 break;
1132
1133 case LONG_OPT_REMOTE:
1134 if (client_options) {
1135 cerr << _F("ERROR: %s is invalid with %s", "--remote", "--client-options") << endl;
1136 return 1;
1137 }
1138
1139 remote_uris.push_back(optarg);
1140 break;
1141
1142 case LONG_OPT_REMOTE_PREFIX:
1143 if (client_options) {
1144 cerr << _F("ERROR: %s is invalid with %s", "--remote-prefix", "--client-options") << endl;
1145 return 1;
1146 }
1147
1148 use_remote_prefix = true;
1149 break;
1150
1151 case LONG_OPT_CHECK_VERSION:
1152 server_args.push_back ("--check-version");
1153 systemtap_v_check = true;
1154 break;
1155
1156 case LONG_OPT_DUMP_PROBE_TYPES:
1157 server_args.push_back ("--dump-probe-types");
1158 dump_probe_types = true;
1159 break;
1160
1161 case LONG_OPT_SUPPRESS_HANDLER_ERRORS:
1162 suppress_handler_errors = true;
7acb3e34 1163 c_macros.push_back (string ("STAP_SUPPRESS_HANDLER_ERRORS"));
372c6458
DB
1164 break;
1165
1166 case LONG_OPT_MODINFO:
1167 // Make sure the global option is only composed of the
1168 // following chars: [_=a-zA-Z0-9]
1169 if (client_options) {
1170 cerr << _F("ERROR: %s is invalid with %s", "--modinfo", "--client-options") << endl;
1171 return 1;
1172 }
1173 assert_regexp_match("--modinfo parameter", optarg, "^[a-z_][a-z0-9_]*=.+$");
1174 modinfos.push_back (string(optarg));
1175 break;
e2012a7a 1176
ea7e1c17
DB
1177 case LONG_OPT_RLIMIT_AS:
1178 if(getrlimit(RLIMIT_AS, & our_rlimit))
1179 cerr << _F("Unable to obtain resource limits for rlimit_as : %s", strerror (errno)) << endl;
6ae64991 1180 our_rlimit.rlim_max = our_rlimit.rlim_cur = strtoul (optarg, &num_endptr, 0);
ea7e1c17
DB
1181 if(*num_endptr || setrlimit (RLIMIT_AS, & our_rlimit))
1182 cerr << _F("Unable to set resource limits for rlimit_as : %s", strerror (errno)) << endl;
ca369a09
FCE
1183 /* Disable core dumps, since exhaustion results in uncaught bad_alloc etc. exceptions */
1184 our_rlimit.rlim_max = our_rlimit.rlim_cur = 0;
1185 (void) setrlimit (RLIMIT_CORE, & our_rlimit);
ea7e1c17
DB
1186 break;
1187
1188 case LONG_OPT_RLIMIT_CPU:
1189 if(getrlimit(RLIMIT_CPU, & our_rlimit))
1190 cerr << _F("Unable to obtain resource limits for rlimit_cpu : %s", strerror (errno)) << endl;
6ae64991 1191 our_rlimit.rlim_max = our_rlimit.rlim_cur = strtoul (optarg, &num_endptr, 0);
ea7e1c17
DB
1192 if(*num_endptr || setrlimit (RLIMIT_CPU, & our_rlimit))
1193 cerr << _F("Unable to set resource limits for rlimit_cpu : %s", strerror (errno)) << endl;
1194 break;
1195
1196 case LONG_OPT_RLIMIT_NPROC:
1197 if(getrlimit(RLIMIT_NPROC, & our_rlimit))
1198 cerr << _F("Unable to obtain resource limits for rlimit_nproc : %s", strerror (errno)) << endl;
6ae64991 1199 our_rlimit.rlim_max = our_rlimit.rlim_cur = strtoul (optarg, &num_endptr, 0);
ea7e1c17
DB
1200 if(*num_endptr || setrlimit (RLIMIT_NPROC, & our_rlimit))
1201 cerr << _F("Unable to set resource limits for rlimit_nproc : %s", strerror (errno)) << endl;
1202 break;
1203
1204 case LONG_OPT_RLIMIT_STACK:
1205 if(getrlimit(RLIMIT_STACK, & our_rlimit))
1206 cerr << _F("Unable to obtain resource limits for rlimit_stack : %s", strerror (errno)) << endl;
6ae64991 1207 our_rlimit.rlim_max = our_rlimit.rlim_cur = strtoul (optarg, &num_endptr, 0);
ea7e1c17
DB
1208 if(*num_endptr || setrlimit (RLIMIT_STACK, & our_rlimit))
1209 cerr << _F("Unable to set resource limits for rlimit_stack : %s", strerror (errno)) << endl;
ca369a09
FCE
1210 /* Disable core dumps, since exhaustion results in SIGSEGV */
1211 our_rlimit.rlim_max = our_rlimit.rlim_cur = 0;
1212 (void) setrlimit (RLIMIT_CORE, & our_rlimit);
ea7e1c17
DB
1213 break;
1214
1215 case LONG_OPT_RLIMIT_FSIZE:
1216 if(getrlimit(RLIMIT_FSIZE, & our_rlimit))
1217 cerr << _F("Unable to obtain resource limits for rlimit_fsize : %s", strerror (errno)) << endl;
6ae64991 1218 our_rlimit.rlim_max = our_rlimit.rlim_cur = strtoul (optarg, &num_endptr, 0);
ea7e1c17
DB
1219 if(*num_endptr || setrlimit (RLIMIT_FSIZE, & our_rlimit))
1220 cerr << _F("Unable to set resource limits for rlimit_fsize : %s", strerror (errno)) << endl;
1221 break;
e2012a7a 1222
4bf09a21
JS
1223 case LONG_OPT_SYSROOT:
1224 if (client_options) {
1225 cerr << _F("ERROR: %s invalid with %s", "--sysroot", "--client-options") << endl;
1226 return 1;
1227 } else if (!sysroot.empty()) {
1228 cerr << "ERROR: multiple --sysroot options not supported" << endl;
1229 return 1;
1230 } else {
5bca76a8 1231 char *spath = canonicalize_file_name (optarg);
4bf09a21
JS
1232 if (spath == NULL) {
1233 cerr << _F("ERROR: %s is an invalid directory for --sysroot", optarg) << endl;
1234 return 1;
1235 }
1236
1237 sysroot = string(spath);
5bca76a8 1238 free (spath);
4bf09a21
JS
1239 if (sysroot[sysroot.size() - 1] != '/')
1240 sysroot.append("/");
b82d77b4 1241
7baf48e9 1242 break;
4bf09a21 1243 }
7baf48e9 1244
4bf09a21
JS
1245 case LONG_OPT_SYSENV:
1246 if (client_options) {
1247 cerr << _F("ERROR: %s invalid with %s", "--sysenv", "--client-options") << endl;
1248 return 1;
1249 } else {
1250 string sysenv_str = optarg;
1251 string value;
1252 size_t pos;
1253 if (sysroot.empty()) {
1254 cerr << "ERROR: --sysenv must follow --sysroot" << endl;
1255 return 1;
1256 }
1257
1258 pos = sysenv_str.find("=");
1259 if (pos == string::npos) {
1260 cerr << _F("ERROR: %s is an invalid argument for --sysenv", optarg) << endl;
1261 return 1;
1262 }
1263
1264 value = sysenv_str.substr(pos + 1);
1265 sysenv[sysenv_str.substr(0, pos)] = value;
1266
1267 break;
1268 }
e2012a7a 1269
152fa051
LB
1270 case LONG_OPT_SUPPRESS_TIME_LIMITS: //require guru_mode to use
1271 if (guru_mode == false)
1272 {
1273 cerr << _F("ERROR %s requires guru mode (-g)", "--suppress-time-limits") << endl;
1274 return 1;
1275 }
1276 else
1277 {
1278 suppress_time_limits = true;
1279 server_args.push_back (string ("--suppress-time-limits"));
1280 c_macros.push_back (string ("STAP_SUPPRESS_TIME_LIMITS_ENABLE"));
1281 break;
1282 }
1283
4441e344 1284 case LONG_OPT_RUNTIME:
45402f2a
JS
1285 if (!parse_cmdline_runtime (optarg))
1286 return 1;
1287 break;
4441e344 1288
45402f2a
JS
1289 case LONG_OPT_RUNTIME_DYNINST:
1290 if (!parse_cmdline_runtime ("dyninst"))
1291 return 1;
4441e344
JS
1292 break;
1293
a3253b49
JS
1294 case LONG_OPT_BENCHMARK_SDT:
1295 // XXX This option is secret, not supported, subject to change at our whim
1296 benchmark_sdt_threads = sysconf(_SC_NPROCESSORS_ONLN);
1297 break;
1298
3d0a328d 1299 case LONG_OPT_BENCHMARK_SDT_LOOPS:
6c116ee4 1300 assert(optarg != 0); // optarg can't be NULL (or getopt would choke)
3d0a328d
JS
1301 // XXX This option is secret, not supported, subject to change at our whim
1302 benchmark_sdt_loops = strtoul(optarg, NULL, 10);
1303 break;
1304
1305 case LONG_OPT_BENCHMARK_SDT_THREADS:
6c116ee4 1306 assert(optarg != 0); // optarg can't be NULL (or getopt would choke)
3d0a328d
JS
1307 // XXX This option is secret, not supported, subject to change at our whim
1308 benchmark_sdt_threads = strtoul(optarg, NULL, 10);
1309 break;
1310
a8c9365c 1311 case LONG_OPT_COLOR_ERRS:
b8f96d36
JL
1312 // --color without arg is equivalent to always
1313 if (!optarg || !strcmp(optarg, "always"))
6d3599fc 1314 color_mode = color_always;
b8f96d36
JL
1315 else if (!strcmp(optarg, "auto"))
1316 color_mode = color_auto;
1317 else if (!strcmp(optarg, "never"))
6d3599fc
JL
1318 color_mode = color_never;
1319 else {
a8c9365c
JL
1320 cerr << _F("Invalid argument '%s' for --color.", optarg) << endl;
1321 return 1;
1322 }
6d3599fc 1323 color_errors = color_mode == color_always
b8f96d36
JL
1324 || (color_mode == color_auto && isatty(STDERR_FILENO) &&
1325 strcmp(getenv("TERM") ?: "notdumb", "dumb"));
a8c9365c
JL
1326 break;
1327
36222574
MW
1328 case '?':
1329 // Invalid/unrecognized option given or argument required, but
1330 // not given. In both cases getopt_long() will have printed the
1331 // appropriate error message to stderr already.
5ec722e1 1332 usage(1);
36222574
MW
1333 break;
1334
e2012a7a 1335 default:
372c6458 1336 // NOTREACHED unless one added a getopt option but not a corresponding case:
46a1a151 1337 cerr << _F("Unhandled argument code %d", (char)grc) << endl;
e2012a7a
DB
1338 return 1;
1339 break;
1340 }
1341 }
1342
1343 return 0;
1344}
1345
45402f2a
JS
1346bool
1347systemtap_session::parse_cmdline_runtime (const string& opt_runtime)
1348{
1349 if (opt_runtime == string("kernel"))
1350 runtime_mode = kernel_runtime;
1351 else if (opt_runtime == string("dyninst"))
1352 {
1353#ifndef HAVE_DYNINST
1354 cerr << _("ERROR: --runtime=dyninst unavailable; this build lacks DYNINST feature") << endl;
1355 version();
1356 return false;
1357#endif
1358 if (privilege_set && pr_unprivileged != privilege)
1359 {
1360 cerr << _("ERROR: --runtime=dyninst implies unprivileged mode only") << endl;
1361 return false;
1362 }
1363 privilege = pr_unprivileged;
1364 privilege_set = true;
1365 runtime_mode = dyninst_runtime;
1366 }
1367 else
1368 {
1369 cerr << _F("ERROR: %s is an invalid argument for --runtime", opt_runtime.c_str()) << endl;
1370 return false;
1371 }
1372
1373 return true;
1374}
1375
e2012a7a
DB
1376void
1377systemtap_session::check_options (int argc, char * const argv [])
1378{
a83cc46b
DB
1379 for (int i = optind; i < argc; i++)
1380 {
1381 if (! have_script)
1382 {
1383 script_file = string (argv[i]);
1384 have_script = true;
1385 }
1386 else
1387 args.push_back (string (argv[i]));
1388 }
1389
3d0a328d
JS
1390 // We don't need a script with --list-servers, --trust-servers, or --dump-probe-types.
1391 bool need_script = server_status_strings.empty () && server_trust_spec.empty () && ! dump_probe_types;
1392
1393 if (benchmark_sdt_loops > 0 || benchmark_sdt_threads > 0)
a83cc46b 1394 {
3d0a328d
JS
1395 // Secret benchmarking options are for local use only, not servers or --remote
1396 if (client_options || !remote_uris.empty())
a83cc46b 1397 {
3d0a328d 1398 cerr << _("Benchmark options are only for local use.") << endl;
a83cc46b
DB
1399 usage(1);
1400 }
3d0a328d
JS
1401
1402 // Fill defaults if either is unset.
1403 if (benchmark_sdt_loops == 0)
1404 benchmark_sdt_loops = 10000000;
1405 if (benchmark_sdt_threads == 0)
1406 benchmark_sdt_threads = 1;
1407
1408 need_script = false;
1409 }
1410
1411 // need a user file
1412 // NB: this is also triggered if stap is invoked with no arguments at all
1413 if (need_script && ! have_script)
1414 {
1415 cerr << _("A script must be specified.") << endl;
1416 usage(1);
a83cc46b
DB
1417 }
1418
2dce8c42
DB
1419#if ! HAVE_NSS
1420 if (client_options)
2713ea24 1421 print_warning("--client-options is not supported by this version of systemtap");
2dce8c42 1422
c4fd15b4
DB
1423 if (! server_status_strings.empty ())
1424 {
1425 print_warning("--list-servers is not supported by this version of systemtap");
1426 server_status_strings.clear ();
1427 }
1428
c77af0d0
DB
1429 if (! server_trust_spec.empty ())
1430 {
2713ea24 1431 print_warning("--trust-servers is not supported by this version of systemtap");
c77af0d0
DB
1432 server_trust_spec.clear ();
1433 }
1434#endif
2dce8c42 1435
2fad97fd
DB
1436 if (runtime_specified && ! specified_servers.empty ())
1437 {
2713ea24 1438 print_warning("Ignoring --use-server due to the use of -R");
2fad97fd
DB
1439 specified_servers.clear ();
1440 }
1441
e2012a7a
DB
1442 if (client_options && last_pass > 4)
1443 {
1444 last_pass = 4; /* Quietly downgrade. Server passed through -p5 naively. */
1445 }
f6be7c06
DB
1446
1447 // If phase 5 has been requested, automatically adjust the --privilege setting to match the
1448 // user's actual privilege level and add --use-server, if necessary.
73f52eb4 1449 // Do this only if we have a script and we are not the server.
b30aefff 1450 // Also do this only if we're running in the kernel (e.g. not --runtime=dyninst)
dbf065b9 1451 // XXX Eventually we could check remote hosts, but disable that case for now.
b30aefff
JS
1452 if (last_pass > 4 && have_script && ! client_options &&
1453 runtime_mode == kernel_runtime && remote_uris.empty())
a83cc46b 1454 {
f6be7c06
DB
1455 // What is the user's privilege level?
1456 privilege_t credentials = get_privilege_credentials ();
73f52eb4
DB
1457 // Don't alter specifically-requested privilege levels
1458 if (! privilege_set && ! pr_contains (credentials, privilege))
a83cc46b 1459 {
73f52eb4 1460 // We do not have the default privilege credentials (stapdev). Lower
bb4470ca
DB
1461 // the privilege level to match our credentials.
1462 if (pr_contains (credentials, pr_stapsys))
a83cc46b 1463 {
bb4470ca
DB
1464 privilege = pr_stapsys;
1465 server_args.push_back ("--privilege=stapsys");
4e78c716
DB
1466 auto_privilege_level_msg =
1467 _("--privilege=stapsys was automatically selected because you are a member "
1468 "of the groups stapusr and stapsys. [man stap]");
a83cc46b 1469 }
bb4470ca
DB
1470 else if (pr_contains (credentials, pr_stapusr))
1471 {
bb4470ca
DB
1472 privilege = pr_stapusr;
1473 server_args.push_back ("--privilege=stapusr");
4e78c716
DB
1474 auto_privilege_level_msg =
1475 _("--privilege=stapusr was automatically selected because you are a member "
1476 "of the group stapusr. [man stap]");
bb4470ca
DB
1477 }
1478 else
1479 {
1480 // Completely unprivileged user.
1481 cerr << _("You are trying to run systemtap as a normal user.\n"
1482 "You should either be root, or be part of "
4e78c716
DB
1483 "the group \"stapusr\" and possibly one of the groups "
1484 "\"stapsys\" or \"stapdev\". [man stap]\n");
3d6362c6
LB
1485#if HAVE_DYNINST
1486 cerr << _("Alternatively, you may specify --runtime=dyninst for userspace probing.\n");
1487#endif
bb4470ca
DB
1488 usage (1); // does not return.
1489 }
1490 }
bb4470ca
DB
1491 // Add --use-server if not already specified and the user's (lack of) credentials require
1492 // it for pass 5.
1493 if (! pr_contains (credentials, pr_stapdev))
1494 {
4e78c716
DB
1495 enable_auto_server (
1496 _F("For users with the privilege level %s, the module created by compiling your "
1497 "script must be signed by a trusted systemtap compile-server.",
1498 pr_name (credentials)));
a83cc46b
DB
1499 }
1500 }
1501
372c6458 1502 if (client_options && ! pr_contains (privilege, pr_stapdev) && ! client_options_disallowed_for_unprivileged.empty ())
e2012a7a 1503 {
f66bb29a 1504 cerr << _F("You can't specify %s when --privilege=%s is specified.",
372c6458 1505 client_options_disallowed_for_unprivileged.c_str(),
f66bb29a
DB
1506 pr_name (privilege))
1507 << endl;
e2012a7a
DB
1508 usage (1);
1509 }
1510 if ((cmd != "") && (target_pid))
1511 {
ce0f6648 1512 cerr << _F("You can't specify %s and %s together.", "-c", "-x") << endl;
e2012a7a
DB
1513 usage (1);
1514 }
3e784e8b
JS
1515
1516 // NB: In user-mode runtimes (dyninst), we can allow guru mode any time, but we
1517 // need to restrict guru by privilege level in the kernel runtime.
ac3af990 1518 if (! runtime_usermode_p () && ! pr_contains (privilege, pr_stapdev) && guru_mode)
e2012a7a 1519 {
f66bb29a
DB
1520 cerr << _F("You can't specify %s and --privilege=%s together.", "-g", pr_name (privilege))
1521 << endl;
e2012a7a
DB
1522 usage (1);
1523 }
3e784e8b 1524
305fac7d
CM
1525 // Can't use --remote and --tmpdir together because with --remote,
1526 // there may be more than one tmpdir needed.
1527 if (!remote_uris.empty() && tmpdir_opt_set)
1528 {
1529 cerr << _F("You can't specify %s and %s together.", "--remote", "--tmpdir") << endl;
1530 usage(1);
1531 }
e2012a7a 1532 // Warn in case the target kernel release doesn't match the running one.
50f2545f
FCE
1533 native_build = (release == kernel_release &&
1534 machine == architecture); // NB: squashed ARCH by PR4186 logic
1535
19da0351
JS
1536 // Non-native builds can't be loaded locally, but may still work on remotes
1537 if (last_pass > 4 && !native_build && remote_uris.empty())
50f2545f 1538 {
2713ea24 1539 print_warning("kernel release/architecture mismatch with host forces last-pass 4.");
50f2545f
FCE
1540 last_pass = 4;
1541 }
0ba354fe
CM
1542 if(download_dbinfo != 0 && access ("/usr/bin/abrt-action-install-debuginfo-to-abrt-cache", X_OK) < 0
1543 && access ("/usr/libexec/abrt-action-install-debuginfo-to-abrt-cache", X_OK) < 0)
ea60076d 1544 {
0ba354fe 1545 print_warning("abrt-action-install-debuginfo-to-abrt-cache is not installed. Continuing without downloading debuginfo.");
ea60076d
CM
1546 download_dbinfo = 0;
1547 }
e2012a7a 1548
e2012a7a
DB
1549 // translate path of runtime to absolute path
1550 if (runtime_path[0] != '/')
1551 {
1552 char cwd[PATH_MAX];
1553 if (getcwd(cwd, sizeof(cwd)))
1554 {
1555 runtime_path = string(cwd) + "/" + runtime_path;
1556 }
1557 }
44edbcd6
JS
1558
1559 // Abnormal characters in our temp path can break us, including parts out
1560 // of our control like Kbuild. Let's enforce nice, safe characters only.
1561 const char *tmpdir = getenv("TMPDIR");
fc4cb088 1562 if (tmpdir != NULL)
44edbcd6 1563 assert_regexp_match("TMPDIR", tmpdir, "^[-/._0-9a-z]+$");
b3367f63
DS
1564
1565 // If the kernel is using signed modules, we need to enforce server
1566 // use.
1567 if (!client_options && modules_must_be_signed())
1568 {
1569 // Force server use to be on, if not on already.
4e78c716
DB
1570 enable_auto_server (
1571 _("The kernel on your system requires modules to be signed for loading.\n"
1572 "The module created by compiling your script must be signed by a systemtap "
1573 "compile-server."));
b3367f63
DS
1574
1575 // Cache the current system's machine owner key (MOK)
1576 // information, to pass over to the server.
1577 get_mok_info();
1578 }
ce286ff0
DB
1579}
1580
8dfad013
JS
1581int
1582systemtap_session::parse_kernel_config ()
1583{
1584 // PR10702: pull config options
1585 string kernel_config_file = kernel_build_tree + "/.config";
1586 struct stat st;
1587 int rc = stat(kernel_config_file.c_str(), &st);
1588 if (rc != 0)
1589 {
1590 clog << _F("Checking \"%s\" failed with error: %s",
1591 kernel_config_file.c_str(), strerror(errno)) << endl;
1592 find_devel_rpms(*this, kernel_build_tree.c_str());
1593 missing_rpm_list_print(*this, "-devel");
1594 return rc;
1595 }
1596
1597 ifstream kcf (kernel_config_file.c_str());
1598 string line;
1599 while (getline (kcf, line))
1600 {
1601 if (!startswith(line, "CONFIG_")) continue;
1602 size_t off = line.find('=');
1603 if (off == string::npos) continue;
1604 string key = line.substr(0, off);
1605 string value = line.substr(off+1, string::npos);
1606 kernel_config[key] = value;
1607 }
1608 if (verbose > 2)
1609 clog << _F("Parsed kernel \"%s\", ", kernel_config_file.c_str())
52c2652f
NMA
1610 << _NF("containing %zu tuple", "containing %zu tuples",
1611 kernel_config.size(), kernel_config.size()) << endl;
1612
8dfad013
JS
1613
1614 kcf.close();
1615 return 0;
1616}
1617
1618
1619int
1620systemtap_session::parse_kernel_exports ()
1621{
1622 string kernel_exports_file = kernel_build_tree + "/Module.symvers";
1623 struct stat st;
1624 int rc = stat(kernel_exports_file.c_str(), &st);
1625 if (rc != 0)
1626 {
1627 clog << _F("Checking \"%s\" failed with error: %s\nEnsure kernel development headers & makefiles are installed",
1628 kernel_exports_file.c_str(), strerror(errno)) << endl;
1629 return rc;
1630 }
1631
1632 ifstream kef (kernel_exports_file.c_str());
1633 string line;
1634 while (getline (kef, line))
1635 {
1636 vector<string> tokens;
1637 tokenize (line, tokens, "\t");
1638 if (tokens.size() == 4 &&
1639 tokens[2] == "vmlinux" &&
1640 tokens[3].substr(0,13) == string("EXPORT_SYMBOL"))
1641 kernel_exports.insert (tokens[1]);
1642 // RHEL4 Module.symvers file only has 3 tokens. No
1643 // 'EXPORT_SYMBOL' token at the end of the line.
1644 else if (tokens.size() == 3 && tokens[2] == "vmlinux")
1645 kernel_exports.insert (tokens[1]);
1646 }
1647 if (verbose > 2)
52c2652f 1648 clog << _NF("Parsed kernel %s, which contained one vmlinux export",
8dfad013 1649 "Parsed kernel %s, which contained %zu vmlinux exports",
52c2652f 1650 kernel_exports.size(), kernel_exports_file.c_str(),
8dfad013
JS
1651 kernel_exports.size()) << endl;
1652
1653 kef.close();
1654 return 0;
1655}
1656
1657
2a639817
JS
1658int
1659systemtap_session::parse_kernel_functions ()
1660{
1661 string system_map_path = kernel_build_tree + "/System.map";
1662 ifstream system_map;
1663
1664 system_map.open(system_map_path.c_str(), ifstream::in);
1665 if (! system_map.is_open())
1666 {
f123a0f1
FCE
1667 if (verbose > 1)
1668 clog << _F("Kernel symbol table %s unavailable, (%s)",
1669 system_map_path.c_str(), strerror(errno)) << endl;
d1d1b146 1670
2a639817 1671 string system_map_path2 = "/boot/System.map-" + kernel_release;
2a639817
JS
1672 system_map.clear();
1673 system_map.open(system_map_path2.c_str(), ifstream::in);
1674 if (! system_map.is_open())
1675 {
f123a0f1
FCE
1676 if (verbose > 1)
1677 clog << _F("Kernel symbol table %s unavailable, (%s)",
1678 system_map_path2.c_str(), strerror(errno)) << endl;
2a639817
JS
1679 }
1680 }
1681
1682 string address, type, name;
f123a0f1 1683 while (system_map.good())
2a639817 1684 {
57accd63
FCE
1685 assert_no_interrupts();
1686
2a639817
JS
1687 system_map >> address >> type >> name;
1688
1689 if (verbose > 3)
1690 clog << "'" << address << "' '" << type << "' '" << name
1691 << "'" << endl;
1692
1693 // 'T'/'t' are text code symbols
1694 if (type != "t" && type != "T")
1695 continue;
1696
1697#ifdef __powerpc__ // XXX cross-compiling hazard
1698 // Map ".sys_foo" to "sys_foo".
1699 if (name[0] == '.')
1700 name.erase(0, 1);
1701#endif
1702
1703 // FIXME: better things to do here - look for _stext before
1704 // remembering symbols. Also:
1705 // - stop remembering names at ???
1706 // - what about __kprobes_text_start/__kprobes_text_end?
1707 kernel_functions.insert(name);
1708 }
2a639817
JS
1709 system_map.close();
1710 return 0;
1711}
1712
1713
44edbcd6
JS
1714void
1715systemtap_session::init_try_server ()
1716{
1717#if HAVE_NSS
1718 // If the option is disabled or we are a server or we are already using a
1719 // server, then never retry compilation using a server.
1720 if (! use_server_on_error || client_options || ! specified_servers.empty ())
1721 try_server_status = dont_try_server;
1722 else
1723 try_server_status = try_server_unset;
1724#else
1725 // No client, so don't bother.
1726 try_server_status = dont_try_server;
1727#endif
1728}
1729
1730void
1731systemtap_session::set_try_server (int t)
1732{
1733 if (try_server_status != dont_try_server)
1734 try_server_status = t;
1735}
1736
1737
c1743705
AK
1738void systemtap_session::insert_loaded_modules()
1739{
1740 char line[1024];
1741 ifstream procmods ("/proc/modules");
1742 while (procmods.good()) {
1743 procmods.getline (line, sizeof(line));
1744 strtok(line, " \t");
1745 if (line[0] == '\0')
1746 break; // maybe print a warning?
1747 unwindsym_modules.insert (string (line));
1748 }
1749 procmods.close();
eebd081d 1750 unwindsym_modules.insert ("kernel");
c1743705
AK
1751}
1752
e2012a7a
DB
1753void
1754systemtap_session::setup_kernel_release (const char* kstr)
1755{
4f747a64
JS
1756 // Sometimes we may get dupes here... e.g. a server may have a full
1757 // -r /path/to/kernel followed by a client's -r kernel.
1758 if (kernel_release == kstr)
1759 return; // nothing new here...
1760
504d2b61 1761 kernel_release = kernel_build_tree = kernel_source_tree = "";
e2012a7a
DB
1762 if (kstr[0] == '/') // fully specified path
1763 {
1764 kernel_build_tree = kstr;
aeb9cc10 1765 kernel_release = kernel_release_from_build_tree (kernel_build_tree, verbose);
61f1a63b
FCE
1766
1767 // PR10745
1768 // Maybe it's a full kernel source tree, for purposes of PR10745.
1769 // In case CONFIG_DEBUG_INFO was set, we'd find it anyway with the
1770 // normal search in tapsets.cxx. Without CONFIG_DEBUG_INFO, we'd
1771 // need heuristics such as this one:
1772
1773 string some_random_source_only_file = kernel_build_tree + "/COPYING";
1774 ifstream epic (some_random_source_only_file.c_str());
1775 if (! epic.fail())
1776 {
1777 kernel_source_tree = kernel_build_tree;
1778 if (verbose > 2)
46a1a151 1779 clog << _F("Located kernel source tree (COPYING) at '%s'", kernel_source_tree.c_str()) << endl;
61f1a63b 1780 }
e2012a7a
DB
1781 }
1782 else
1783 {
05fb3e0c 1784 update_release_sysroot = true;
e2012a7a 1785 kernel_release = string (kstr);
504d2b61
JS
1786 if (!kernel_release.empty())
1787 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
61f1a63b
FCE
1788
1789 // PR10745
1790 // Let's not look for the kernel_source_tree; it's definitely
1791 // not THERE. tapsets.cxx might try to find it later if tracepoints
1792 // need it.
e2012a7a
DB
1793 }
1794}
1795
1796
1797// Register all the aliases we've seen in library files, and the user
1798// file, as patterns.
1799void
1800systemtap_session::register_library_aliases()
1801{
1802 vector<stapfile*> files(library_files);
1803 files.push_back(user_file);
1804
1805 for (unsigned f = 0; f < files.size(); ++f)
1806 {
1807 stapfile * file = files[f];
1808 for (unsigned a = 0; a < file->aliases.size(); ++a)
1809 {
1810 probe_alias * alias = file->aliases[a];
1811 try
1812 {
1813 for (unsigned n = 0; n < alias->alias_names.size(); ++n)
1814 {
1815 probe_point * name = alias->alias_names[n];
6f58d8ae 1816 match_node * mn = pattern_root;
e2012a7a
DB
1817 for (unsigned c = 0; c < name->components.size(); ++c)
1818 {
1819 probe_point::component * comp = name->components[c];
1820 // XXX: alias parameters
1821 if (comp->arg)
dc09353a 1822 throw SEMANTIC_ERROR(_F("alias component %s contains illegal parameter",
46a1a151 1823 comp->functor.c_str()));
6f58d8ae 1824 mn = mn->bind(comp->functor);
e2012a7a 1825 }
f66bb29a 1826 // PR 12916: All probe aliases are OK for all users. The actual
373027ba 1827 // referenced probe points will be checked when the alias is resolved.
f66bb29a 1828 mn->bind_privilege (pr_all);
6f58d8ae 1829 mn->bind(new alias_expansion_builder(alias));
e2012a7a
DB
1830 }
1831 }
1832 catch (const semantic_error& e)
1833 {
c081af73
JL
1834 semantic_error er(ERR_SRC, _("while registering probe alias"),
1835 alias->tok, NULL, &e);
1836 print_error (er);
e2012a7a
DB
1837 }
1838 }
1839 }
1840}
1841
1842
1843// Print this given token, but abbreviate it if the last one had the
1844// same file name.
1845void
1846systemtap_session::print_token (ostream& o, const token* tok)
1847{
1848 assert (tok);
1849
1850 if (last_token && last_token->location.file == tok->location.file)
1851 {
1852 stringstream tmpo;
1853 tmpo << *tok;
1854 string ts = tmpo.str();
1855 // search & replace the file name with nothing
1856 size_t idx = ts.find (tok->location.file->name);
d4d892e1
JL
1857 if (idx != string::npos) {
1858 ts.erase(idx, tok->location.file->name.size()); // remove path
1859 if (color_errors) {
1860 string src = ts.substr(idx); // keep line & col
1861 ts.erase(idx); // remove from output string
1862 ts += colorize(src, "source"); // re-add it colorized
1863 }
1864 }
e2012a7a
DB
1865
1866 o << ts;
1867 }
1868 else
eada930e 1869 o << colorize(tok);
e2012a7a
DB
1870
1871 last_token = tok;
1872}
1873
1874
e2012a7a 1875void
9e1a2390 1876systemtap_session::print_error (const semantic_error& se)
e2012a7a 1877{
9f20af93
FCE
1878 // skip error message printing for listing mode with low verbosity
1879 if (this->listing_mode && this->verbose <= 1)
1880 {
9e1a2390 1881 seen_errors[se.errsrc_chain()]++; // increment num_errors()
9f20af93
FCE
1882 return;
1883 }
1884
9e1a2390
JL
1885 // duplicate elimination
1886 if (verbose > 0 || seen_errors[se.errsrc_chain()] < 1)
e2012a7a 1887 {
9e1a2390 1888 seen_errors[se.errsrc_chain()]++;
c081af73 1889 for (const semantic_error *e = &se; e != NULL; e = e->get_chain())
9e1a2390 1890 cerr << build_error_msg(*e);
e2012a7a 1891 }
9e1a2390
JL
1892 else suppressed_errors++;
1893}
e2012a7a 1894
9e1a2390
JL
1895string
1896systemtap_session::build_error_msg (const semantic_error& e)
1897{
1898 stringstream message;
1899 string align_semantic_error (" ");
1900
1901 message << colorize(_("semantic error:"), "error") << ' ' << e.what ();
1902 if (e.tok1 || e.tok2)
1903 message << ": ";
1904 if (e.tok1)
1905 {
1906 print_token (message, e.tok1);
1907 message << endl;
1908 print_error_source (message, align_semantic_error, e.tok1);
1909 }
1910 if (e.tok2)
1911 {
1912 print_token (message, e.tok2);
1913 message << endl;
1914 print_error_source (message, align_semantic_error, e.tok2);
1915 }
1916 message << endl;
1917 return message.str();
e2012a7a
DB
1918}
1919
1920void
1921systemtap_session::print_error_source (std::ostream& message,
1922 std::string& align, const token* tok)
1923{
1924 unsigned i = 0;
1925
1926 assert (tok);
1927 if (!tok->location.file)
1928 //No source to print, silently exit
1929 return;
1930
1931 unsigned line = tok->location.line;
1932 unsigned col = tok->location.column;
1933 const string &file_contents = tok->location.file->file_contents;
1934
1935 size_t start_pos = 0, end_pos = 0;
1936 //Navigate to the appropriate line
1937 while (i != line && end_pos != std::string::npos)
1938 {
1939 start_pos = end_pos;
1940 end_pos = file_contents.find ('\n', start_pos) + 1;
1941 i++;
1942 }
d4d892e1
JL
1943 //TRANSLATORS: Here we are printing the source string of the error
1944 message << align << _("source: ");
1945 string srcline = file_contents.substr(start_pos, end_pos-start_pos-1);
0dd40eb5
FCE
1946 if (color_errors &&
1947 // Only colorize tokens whose content is known to match the source
1948 // content. e.g. tok_string doesn't qualify because of the double-quotes.
1949 // tok_embedded lacks the %{ %}. tok_junk is just junky.
1950 (tok->type == tok_number ||
1951 tok->type == tok_identifier ||
1952 tok->type == tok_operator)) {
d4d892e1 1953 // Split into before token, token, and after token
0dd40eb5 1954 string tok_content = tok->content;
d4d892e1 1955 message << srcline.substr(0, col-1);
0dd40eb5
FCE
1956 message << colorize(tok_content, "token");
1957 message << srcline.substr(col+tok_content.size()-1) << endl;
d4d892e1
JL
1958 } else
1959 message << srcline << endl;
e2012a7a
DB
1960 message << align << " ";
1961 //Navigate to the appropriate column
1962 for (i=start_pos; i<start_pos+col-1; i++)
1963 {
1964 if(isspace(file_contents[i]))
1965 message << file_contents[i];
1966 else
1967 message << ' ';
1968 }
d4d892e1 1969 message << colorize("^", "caret") << endl;
101b0805
JS
1970
1971 // print chained macro invocations and synthesized code
1972 if (tok->chain)
1973 {
1974 if (tok->location.file->synthetic)
1975 message << _("\tin synthesized code from: ");
1976 else
1977 message << _("\tin expansion of macro: ");
1978 message << colorize(tok->chain) << endl;
1979 print_error_source (message, align, tok->chain);
1980 }
e2012a7a
DB
1981}
1982
1983void
1984systemtap_session::print_warning (const string& message_str, const token* tok)
1985{
1c1f304d
JL
1986 if (suppress_warnings)
1987 return; // NB: don't count towards suppressed_warnings count
2713ea24 1988
e2012a7a
DB
1989 // Duplicate elimination
1990 string align_warning (" ");
1c1f304d 1991 if (verbose > 0 || seen_warnings.find (message_str) == seen_warnings.end())
e2012a7a
DB
1992 {
1993 seen_warnings.insert (message_str);
d4d892e1 1994 clog << colorize(_("WARNING:"), "warning") << ' ' << message_str;
e2012a7a
DB
1995 if (tok) { clog << ": "; print_token (clog, tok); }
1996 clog << endl;
1997 if (tok) { print_error_source (clog, align_warning, tok); }
1998 }
1c1f304d 1999 else suppressed_warnings++;
e2012a7a
DB
2000}
2001
d4d892e1 2002
6b7d7185
JL
2003void
2004systemtap_session::print_error (const parse_error &pe,
2005 const token* tok,
7ac01ea0
JL
2006 const std::string &input_name,
2007 bool is_warningerr)
6b7d7185 2008{
9e1a2390
JL
2009 // duplicate elimination
2010 if (verbose > 0 || seen_errors[pe.errsrc_chain()] < 1)
2011 {
7ac01ea0
JL
2012 // Sometimes, we need to print parse errors that should not be considered
2013 // critical. For example, when we parse tapsets and macros. In those
2014 // cases, is_warningerr is true, and we cancel out the increase in
2015 // seen_errors.size() by also increasing warningerr_count, so that the
2016 // net num_errors() value is unchanged.
2017 seen_errors[pe.errsrc_chain()]++; // can be simplified if we
2018 if (seen_errors[pe.errsrc_chain()] == 1 && is_warningerr) // change map to a set (and
2019 warningerr_count++; // settle on threshold of 1)
9e1a2390
JL
2020 cerr << build_error_msg(pe, tok, input_name);
2021 for (const parse_error *e = pe.chain; e != NULL; e = e->chain)
2022 cerr << build_error_msg(*e, e->tok, input_name);
2023 }
2024 else suppressed_errors++;
2025}
2026
2027string
2028systemtap_session::build_error_msg (const parse_error& pe,
2029 const token* tok,
2030 const std::string &input_name)
2031{
2032 stringstream message;
6b7d7185
JL
2033 string align_parse_error (" ");
2034
2035 // print either pe.what() or a deferred error from the lexer
2036 bool found_junk = false;
2037 if (tok && tok->type == tok_junk && tok->msg != "")
2038 {
2039 found_junk = true;
9e1a2390 2040 message << colorize(_("parse error:"), "error") << ' ' << tok->msg << endl;
6b7d7185
JL
2041 }
2042 else
2043 {
9e1a2390 2044 message << colorize(_("parse error:"), "error") << ' ' << pe.what() << endl;
6b7d7185
JL
2045 }
2046
2047 // NB: It makes sense for lexer errors to always override parser
2048 // errors, since the original obvious scheme was for the lexer to
2049 // throw an exception before the token reached the parser.
2050
2051 if (pe.tok || found_junk)
2052 {
9e1a2390
JL
2053 message << _("\tat: ") << colorize(tok) << endl;
2054 print_error_source (message, align_parse_error, tok);
6b7d7185
JL
2055 }
2056 else if (tok) // "expected" type error
2057 {
9e1a2390
JL
2058 message << _("\tsaw: ") << colorize(tok) << endl;
2059 print_error_source (message, align_parse_error, tok);
6b7d7185
JL
2060 }
2061 else
2062 {
9e1a2390 2063 message << _("\tsaw: ") << input_name << " EOF" << endl;
6b7d7185 2064 }
9e1a2390 2065 message << endl;
78ab2de3 2066
9e1a2390 2067 return message.str();
6b7d7185
JL
2068}
2069
1c1f304d
JL
2070void
2071systemtap_session::report_suppression()
2072{
2073 if (this->suppressed_errors > 0)
2074 cerr << colorize(_F("Number of similar error messages suppressed: %d.",
2075 this->suppressed_errors),
2076 "error") << endl;
2077 if (this->suppressed_warnings > 0)
2078 cerr << colorize(_F("Number of similar warning messages suppressed: %d.",
2079 this->suppressed_warnings),
2080 "warning") << endl;
2081 if (this->suppressed_errors > 0 || this->suppressed_warnings > 0)
2082 cerr << "Rerun with -v to see them." << endl;
2083}
2084
b96901b7
CM
2085void
2086systemtap_session::create_tmp_dir()
2087{
2088 if (!tmpdir.empty())
2089 return;
2090
2091 // Create the temp directory
2092 const char * tmpdir_env = getenv("TMPDIR");
2093 if (!tmpdir_env)
2094 tmpdir_env = "/tmp";
2095
2096 string stapdir = "/stapXXXXXX";
2097 string tmpdirt = tmpdir_env + stapdir;
2098 const char *tmpdir_name = mkdtemp((char *)tmpdirt.c_str());
2099 if (! tmpdir_name)
2100 {
2101 const char* e = strerror(errno);
2102 //TRANSLATORS: we can't make the directory due to the error
2103 throw runtime_error(_F("cannot create temporary directory (\" %s \"): %s", tmpdirt.c_str(), e));
2104 }
2105 else
2106 tmpdir = tmpdir_name;
2107}
2108
2109void
2110systemtap_session::remove_tmp_dir()
2111{
2112 if(tmpdir.empty())
2113 return;
2114
2115 // Remove temporary directory
2116 if (keep_tmpdir && !tmpdir_opt_set)
2117 clog << _F("Keeping temporary directory \"%s\"", tmpdir.c_str()) << endl;
2118 else if (!tmpdir_opt_set)
2119 {
2120 // Mask signals while we're deleting the temporary directory.
2121 stap_sigmasker masked;
2122
2123 // Remove the temporary directory.
2124 vector<string> cleanupcmd;
2125 cleanupcmd.push_back("rm");
2126 cleanupcmd.push_back("-rf");
2127 cleanupcmd.push_back(tmpdir);
2128
2129 (void) stap_system(verbose, cleanupcmd);
2130 if (verbose>1)
2131 clog << _F("Removed temporary directory \"%s\"", tmpdir.c_str()) << endl;
2132 tmpdir.clear();
2133
2134 }
2135}
2136
2137void
2138systemtap_session::reset_tmp_dir()
2139{
2140 remove_tmp_dir();
2141 create_tmp_dir();
2142}
a4b9c3b3
FCE
2143
2144translator_output* systemtap_session::op_create_auxiliary()
2145{
2146 static int counter = 0;
2147 string tmpname = this->tmpdir + "/" + this->module_name + "_aux_" + lex_cast(counter++) + ".c";
2148 translator_output* n = new translator_output (tmpname);
2149 auxiliary_outputs.push_back (n);
2150 return n;
2151}
2152
e19ebcf7
CM
2153// Wrapper for checking if there are pending interrupts
2154void
e2d0f787
JS
2155assert_no_interrupts()
2156{
2157 if (pending_interrupts)
2158 throw interrupt_exception();
2159}
a4b9c3b3 2160
d4d892e1 2161std::string
eada930e 2162systemtap_session::colorize(const std::string& str, const std::string& type)
d4d892e1
JL
2163{
2164 if (str.empty() || !color_errors)
2165 return str;
ed28ad1b
JL
2166 else {
2167 // Check if this type is defined in SYSTEMTAP_COLORS
2168 std::string color = parse_stap_color(type);
aeb08b15
JL
2169 if (!color.empty()) // no need to pollute terminal if not necessary
2170 return "\033[" + color + "m\033[K" + str + "\033[m\033[K";
2171 else
2172 return str;
ed28ad1b 2173 }
d4d892e1
JL
2174}
2175
2176// Colorizes the path:row:col part of the token
2177std::string
eada930e 2178systemtap_session::colorize(const token* tok)
d4d892e1 2179{
eada930e
JL
2180 if (tok == NULL)
2181 return "";
2182
d4d892e1 2183 stringstream tmp;
eada930e 2184 tmp << *tok;
d4d892e1
JL
2185
2186 if (!color_errors)
2187 return tmp.str(); // Might as well stop now to save time
2188 else {
2189 string ts = tmp.str();
2190
2191 // Print token location, which is also the tail of ts
2192 stringstream loc;
eada930e 2193 loc << tok->location;
d4d892e1
JL
2194
2195 // Remove token location and re-add it colorized
2196 ts.erase(ts.size()-loc.str().size());
2197 return ts + colorize(loc.str(), "source");
2198 }
2199}
2200
ed28ad1b
JL
2201/* Parse SYSTEMTAP_COLORS and returns the SGR parameter(s) for the given
2202type. The env var SYSTEMTAP_COLORS must be in the following format:
2203'key1=val1:key2=val2:' etc... where valid keys are 'error', 'warning',
2204'source', 'caret', 'token' and valid values constitute SGR parameter(s).
2205For example, the default setting would be:
80c39315 2206'error=01;31:warning=00;33:source=00;34:caret=01:token=01'
80c39315 2207*/
ed28ad1b 2208std::string
eada930e 2209systemtap_session::parse_stap_color(const std::string& type)
80c39315 2210{
291e91fe
JL
2211 const char *key, *col, *eq;
2212 int n = type.size();
2213 int done = 0;
2214
2215 key = getenv("SYSTEMTAP_COLORS");
6667be37 2216 if (key == NULL)
291e91fe 2217 key = "error=01;31:warning=00;33:source=00;34:caret=01:token=01";
6667be37
JL
2218 else if (*key == '\0')
2219 return ""; // disable colors if set but empty
291e91fe
JL
2220
2221 while (!done) {
014da3e6 2222 if (!(col = strchr(key, ':'))) {
291e91fe
JL
2223 col = strchr(key, '\0');
2224 done = 1;
2759d5b4 2225 }
291e91fe
JL
2226 if (!((eq = strchr(key, '=')) && eq < col))
2227 return ""; /* invalid syntax: no = in range */
2228 if (!(key < eq && eq < col-1))
2229 return ""; /* invalid syntax: key or val empty */
2230 if (strspn(eq+1, "0123456789;") < (size_t)(col-eq-1))
2231 return ""; /* invalid syntax: invalid char in val */
014da3e6 2232 if (eq-key == n && type.compare(0, n, key, n) == 0)
291e91fe
JL
2233 return string(eq+1, col-eq-1);
2234 if (!done) key = col+1; /* advance to next key */
2235 }
2236
ed28ad1b
JL
2237 // Could not find the key
2238 return "";
80c39315 2239}
d4d892e1 2240
b3367f63
DS
2241/*
2242 * Returns true if this system requires modules to have signatures
2243 * (typically on a secure boot system), false otherwise.
2244 *
2245 * This routine parses /sys/module/module/parameters/sig_enforce to
2246 * figure out if signatures are enforced on modules. Note that if the
2247 * file doesn't exist, we don't really care and return false.
2248 */
2249bool
2250systemtap_session::modules_must_be_signed()
2251{
2252 ifstream statm("/sys/module/module/parameters/sig_enforce");
2253 char status;
2254
2255 statm >> status;
2256 if (status == 'Y')
2257 return true;
2258 return false;
2259}
2260
2261/*
2262 * Get information on the list of enrolled machine owner keys (MOKs) on
2263 * this system.
2264 */
2265void
2266systemtap_session::get_mok_info()
2267{
2268 vector<string> cmd;
2269 int rc;
2270 stringstream out;
2271
b3367f63
DS
2272 // FIXME: In theory, we should be able to read /sys files and use
2273 // some of the guts of read_cert_info_from_file() to get the
2274 // fingerprints. This would rid us of our mokutil
2275 // dependency. However, we'd need to copy/duplicate efilib.c from
2276 // mokutil source to be able to decipher the efi data.
b3367f63
DS
2277
2278 cmd.push_back("mokutil");
2279 cmd.push_back("--list-enrolled");
2280 rc = stap_system_read(verbose, cmd, out);
2281 if (rc != 0)
25c72c50
DS
2282 // If we're here, we know the client requires module signing, but
2283 // we can't get the list of MOKs. Quit.
2284 throw runtime_error(_F("failed to get list of machine owner keys (MOK) fingerprints: rc %d", rc));
b3367f63
DS
2285
2286 string line, fingerprint;
2287 while (! out.eof())
2288 {
2289 vector<string> matches;
2290
cd1418c7
DS
2291 // Get a line of the output, then try to find the fingerprint in
2292 // the line.
b3367f63
DS
2293 getline(out, line);
2294 if (! regexp_match(line, "^SHA1 Fingerprint: ([0-9a-f:]+)$", matches))
2295 {
2296 // matches[0] is the entire line, matches[1] is the first
2297 // submatch, in this case the actual fingerprint
2298 if (verbose > 2)
2299 clog << "MOK fingerprint found: " << matches[1] << endl;
2300 if (! matches[1].empty())
cd1418c7 2301 mok_fingerprints.push_back(matches[1]);
b3367f63
DS
2302 }
2303 }
2304}
2305
4e78c716
DB
2306void
2307systemtap_session::enable_auto_server (const string &message)
2308{
2309 // There may be more than one reason to enable auto server mode, so we may be called
2310 // more than once. Accumulate the messages.
2311 auto_server_msgs.push_back (message);
2312
2313#if HAVE_NSS
2314 // Enable auto server mode, if not enabled already.
2315 if (specified_servers.empty())
2316 specified_servers.push_back ("");
2317#else
2318 // Compilation using a server is not supported. exit() after
2319 // the first explanation.
2320 explain_auto_options ();
2321 clog << _("Unable to request compilation by a compile-server\n."
2322 "Without NSS, --use-server is not supported by this version systemtap.") << endl;
2323 exit(1);
2324#endif
2325}
2326
2327void
2328systemtap_session::explain_auto_options()
2329{
2330 // Was there an automatic privilege setting?
2331 if (! auto_privilege_level_msg.empty())
2332 clog << auto_privilege_level_msg << endl;
2333
2334 // Was a server was automatically requested? Handle this one after other auto_settings
2335 // which may result in an auto_server setting.
2336 if (! auto_server_msgs.empty())
2337 {
2338 for (vector<string>::iterator i = auto_server_msgs.begin(); i != auto_server_msgs.end(); ++i)
2339 {
2340 clog << *i << endl;
2341 clog << _("--use-server was automatically selected in order to request compilation by "
2342 "a compile-server.") << endl;
2343 }
2344 }
2345}
b3367f63 2346
2dce8c42
DB
2347// --------------------------------------------------------------------------
2348
e2012a7a
DB
2349/*
2350Perngrq sebz fzvyrlgnc.fit, rkcbegrq gb n 1484k1110 fzvyrlgnc.cat,
2351gurapr catgbcnz | cazfpnyr -jvqgu 160 |
2352cczqvgure -qvz 4 -erq 2 -terra 2 -oyhr 2 | cczgbnafv -2k4 | bq -i -j19 -g k1 |
2353phg -s2- -q' ' | frq -r 'f,^,\\k,' -r 'f, ,\\k,t' -r 'f,^,",' -r 'f,$,",'
2354*/
2355const char*
2356systemtap_session::morehelp =
2357"\x1b\x5b\x30\x6d\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2358"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2359"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2360"\x20\x20\x20\x60\x20\x20\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2361"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20"
2362"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2363"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2364"\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x1b\x5b"
2365"\x33\x33\x6d\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2366"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2367"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2368"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x20\x60"
2369"\x2e\x60\x1b\x5b\x33\x37\x6d\x20\x3a\x2c\x3a\x2e\x60\x20\x60\x20\x60\x20\x60"
2370"\x2c\x3b\x2c\x3a\x20\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d"
2371"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
2372"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2373"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33"
2374"\x33\x6d\x20\x60\x20\x60\x20\x3a\x27\x60\x1b\x5b\x33\x37\x6d\x20\x60\x60\x60"
2375"\x20\x20\x20\x60\x20\x60\x60\x60\x20\x1b\x5b\x33\x33\x6d\x60\x3a\x60\x20\x60"
2376"\x20\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2377"\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2378"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2379"\x20\x2e\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x20\x1b\x5b\x33"
2380"\x37\x6d\x20\x3a\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x2e\x1b\x5b\x33\x33"
2381"\x6d\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20"
2382"\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x2e\x3a\x20\x20"
2383"\x20\x20\x20\x20\x20\x20\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2384"\x20\x20\x2e\x76\x53\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x1b\x5b"
2385"\x33\x31\x6d\x2b\x1b\x5b\x33\x33\x6d\x60\x20\x60\x20\x60\x20\x20\x20\x20\x1b"
2386"\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x33\x6d\x2b\x1b\x5b"
2387"\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x2e\x1b\x5b\x33\x30\x6d\x24\x1b\x5b"
2388"\x33\x37\x6d\x3b\x1b\x5b\x33\x31\x6d\x7c\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
2389"\x20\x60\x20\x60\x1b\x5b\x33\x31\x6d\x2c\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33"
2390"\x37\x6d\x53\x53\x3e\x2c\x2e\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x2e"
2391"\x3b\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x20\x20\x20\x20\x20\x20"
2392"\x20\x20\x20\x2e\x2e\x3a\x1b\x5b\x33\x30\x6d\x26\x46\x46\x46\x48\x46\x1b\x5b"
2393"\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x30\x6d\x4d\x4d"
2394"\x46\x1b\x5b\x33\x33\x6d\x20\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x1b\x5b"
2395"\x33\x33\x6d\x20\x3a\x1b\x5b\x33\x30\x6d\x4d\x4d\x46\x1b\x5b\x33\x33\x6d\x20"
2396"\x20\x20\x60\x20\x60\x2e\x60\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x30\x6d\x46"
2397"\x46\x46\x24\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
2398"\x20\x2e\x3c\x3a\x60\x20\x20\x20\x20\x2e\x3a\x2e\x3a\x2e\x2e\x3b\x27\x20\x20"
2399"\x20\x20\x20\x20\x2e\x60\x2e\x3a\x60\x60\x3c\x27\x1b\x5b\x33\x31\x6d\x3c\x27"
2400"\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x3c\x1b\x5b\x33"
2401"\x30\x6d\x26\x1b\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x33\x6d\x20\x1b\x5b\x33\x37"
2402"\x6d\x20\x1b\x5b\x33\x33\x6d\x20\x20\x20\x20\x20\x1b\x5b\x33\x37\x6d\x60\x1b"
2403"\x5b\x33\x30\x6d\x2a\x46\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x20\x60"
2404"\x20\x60\x20\x60\x20\x60\x20\x1b\x5b\x33\x31\x6d\x60\x3a\x1b\x5b\x33\x37\x6d"
2405"\x27\x3c\x1b\x5b\x33\x30\x6d\x23\x1b\x5b\x33\x37\x6d\x3c\x60\x3a\x20\x20\x20"
2406"\x0a\x20\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x20\x60\x3a\x2e\x2e\x2e\x2e\x3c"
2407"\x3c\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x60\x20\x20\x20\x60\x1b\x5b\x33"
2408"\x33\x6d\x3a\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x20"
2409"\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x37\x6d\x20\x20\x1b\x5b\x33\x33\x6d"
2410"\x20\x60\x20\x20\x20\x60\x1b\x5b\x33\x37\x6d\x20\x60\x20\x60\x1b\x5b\x33\x33"
2411"\x6d\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
2412"\x20\x60\x3a\x2e\x60\x2e\x20\x0a\x20\x20\x20\x60\x3a\x60\x3a\x60\x20\x20\x20"
2413"\x20\x20\x60\x60\x60\x60\x20\x3a\x2d\x20\x20\x20\x20\x20\x60\x20\x60\x20\x20"
2414"\x20\x20\x20\x60\x1b\x5b\x33\x33\x6d\x3a\x60\x2e\x60\x20\x60\x20\x60\x20\x60"
2415"\x20\x60\x20\x20\x2e\x3b\x1b\x5b\x33\x31\x6d\x76\x1b\x5b\x33\x30\x6d\x24\x24"
2416"\x24\x1b\x5b\x33\x31\x6d\x2b\x53\x1b\x5b\x33\x33\x6d\x2c\x60\x20\x60\x20\x60"
2417"\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x3a"
2418"\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x2e\x60\x20\x20\x0a\x20\x20\x20\x60"
2419"\x3a\x3a\x3a\x3a\x20\x20\x20\x20\x3a\x60\x60\x60\x60\x3a\x53\x20\x20\x20\x20"
2420"\x20\x20\x3a\x2e\x60\x2e\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
2421"\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20\x60"
2422"\x20\x3a\x1b\x5b\x33\x30\x6d\x24\x46\x46\x48\x46\x46\x46\x46\x46\x1b\x5b\x33"
2423"\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2e"
2424"\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
2425"\x20\x2e\x60\x2e\x3a\x20\x20\x0a\x20\x20\x20\x60\x3a\x3a\x3a\x60\x20\x20\x20"
2426"\x60\x3a\x20\x2e\x20\x3b\x27\x3a\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x20"
2427"\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x60\x1b"
2428"\x5b\x33\x33\x6d\x2e\x60\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x30\x6d\x53"
2429"\x46\x46\x46\x53\x46\x46\x46\x53\x46\x46\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
2430"\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x20"
2431"\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x0a\x20\x20\x20\x20\x60\x3c\x3b\x3c\x20"
2432"\x20\x20\x20\x20\x60\x60\x60\x20\x3a\x3a\x20\x20\x20\x20\x20\x20\x20\x3a\x3a"
2433"\x2e\x60\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d"
2434"\x3c\x3a\x60\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x30"
2435"\x6d\x53\x46\x53\x46\x46\x46\x53\x46\x46\x46\x53\x1b\x5b\x33\x33\x6d\x2e\x60"
2436"\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b"
2437"\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x3a\x3a\x60\x20\x20\x20\x0a\x20\x20"
2438"\x20\x20\x20\x60\x3b\x3c\x20\x20\x20\x20\x20\x20\x20\x3a\x3b\x60\x20\x20\x20"
2439"\x20\x20\x20\x20\x20\x20\x60\x3a\x60\x2e\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33"
2440"\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33"
2441"\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x1b\x5b\x33\x31\x6d\x3a"
2442"\x1b\x5b\x33\x30\x6d\x46\x53\x46\x53\x46\x53\x46\x53\x46\x1b\x5b\x33\x31\x6d"
2443"\x3f\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x2e\x3a\x3a\x1b\x5b\x33\x31\x6d\x3c"
2444"\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x60\x20"
2445"\x20\x20\x3a\x3a\x3a\x60\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x53\x3c"
2446"\x20\x20\x20\x20\x20\x20\x3a\x53\x3a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2447"\x20\x60\x3a\x3a\x60\x2e\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
2448"\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a"
2449"\x60\x2e\x60\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x53\x24\x53\x46\x53\x24\x1b\x5b"
2450"\x33\x33\x6d\x60\x3a\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
2451"\x33\x31\x6d\x3a\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b"
2452"\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x2e\x60\x3a\x3a\x60\x20"
2453"\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x3b\x3c\x2e\x2e\x2c\x2e\x2e\x20"
2454"\x3a\x3c\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a"
2455"\x60\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31"
2456"\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33"
2457"\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3c\x1b\x5b\x33\x30\x6d\x53\x24\x53\x1b"
2458"\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x2e\x3a\x3b"
2459"\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x31\x6d"
2460"\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x20\x60\x2e\x3a"
2461"\x3a\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x2e\x3a\x3a\x3c\x53\x3c\x3a\x60"
2462"\x3a\x3a\x3a\x3a\x53\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33\x37\x6d\x3b\x27\x3a"
2463"\x3c\x2c\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a\x3a\x2e\x60"
2464"\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
2465"\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b"
2466"\x33\x31\x6d\x3c\x2c\x1b\x5b\x33\x33\x6d\x3c\x3b\x3a\x1b\x5b\x33\x31\x6d\x2c"
2467"\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x53"
2468"\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x3c\x1b\x5b\x33\x37\x6d\x3a"
2469"\x60\x2e\x60\x2e\x3b\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x3f\x27"
2470"\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x3a\x3c\x53\x53\x3b\x3c"
2471"\x3a\x60\x3a\x3a\x53\x53\x53\x3c\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x1b\x5b"
2472"\x33\x37\x6d\x2b\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x3a\x1b\x5b\x33\x34"
2473"\x6d\x53\x1b\x5b\x33\x30\x6d\x53\x46\x24\x1b\x5b\x33\x37\x6d\x2c\x60\x3a\x3a"
2474"\x3a\x3c\x3a\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33"
2475"\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31"
2476"\x6d\x53\x3b\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33"
2477"\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37"
2478"\x6d\x3c\x53\x3c\x3a\x3a\x3a\x3a\x3f\x1b\x5b\x33\x30\x6d\x53\x24\x48\x1b\x5b"
2479"\x33\x37\x6d\x27\x60\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x2e"
2480"\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x1b\x5b\x33"
2481"\x30\x6d\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20"
2482"\x60\x3a\x1b\x5b\x33\x30\x6d\x3c\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60"
2483"\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3c\x3a\x60\x3a\x27\x3a\x60\x3a\x60\x3a"
2484"\x60\x3a\x60\x3b\x1b\x5b\x33\x30\x6d\x53\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27"
2485"\x20\x60\x20\x60\x20\x60\x20\x20\x20\x20\x0a\x20\x3c\x3b\x3a\x2e\x60\x20\x60"
2486"\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2c\x53\x1b\x5b\x33\x32\x6d\x53\x1b"
2487"\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2488"\x20\x20\x60\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x46\x46\x1b\x5b\x33\x34\x6d"
2489"\x2b\x1b\x5b\x33\x37\x6d\x3a\x20\x60\x20\x60\x20\x60\x2e\x60\x20\x60\x2e\x60"
2490"\x20\x60\x2e\x60\x20\x60\x20\x60\x2c\x1b\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b"
2491"\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x20"
2492"\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3b\x3c"
2493"\x2c\x60\x2c\x3b\x3b\x53\x3f\x53\x1b\x5b\x33\x30\x6d\x24\x46\x3c\x1b\x5b\x33"
2494"\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x60"
2495"\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60\x20"
2496"\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x3b\x76\x1b\x5b\x33\x30\x6d"
2497"\x48\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20"
2498"\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x24\x1b"
2499"\x5b\x33\x37\x6d\x53\x53\x53\x53\x53\x53\x1b\x5b\x33\x30\x6d\x53\x24\x53\x46"
2500"\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2501"\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x23\x46\x46\x46"
2502"\x24\x1b\x5b\x33\x37\x6d\x76\x2c\x2c\x20\x2e\x20\x2e\x20\x2c\x2c\x76\x1b\x5b"
2503"\x33\x30\x6d\x26\x24\x46\x46\x48\x3c\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20"
2504"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x60"
2505"\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x46\x24\x46\x24\x46\x46\x48\x46\x53\x1b\x5b"
2506"\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x2e\x60\x20\x60\x2e\x60\x2e\x60"
2507"\x2e\x60\x2e\x60\x3a\x3a\x3a\x3a\x3a\x1b\x5b\x33\x30\x6d\x2a\x46\x46\x46\x48"
2508"\x46\x48\x46\x48\x46\x46\x46\x48\x46\x48\x46\x48\x1b\x5b\x33\x37\x6d\x3c\x22"
2509"\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x0a"
2510"\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x48"
2511"\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x20\x60\x2e\x60\x20\x60"
2512"\x2e\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3a\x3a\x60\x3a\x3c\x3c"
2513"\x1b\x5b\x33\x30\x6d\x3c\x46\x48\x46\x46\x46\x48\x46\x46\x46\x1b\x5b\x33\x37"
2514"\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
2515"\x60\x20\x60\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b"
2516"\x33\x30\x6d\x2a\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x20\x20\x60\x20\x60"
2517"\x2e\x60\x20\x60\x2e\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a"
2518"\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x46\x46\x48\x46\x48\x46"
2519"\x1b\x5b\x33\x37\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x3a\x60\x2e"
2520"\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x20\x60\x0a\x20\x20\x20\x20\x20\x20\x20"
2521"\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x1b\x5b\x33\x37\x6d"
2522"\x2b\x60\x20\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2e\x60\x20"
2523"\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x60\x2e\x60\x3b\x1b\x5b\x33\x30\x6d"
2524"\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
2525"\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x20\x20\x0a\x20"
2526"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22\x1b\x5b\x33\x30\x6d\x3c"
2527"\x48\x46\x53\x1b\x5b\x33\x37\x6d\x2b\x3a\x20\x20\x20\x60\x20\x60\x20\x60\x20"
2528"\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2c\x1b"
2529"\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x60\x20\x60\x20"
2530"\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60"
2531"\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2532"\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x48\x24\x46\x46\x1b\x5b\x33\x37\x6d\x3e\x2c"
2533"\x2e\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x3b"
2534"\x2c\x2c\x1b\x5b\x33\x30\x6d\x24\x53\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x22"
2535"\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x20\x20"
2536"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20"
2537"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b\x33\x30\x6d\x2a\x3c\x48"
2538"\x46\x46\x24\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3e\x3e\x3e\x3e\x3e\x53"
2539"\x3e\x53\x1b\x5b\x33\x30\x6d\x24\x53\x24\x46\x24\x48\x46\x23\x1b\x5b\x33\x37"
2540"\x6d\x27\x22\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2541"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20"
2542"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2543"\x60\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x2a\x3c\x3c\x3c\x48\x46\x46\x46\x48\x46"
2544"\x46\x46\x23\x3c\x1b\x5b\x33\x36\x6d\x3c\x1b\x5b\x33\x37\x6d\x3c\x27\x22\x22"
2545"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2546"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x1b"
2547 "\x5b\x30\x6d";
ebff2ed0
JS
2548
2549/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.462551 seconds and 5 git commands to generate.