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