]> sourceware.org Git - systemtap.git/blob - session.cxx
PR13513: undo PR11759 PREEMPT_RT hack
[systemtap.git] / session.cxx
1 // session functions
2 // Copyright (C) 2010-2011 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 "elaborate.h"
13 #include "translate.h"
14 #include "buildrun.h"
15 #include "coveragedb.h"
16 #include "hash.h"
17 #include "task_finder.h"
18 #include "csclient.h"
19 #include "rpm_finder.h"
20 #include "util.h"
21 #include "git_version.h"
22
23 #include <cerrno>
24 #include <cstdlib>
25
26 extern "C" {
27 #include <getopt.h>
28 #include <limits.h>
29 #include <grp.h>
30 #include <sys/stat.h>
31 #include <sys/utsname.h>
32 #include <elfutils/libdwfl.h>
33 }
34
35 #if HAVE_NSS
36 extern "C" {
37 #include <nspr.h>
38 }
39 #endif
40
41 #include <string>
42
43 using namespace std;
44
45 /* getopt variables */
46 extern int optind;
47
48 #define PATH_TBD string("__TBD__")
49
50 #if HAVE_NSS
51 bool systemtap_session::NSPR_Initialized = false;
52 #endif
53
54 systemtap_session::systemtap_session ():
55 // NB: pointer members must be manually initialized!
56 // NB: don't forget the copy constructor too!
57 base_hash(0),
58 pattern_root(new match_node),
59 user_file (0),
60 be_derived_probes(0),
61 dwarf_derived_probes(0),
62 kprobe_derived_probes(0),
63 hwbkpt_derived_probes(0),
64 perf_derived_probes(0),
65 uprobe_derived_probes(0),
66 utrace_derived_probes(0),
67 itrace_derived_probes(0),
68 task_finder_derived_probes(0),
69 timer_derived_probes(0),
70 profile_derived_probes(0),
71 mark_derived_probes(0),
72 tracepoint_derived_probes(0),
73 hrtimer_derived_probes(0),
74 procfs_derived_probes(0),
75 op (0), up (0),
76 sym_kprobes_text_start (0),
77 sym_kprobes_text_end (0),
78 sym_stext (0),
79 module_cache (0),
80 last_token (0)
81 {
82 struct utsname buf;
83 (void) uname (& buf);
84 kernel_release = string (buf.release);
85 release = kernel_release;
86 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
87 architecture = machine = normalize_machine(buf.machine);
88
89 for (unsigned i=0; i<5; i++) perpass_verbose[i]=0;
90 verbose = 0;
91
92 have_script = false;
93 runtime_specified = false;
94 include_arg_start = -1;
95 timing = false;
96 guru_mode = false;
97 bulk_mode = false;
98 unoptimized = false;
99 suppress_warnings = false;
100 panic_warnings = false;
101 listing_mode = false;
102 listing_mode_vars = false;
103 dump_probe_types = false;
104
105 #ifdef ENABLE_PROLOGUES
106 prologue_searching = true;
107 #else
108 prologue_searching = false;
109 #endif
110
111 buffer_size = 0;
112 last_pass = 5;
113 module_name = "stap_" + lex_cast(getpid());
114 stapconf_name = "stapconf_" + lex_cast(getpid()) + ".h";
115 output_file = ""; // -o FILE
116 tmpdir_opt_set = false;
117 save_module = false;
118 modname_given = false;
119 keep_tmpdir = false;
120 cmd = "";
121 target_pid = 0;
122 use_cache = true;
123 use_script_cache = true;
124 poison_cache = false;
125 tapset_compile_coverage = false;
126 need_uprobes = false;
127 need_unwind = false;
128 need_symbols = false;
129 uprobes_path = "";
130 consult_symtab = false;
131 ignore_vmlinux = false;
132 ignore_dwarf = false;
133 load_only = false;
134 skip_badvars = false;
135 privilege = pr_stapdev;
136 omit_werror = false;
137 compatible = VERSION; // XXX: perhaps also process GIT_SHAID if available?
138 unwindsym_ldd = false;
139 client_options = false;
140 server_cache = NULL;
141 automatic_server_mode = false;
142 use_server_on_error = false;
143 try_server_status = try_server_unset;
144 use_remote_prefix = false;
145 systemtap_v_check = false;
146 download_dbinfo = 0;
147 suppress_handler_errors = false;
148 native_build = true; // presumed
149
150 /* adding in the XDG_DATA_DIRS variable path,
151 * this searches in conjunction with SYSTEMTAP_TAPSET
152 * to locate stap scripts, either can be disabled if
153 * needed using env $PATH=/dev/null where $PATH is the
154 * path you want disabled
155 */
156 const char* s_p1 = getenv ("XDG_DATA_DIRS");
157 if ( s_p1 != NULL )
158 {
159 vector<string> dirs;
160 tokenize(s_p1, dirs, ":");
161 for(vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i)
162 {
163 include_path.push_back(*i + "/systemtap/tapset");
164 }
165 }
166
167 const char* s_p = getenv ("SYSTEMTAP_TAPSET");
168 if (s_p != NULL)
169 {
170 include_path.push_back (s_p);
171 }
172 else
173 {
174 include_path.push_back (string(PKGDATADIR) + "/tapset");
175 }
176
177 const char* s_r = getenv ("SYSTEMTAP_RUNTIME");
178 if (s_r != NULL)
179 runtime_path = s_r;
180 else
181 runtime_path = string(PKGDATADIR) + "/runtime";
182
183 const char* s_d = getenv ("SYSTEMTAP_DIR");
184 if (s_d != NULL)
185 data_path = s_d;
186 else
187 data_path = get_home_directory() + string("/.systemtap");
188 if (create_dir(data_path.c_str()) == 1)
189 {
190 const char* e = strerror (errno);
191 if (! suppress_warnings)
192 cerr << _F("Warning: failed to create systemtap data directory \"%s\":%s, disabling cache support.",
193 data_path.c_str(),e) << endl;
194 use_cache = use_script_cache = false;
195 }
196
197 if (use_cache)
198 {
199 cache_path = data_path + "/cache";
200 if (create_dir(cache_path.c_str()) == 1)
201 {
202 const char* e = strerror (errno);
203 if (! suppress_warnings)
204 cerr << _F("Warning: failed to create cache directory (\" %s \"): %s, disabling cache support.",
205 cache_path.c_str(),e) << endl;
206 use_cache = use_script_cache = false;
207 }
208 }
209
210 const char* s_tc = getenv ("SYSTEMTAP_COVERAGE");
211 if (s_tc != NULL)
212 tapset_compile_coverage = true;
213
214 const char* s_kr = getenv ("SYSTEMTAP_RELEASE");
215 if (s_kr != NULL) {
216 setup_kernel_release(s_kr);
217 }
218 }
219
220 systemtap_session::systemtap_session (const systemtap_session& other,
221 const string& arch,
222 const string& kern):
223 // NB: pointer members must be manually initialized!
224 // NB: this needs to consider everything that the base ctor does,
225 // plus copying any wanted implicit fields (strings, vectors, etc.)
226 base_hash(0),
227 pattern_root(new match_node),
228 user_file (other.user_file),
229 be_derived_probes(0),
230 dwarf_derived_probes(0),
231 kprobe_derived_probes(0),
232 hwbkpt_derived_probes(0),
233 perf_derived_probes(0),
234 uprobe_derived_probes(0),
235 utrace_derived_probes(0),
236 itrace_derived_probes(0),
237 task_finder_derived_probes(0),
238 timer_derived_probes(0),
239 profile_derived_probes(0),
240 mark_derived_probes(0),
241 tracepoint_derived_probes(0),
242 hrtimer_derived_probes(0),
243 procfs_derived_probes(0),
244 op (0), up (0),
245 sym_kprobes_text_start (0),
246 sym_kprobes_text_end (0),
247 sym_stext (0),
248 module_cache (0),
249 last_token (0)
250 {
251 release = kernel_release = kern;
252 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
253 architecture = machine = normalize_machine(arch);
254 setup_kernel_release(kern.c_str());
255 native_build = false; // assumed; XXX: could be computed as in check_options()
256
257 // These are all copied in the same order as the default ctor did above.
258
259 copy(other.perpass_verbose, other.perpass_verbose + 5, perpass_verbose);
260 verbose = other.verbose;
261
262 have_script = other.have_script;
263 runtime_specified = other.runtime_specified;
264 include_arg_start = other.include_arg_start;
265 timing = other.timing;
266 guru_mode = other.guru_mode;
267 bulk_mode = other.bulk_mode;
268 unoptimized = other.unoptimized;
269 suppress_warnings = other.suppress_warnings;
270 panic_warnings = other.panic_warnings;
271 listing_mode = other.listing_mode;
272 listing_mode_vars = other.listing_mode_vars;
273 dump_probe_types = other.dump_probe_types;
274
275 prologue_searching = other.prologue_searching;
276
277 buffer_size = other.buffer_size;
278 last_pass = other.last_pass;
279 module_name = other.module_name;
280 stapconf_name = other.stapconf_name;
281 output_file = other.output_file; // XXX how should multiple remotes work?
282 tmpdir_opt_set = false;
283 save_module = other.save_module;
284 modname_given = other.modname_given;
285 keep_tmpdir = other.keep_tmpdir;
286 cmd = other.cmd;
287 target_pid = other.target_pid; // XXX almost surely nonsense for multiremote
288 use_cache = other.use_cache;
289 use_script_cache = other.use_script_cache;
290 poison_cache = other.poison_cache;
291 tapset_compile_coverage = other.tapset_compile_coverage;
292 need_uprobes = false;
293 need_unwind = false;
294 need_symbols = false;
295 uprobes_path = "";
296 consult_symtab = other.consult_symtab;
297 ignore_vmlinux = other.ignore_vmlinux;
298 ignore_dwarf = other.ignore_dwarf;
299 load_only = other.load_only;
300 skip_badvars = other.skip_badvars;
301 privilege = other.privilege;
302 omit_werror = other.omit_werror;
303 compatible = other.compatible;
304 unwindsym_ldd = other.unwindsym_ldd;
305 client_options = other.client_options;
306 server_cache = NULL;
307 use_server_on_error = other.use_server_on_error;
308 try_server_status = other.try_server_status;
309 use_remote_prefix = other.use_remote_prefix;
310 systemtap_v_check = other.systemtap_v_check;
311 download_dbinfo = other.download_dbinfo;
312 suppress_handler_errors = other.suppress_handler_errors;
313
314 include_path = other.include_path;
315 runtime_path = other.runtime_path;
316
317 // NB: assuming that "other" created these already
318 data_path = other.data_path;
319 cache_path = other.cache_path;
320
321 tapset_compile_coverage = other.tapset_compile_coverage;
322
323
324 // These are fields that were left to their default ctor, but now we want to
325 // copy them from "other". In the same order as declared...
326 script_file = other.script_file;
327 cmdline_script = other.cmdline_script;
328 macros = other.macros;
329 args = other.args;
330 kbuildflags = other.kbuildflags;
331 globalopts = other.globalopts;
332 modinfos = other.modinfos;
333
334 client_options_disallowed = other.client_options_disallowed;
335 server_status_strings = other.server_status_strings;
336 specified_servers = other.specified_servers;
337 server_trust_spec = other.server_trust_spec;
338 server_args = other.server_args;
339
340 unwindsym_modules = other.unwindsym_modules;
341 automatic_server_mode = other.automatic_server_mode;
342 }
343
344 systemtap_session::~systemtap_session ()
345 {
346 delete_map(subsessions);
347 delete pattern_root;
348 }
349
350 #if HAVE_NSS
351 void
352 systemtap_session::NSPR_init ()
353 {
354 if (! NSPR_Initialized)
355 {
356 PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
357 NSPR_Initialized = true;
358 }
359 }
360 #endif // HAVE_NSS
361
362 systemtap_session*
363 systemtap_session::clone(const string& arch, const string& release)
364 {
365 const string norm_arch = normalize_machine(arch);
366 if (this->architecture == norm_arch && this->kernel_release == release)
367 return this;
368
369 systemtap_session*& s = subsessions[make_pair(norm_arch, release)];
370 if (!s)
371 s = new systemtap_session(*this, norm_arch, release);
372 return s;
373 }
374
375 void
376 systemtap_session::version ()
377 {
378 clog << _F("Systemtap translator/driver (version %s/%s %s)\n"
379 "Copyright (C) 2005-2011 Red Hat, Inc. and others\n"
380 "This is free software; see the source for copying conditions.",
381 VERSION, dwfl_version(NULL), GIT_MESSAGE) << endl;
382 clog << _("enabled features:")
383 #ifdef HAVE_AVAHI
384 << " AVAHI"
385 #endif
386 #ifdef HAVE_LIBRPM
387 << " LIBRPM"
388 #endif
389 #ifdef HAVE_LIBSQLITE3
390 << " LIBSQLITE3"
391 #endif
392 #ifdef HAVE_NSS
393 << " NSS"
394 #endif
395 #ifdef HAVE_BOOST_SHARED_PTR_HPP
396 << " BOOST_SHARED_PTR"
397 #endif
398 #ifdef HAVE_TR1_UNORDERED_MAP
399 << " TR1_UNORDERED_MAP"
400 #endif
401 #ifdef ENABLE_PROLOGUES
402 << " PROLOGUES"
403 #endif
404 #ifdef ENABLE_NLS
405 << " NLS"
406 #endif
407 << endl;
408 }
409
410 void
411 systemtap_session::usage (int exitcode)
412 {
413 version ();
414 clog
415 << endl
416 //Session.cxx:287-390 detail systemtap usage from stap -h
417 << _F("Usage: stap [options] FILE Run script in file.\n"
418 " or: stap [options] - Run script on stdin.\n"
419 " or: stap [options] -e SCRIPT Run given script.\n"
420 " or: stap [options] -l PROBE List matching probes.\n"
421 " or: stap [options] -L PROBE List matching probes and local variables.\n\n"
422 "Options:\n"
423 " -- end of translator options, script options follow\n"
424 " -h --help show help\n"
425 " -V --version show version\n"
426 " -p NUM stop after pass NUM 1-5, instead of %d\n"
427 " (parse, elaborate, translate, compile, run)\n"
428 " -v add verbosity to all passes\n"
429 " --vp {N}+ add per-pass verbosity [", last_pass);
430 for (unsigned i=0; i<5; i++)
431 clog << (perpass_verbose[i] <= 9 ? perpass_verbose[i] : 9);
432 clog
433 << "]" << endl;
434 clog << _F(" -k keep temporary directory\n"
435 " -u unoptimized translation %s\n"
436 " -w suppress warnings %s\n"
437 " -W turn warnings into errors %s\n"
438 " -g guru mode %s\n"
439 " -P prologue-searching for function probes %s\n"
440 " -b bulk (percpu file) mode %s\n"
441 " -s NUM buffer size in megabytes, instead of %d\n"
442 " -I DIR look in DIR for additional .stp script files", (unoptimized ? _(" [set]") : ""),
443 (suppress_warnings ? _(" [set]") : ""), (panic_warnings ? _(" [set]") : ""),
444 (guru_mode ? _(" [set]") : ""), (prologue_searching ? _(" [set]") : ""),
445 (bulk_mode ? _(" [set]") : ""), buffer_size);
446 if (include_path.size() == 0)
447 clog << endl;
448 else
449 clog << _(", in addition to") << endl;
450 for (unsigned i=0; i<include_path.size(); i++)
451 clog << " " << include_path[i].c_str() << endl;
452 clog
453 << _F(" -D NM=VAL emit macro definition into generated C code\n"
454 " -B NM=VAL pass option to kbuild make\n"
455 " --modinfo NM=VAL\n"
456 " include a MODULE_INFO(NM,VAL) in the generated C code\n"
457 " -G VAR=VAL set global variable to value\n"
458 //TRANSLATORS: translating 'runtime' is not advised
459 " -R DIR look in DIR for runtime, instead of\n"
460 " %s\n"
461 " -r DIR cross-compile to kernel with given build tree; or else\n"
462 " -r RELEASE cross-compile to kernel /lib/modules/RELEASE/build, instead of\n"
463 " %s\n"
464 " -a ARCH cross-compile to given architecture, instead of %s\n"
465 " -m MODULE set probe module name, instead of \n"
466 " %s\n"
467 " -o FILE send script output to file, instead of stdout. This supports\n"
468 " strftime(3) formats for FILE\n"
469 " -c CMD start the probes, run CMD, and exit when it finishes\n"
470 " -x PID sets target() to PID\n"
471 " -F run as on-file flight recorder with -o.\n"
472 " run as on-memory flight recorder without -o.\n"
473 " -S size[,n] set maximum of the size and the number of files.\n"
474 " -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());
475 if (unwindsym_modules.size() == 0)
476 clog << endl;
477 else
478 clog << _(", in addition to") << endl;
479 {
480 vector<string> syms (unwindsym_modules.begin(), unwindsym_modules.end());
481 for (unsigned i=0; i<syms.size(); i++)
482 clog << " " << syms[i].c_str() << endl;
483 }
484 clog
485 << _F(" --ldd add unwind/symbol data for all referenced object files.\n"
486 " --all-modules\n"
487 " add unwind/symbol data for all loaded kernel objects.\n"
488 " -t collect probe timing information\n"
489 #ifdef HAVE_LIBSQLITE3
490 " -q generate information on tapset coverage\n"
491 #endif /* HAVE_LIBSQLITE3 */
492 " --privilege=PRIVILEGE_LEVEL\n"
493 " check the script for constructs not allowed at the given privilege level\n"
494 " --unprivileged\n"
495 " equivalent to --privilege=stapusr\n"
496 #if 0 /* PR6864: disable temporarily; should merge with -d somehow */
497 " --kelf make do with symbol table from vmlinux\n"
498 " --kmap[=FILE]\n"
499 " make do with symbol table from nm listing\n"
500 #endif
501 // Formerly present --ignore-{vmlinux,dwarf} options are for testsuite use
502 // only, and don't belong in the eyesight of a plain user.
503 " --compatible=VERSION\n"
504 " suppress incompatible language/tapset changes beyond VERSION,\n"
505 " instead of %s\n"
506 " --check-version\n"
507 " displays warnings where a syntax element may be \n"
508 " version dependent\n"
509 " --skip-badvars\n"
510 " substitute zero for bad context $variables\n"
511 " --suppress-handler-errors\n"
512 " catch all runtime errors, quietly skip probe handlers\n"
513 " --use-server[=SERVER-SPEC]\n"
514 " specify systemtap compile-servers\n"
515 " --list-servers[=PROPERTIES]\n"
516 " report on the status of the specified compile-servers:\n"
517 " all,specified,online,trusted,signer,compatible\n"
518 #if HAVE_NSS
519 " --trust-servers[=TRUST-SPEC]\n"
520 " add/revoke trust of specified compile-servers:\n"
521 " ssl,signer,all-users,revoke,no-prompt\n"
522 " --use-server-on-error[=yes/no]\n"
523 " retry compilation using a compile server upon compilation error\n"
524 #endif
525 " --remote=HOSTNAME\n"
526 " run pass 5 on the specified ssh host.\n"
527 " may be repeated for targeting multiple hosts.\n"
528 " --remote-prefix\n"
529 " prefix each line of remote output with a host index.\n"
530 " --tmpdir=NAME\n"
531 " specify name of temporary directory to be used.\n"
532 " --download-debuginfo[=OPTION]\n"
533 " automatically download debuginfo using ABRT.\n"
534 " yes,no,ask,<timeout value>\n"
535 " --dump-probe-types\n"
536 " show a list of available probe types.\n"
537 , compatible.c_str()) << endl
538 ;
539
540 time_t now;
541 time (& now);
542 struct tm* t = localtime (& now);
543 if (t && t->tm_mon*3 + t->tm_mday*173 == 0xb6)
544 clog << morehelp << endl;
545
546 exit (exitcode);
547 }
548
549 int
550 systemtap_session::parse_cmdline (int argc, char * const argv [])
551 {
552 client_options_disallowed = "";
553 while (true)
554 {
555 int long_opt = 0;
556 char * num_endptr;
557
558 // NB: when adding new options, consider very carefully whether they
559 // should be restricted from stap clients (after --client-options)!
560 #define LONG_OPT_KELF 1
561 #define LONG_OPT_KMAP 2
562 #define LONG_OPT_IGNORE_VMLINUX 3
563 #define LONG_OPT_IGNORE_DWARF 4
564 #define LONG_OPT_VERBOSE_PASS 5
565 #define LONG_OPT_SKIP_BADVARS 6
566 #define LONG_OPT_UNPRIVILEGED 7
567 #define LONG_OPT_OMIT_WERROR 8
568 #define LONG_OPT_CLIENT_OPTIONS 9
569 #define LONG_OPT_HELP 10
570 #define LONG_OPT_DISABLE_CACHE 11
571 #define LONG_OPT_POISON_CACHE 12
572 #define LONG_OPT_CLEAN_CACHE 13
573 #define LONG_OPT_COMPATIBLE 14
574 #define LONG_OPT_LDD 15
575 #define LONG_OPT_USE_SERVER 16
576 #define LONG_OPT_LIST_SERVERS 17
577 #define LONG_OPT_TRUST_SERVERS 18
578 #define LONG_OPT_ALL_MODULES 19
579 #define LONG_OPT_REMOTE 20
580 #define LONG_OPT_CHECK_VERSION 21
581 #define LONG_OPT_USE_SERVER_ON_ERROR 22
582 #define LONG_OPT_VERSION 23
583 #define LONG_OPT_REMOTE_PREFIX 24
584 #define LONG_OPT_TMPDIR 25
585 #define LONG_OPT_DOWNLOAD_DEBUGINFO 26
586 #define LONG_OPT_DUMP_PROBE_TYPES 27
587 #define LONG_OPT_PRIVILEGE 28
588 #define LONG_OPT_SUPPRESS_HANDLER_ERRORS 29
589 #define LONG_OPT_MODINFO 30
590 // NB: also see find_hash(), usage(), switch stmt below, stap.1 man page
591 static struct option long_options[] = {
592 { "kelf", 0, &long_opt, LONG_OPT_KELF },
593 { "kmap", 2, &long_opt, LONG_OPT_KMAP },
594 { "ignore-vmlinux", 0, &long_opt, LONG_OPT_IGNORE_VMLINUX },
595 { "ignore-dwarf", 0, &long_opt, LONG_OPT_IGNORE_DWARF },
596 { "skip-badvars", 0, &long_opt, LONG_OPT_SKIP_BADVARS },
597 { "vp", 1, &long_opt, LONG_OPT_VERBOSE_PASS },
598 { "unprivileged", 0, &long_opt, LONG_OPT_UNPRIVILEGED },
599 #define OWE5 "tter"
600 #define OWE1 "uild-"
601 #define OWE6 "fu-kb"
602 #define OWE2 "i-kno"
603 #define OWE4 "st"
604 #define OWE3 "w-be"
605 { OWE4 OWE6 OWE1 OWE2 OWE3 OWE5, 0, &long_opt, LONG_OPT_OMIT_WERROR },
606 { "client-options", 0, &long_opt, LONG_OPT_CLIENT_OPTIONS },
607 { "help", 0, &long_opt, LONG_OPT_HELP },
608 { "disable-cache", 0, &long_opt, LONG_OPT_DISABLE_CACHE },
609 { "poison-cache", 0, &long_opt, LONG_OPT_POISON_CACHE },
610 { "clean-cache", 0, &long_opt, LONG_OPT_CLEAN_CACHE },
611 { "compatible", 1, &long_opt, LONG_OPT_COMPATIBLE },
612 { "ldd", 0, &long_opt, LONG_OPT_LDD },
613 { "use-server", 2, &long_opt, LONG_OPT_USE_SERVER },
614 { "list-servers", 2, &long_opt, LONG_OPT_LIST_SERVERS },
615 { "trust-servers", 2, &long_opt, LONG_OPT_TRUST_SERVERS },
616 { "use-server-on-error", 2, &long_opt, LONG_OPT_USE_SERVER_ON_ERROR },
617 { "all-modules", 0, &long_opt, LONG_OPT_ALL_MODULES },
618 { "remote", 1, &long_opt, LONG_OPT_REMOTE },
619 { "remote-prefix", 0, &long_opt, LONG_OPT_REMOTE_PREFIX },
620 { "check-version", 0, &long_opt, LONG_OPT_CHECK_VERSION },
621 { "version", 0, &long_opt, LONG_OPT_VERSION },
622 { "tmpdir", 1, &long_opt, LONG_OPT_TMPDIR },
623 { "download-debuginfo", 2, &long_opt, LONG_OPT_DOWNLOAD_DEBUGINFO },
624 { "dump-probe-types", 0, &long_opt, LONG_OPT_DUMP_PROBE_TYPES },
625 { "privilege", 1, &long_opt, LONG_OPT_PRIVILEGE },
626 { "suppress-handler-errors", 0, &long_opt, LONG_OPT_SUPPRESS_HANDLER_ERRORS },
627 { "modinfo", 1, &long_opt, LONG_OPT_MODINFO },
628 { NULL, 0, NULL, 0 }
629 };
630 int grc = getopt_long (argc, argv, "hVvtp:I:e:o:R:r:a:m:kgPc:x:D:bs:uqwl:d:L:FS:B:WG:",
631 long_options, NULL);
632 // NB: when adding new options, consider very carefully whether they
633 // should be restricted from stap clients (after --client-options)!
634
635 if (grc < 0)
636 break;
637 bool push_server_opt = false;
638 switch (grc)
639 {
640 case 'V':
641 push_server_opt = true;
642 version ();
643 exit (0);
644
645 case 'v':
646 push_server_opt = true;
647 for (unsigned i=0; i<5; i++)
648 perpass_verbose[i] ++;
649 verbose ++;
650 break;
651
652 case 'G':
653 // Make sure the global option is only composed of the
654 // following chars: [_=a-zA-Z0-9]
655 assert_regexp_match("-G parameter", optarg, "^[a-z_][a-z0-9_]*=[a-z0-9_-]+$");
656 globalopts.push_back (string(optarg));
657 break;
658
659 case 't':
660 push_server_opt = true;
661 timing = true;
662 break;
663
664 case 'w':
665 push_server_opt = true;
666 suppress_warnings = true;
667 break;
668
669 case 'W':
670 push_server_opt = true;
671 panic_warnings = true;
672 break;
673
674 case 'p':
675 last_pass = (int)strtoul(optarg, &num_endptr, 10);
676 if (*num_endptr != '\0' || last_pass < 1 || last_pass > 5)
677 {
678 cerr << _("Invalid pass number (should be 1-5).") << endl;
679 return 1;
680 }
681 if (listing_mode && last_pass != 2)
682 {
683 cerr << _("Listing (-l) mode implies pass 2.") << endl;
684 return 1;
685 }
686 push_server_opt = true;
687 break;
688
689 case 'I':
690 if (client_options)
691 client_options_disallowed += client_options_disallowed.empty () ? "-I" : ", -I";
692 if (include_arg_start == -1)
693 include_arg_start = include_path.size ();
694 include_path.push_back (string (optarg));
695 break;
696
697 case 'd':
698 push_server_opt = true;
699 {
700 // At runtime user module names are resolved through their
701 // canonical (absolute) path.
702 const char *mpath = canonicalize_file_name (optarg);
703 if (mpath == NULL) // Must be a kernel module name
704 mpath = optarg;
705 unwindsym_modules.insert (string (mpath));
706 // PR10228: trigger vma tracker logic early if -d /USER-MODULE/
707 // given. XXX This is actually too early. Having a user module
708 // is a good indicator that something will need vma tracking.
709 // But it is not 100%, this really should only trigger through
710 // a user mode tapset /* pragma:vma */ or a probe doing a
711 // variable lookup through a dynamic module.
712 if (mpath[0] == '/')
713 enable_vma_tracker (*this);
714 break;
715 }
716
717 case 'e':
718 if (have_script)
719 {
720 cerr << _("Only one script can be given on the command line.")
721 << endl;
722 return 1;
723 }
724 push_server_opt = true;
725 cmdline_script = string (optarg);
726 have_script = true;
727 break;
728
729 case 'o':
730 // NB: client_options not a problem, since pass 1-4 does not use output_file.
731 push_server_opt = true;
732 output_file = string (optarg);
733 break;
734
735 case 'R':
736 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-R", "--client-options") << endl; return 1; }
737 runtime_specified = true;
738 runtime_path = string (optarg);
739 break;
740
741 case 'm':
742 if (client_options)
743 client_options_disallowed += client_options_disallowed.empty () ? "-m" : ", -m";
744 module_name = string (optarg);
745 save_module = true;
746 modname_given = true;
747 {
748 // If the module name ends with '.ko', chop it off since
749 // modutils doesn't like modules named 'foo.ko.ko'.
750 if (endswith(module_name, ".ko"))
751 {
752 module_name.erase(module_name.size() - 3);
753 cerr << _F("Truncating module name to '%s'", module_name.c_str()) << endl;
754 }
755
756 // Make sure an empty module name wasn't specified (-m "")
757 if (module_name.empty())
758 {
759 cerr << _("Module name cannot be empty.") << endl;
760 return 1;
761 }
762
763 // Make sure the module name is only composed of the
764 // following chars: [a-z0-9_]
765 assert_regexp_match("-m parameter", module_name, "^[a-z0-9_]+$");
766
767 // Make sure module name isn't too long.
768 if (module_name.size() >= (MODULE_NAME_LEN - 1))
769 {
770 module_name.resize(MODULE_NAME_LEN - 1);
771 cerr << _F("Truncating module name to '%s'", module_name.c_str()) << endl;
772 }
773 }
774
775 push_server_opt = true;
776 use_script_cache = false;
777 break;
778
779 case 'r':
780 if (client_options) // NB: no paths!
781 assert_regexp_match("-r parameter from client", optarg, "^[a-z0-9_.-]+$");
782 push_server_opt = true;
783 setup_kernel_release(optarg);
784 break;
785
786 case 'a':
787 assert_regexp_match("-a parameter", optarg, "^[a-z0-9_-]+$");
788 push_server_opt = true;
789 architecture = string(optarg);
790 break;
791
792 case 'k':
793 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-k", "--client-options") << endl; return 1; }
794 keep_tmpdir = true;
795 use_script_cache = false; /* User wants to keep a usable build tree. */
796 break;
797
798 case 'g':
799 push_server_opt = true;
800 guru_mode = true;
801 break;
802
803 case 'P':
804 push_server_opt = true;
805 prologue_searching = true;
806 break;
807
808 case 'b':
809 push_server_opt = true;
810 bulk_mode = true;
811 break;
812
813 case 'u':
814 push_server_opt = true;
815 unoptimized = true;
816 break;
817
818 case 's':
819 buffer_size = (int) strtoul (optarg, &num_endptr, 10);
820 if (*num_endptr != '\0' || buffer_size < 1 || buffer_size > 4095)
821 {
822 cerr << _("Invalid buffer size (should be 1-4095).") << endl;
823 return 1;
824 }
825 push_server_opt = true;
826 break;
827
828 case 'c':
829 push_server_opt = true;
830 cmd = string (optarg);
831 if (cmd == "")
832 {
833 // This would mess with later code deciding to pass -c
834 // through to staprun
835 cerr << _("Empty CMD string invalid.") << endl;
836 return 1;
837 }
838 break;
839
840 case 'x':
841 target_pid = (int) strtoul(optarg, &num_endptr, 10);
842 if (*num_endptr != '\0')
843 {
844 cerr << _("Invalid target process ID number.") << endl;
845 return 1;
846 }
847 push_server_opt = true;
848 break;
849
850 case 'D':
851 assert_regexp_match ("-D parameter", optarg, "^[a-z_][a-z_0-9]*(=-?[a-z_0-9]+)?$");
852 if (client_options)
853 client_options_disallowed += client_options_disallowed.empty () ? "-D" : ", -D";
854 push_server_opt = true;
855 macros.push_back (string (optarg));
856 break;
857
858 case 'S':
859 assert_regexp_match ("-S parameter", optarg, "^[0-9]+(,[0-9]+)?$");
860 push_server_opt = true;
861 size_option = string (optarg);
862 break;
863
864 case 'q':
865 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-q", "--client-options") << endl; return 1; }
866 push_server_opt = true;
867 tapset_compile_coverage = true;
868 break;
869
870 case 'h':
871 usage (0);
872 break;
873
874 case 'L':
875 listing_mode_vars = true;
876 unoptimized = true; // This causes retention of variables for listing_mode
877 // fallthrough
878 case 'l':
879 suppress_warnings = true;
880 listing_mode = true;
881 last_pass = 2;
882 if (have_script)
883 {
884 cerr << _("Only one script can be given on the command line.")
885 << endl;
886 return 1;
887 }
888 push_server_opt = true;
889 cmdline_script = string("probe ") + string(optarg) + " {}";
890 have_script = true;
891 break;
892
893 case 'F':
894 push_server_opt = true;
895 load_only = true;
896 break;
897
898 case 'B':
899 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-B", "--client-options") << endl; return 1; }
900 push_server_opt = true;
901 kbuildflags.push_back (string (optarg));
902 break;
903
904 case 0:
905 switch (long_opt)
906 {
907 case LONG_OPT_VERSION:
908 push_server_opt = true;
909 version ();
910 exit (0);
911 break;
912 case LONG_OPT_KELF:
913 push_server_opt = true;
914 consult_symtab = true;
915 break;
916 case LONG_OPT_KMAP:
917 // Leave consult_symtab unset for now, to ease error checking.
918 if (!kernel_symtab_path.empty())
919 {
920 cerr << _("You can't specify multiple --kmap options.") << endl;
921 return 1;
922 }
923 push_server_opt = true;
924 if (optarg)
925 kernel_symtab_path = optarg;
926 else
927 kernel_symtab_path = PATH_TBD;
928 break;
929 case LONG_OPT_IGNORE_VMLINUX:
930 push_server_opt = true;
931 ignore_vmlinux = true;
932 break;
933 case LONG_OPT_IGNORE_DWARF:
934 push_server_opt = true;
935 ignore_dwarf = true;
936 break;
937 case LONG_OPT_VERBOSE_PASS:
938 {
939 bool ok = true;
940 if (strlen(optarg) < 1 || strlen(optarg) > 5)
941 ok = false;
942 if (ok)
943 for (unsigned i=0; i<strlen(optarg); i++)
944 if (isdigit (optarg[i]))
945 perpass_verbose[i] += optarg[i]-'0';
946 else
947 ok = false;
948
949 if (! ok)
950 {
951 cerr << _("Invalid --vp argument: it takes 1 to 5 digits.") << endl;
952 return 1;
953 }
954 // NB: we don't do this: last_pass = strlen(optarg);
955 push_server_opt = true;
956 break;
957 }
958 case LONG_OPT_SKIP_BADVARS:
959 push_server_opt = true;
960 skip_badvars = true;
961 break;
962 case LONG_OPT_PRIVILEGE:
963 push_server_opt = true;
964 if (strcmp (optarg, "stapdev") == 0)
965 privilege = pr_stapdev;
966 else if (strcmp (optarg, "stapsys") == 0)
967 privilege = pr_stapsys;
968 else if (strcmp (optarg, "stapusr") == 0)
969 privilege = pr_stapusr;
970 else
971 {
972 cerr << _F("Invalid argument '%s' for --privilege.", optarg) << endl;
973 return 1;
974 }
975 /* NB: for server security, it is essential that once this flag is
976 set, no future flag be able to unset it. */
977 break;
978 case LONG_OPT_UNPRIVILEGED:
979 // Equivalent to --privilege=stapusr
980 push_server_opt = true;
981 privilege = pr_stapusr;
982 /* NB: for server security, it is essential that once this flag is
983 set, no future flag be able to unset it. */
984 break;
985 case LONG_OPT_OMIT_WERROR:
986 push_server_opt = true;
987 omit_werror = true;
988 break;
989 case LONG_OPT_CLIENT_OPTIONS:
990 client_options = true;
991 break;
992 case LONG_OPT_TMPDIR:
993 if (client_options)
994 client_options_disallowed += client_options_disallowed.empty() ? "--tmpdir" : ", --tmpdir";
995 tmpdir_opt_set = true;
996 tmpdir = optarg;
997 break;
998 case LONG_OPT_DOWNLOAD_DEBUGINFO:
999 if(optarg)
1000 {
1001 if(strcmp(optarg, "no") == 0)
1002 download_dbinfo = 0; //Disable feature
1003 else if (strcmp(optarg, "yes") == 0)
1004 download_dbinfo = INT_MAX; //Enable, No Timeout
1005 /* NOTE: Timeout and Asking for Confirmation features below are not supported yet by abrt
1006 * in version abrt-2.0.3-1.fc15.x86_64, Bugzilla: BZ730107 (timeout), BZ726192 ('-y') */
1007 else if(atoi(optarg) > 0)
1008 download_dbinfo = atoi(optarg); //Enable, Set timeout to optarg
1009 else if (strcmp(optarg, "ask") == 0)
1010 download_dbinfo = -1; //Enable, Ask for confirmation
1011 else
1012 {
1013 cerr << _F("ERROR: %s is not a valid value. Use 'yes', 'no', 'ask' or a timeout value.", optarg) << endl;
1014 return 1;
1015 }
1016 }
1017 else
1018 download_dbinfo = INT_MAX; //Enable, No Timeout
1019 break;
1020 case LONG_OPT_USE_SERVER:
1021 if (client_options)
1022 client_options_disallowed += client_options_disallowed.empty () ? "--use-server" : ", --use-server";
1023 if (optarg)
1024 specified_servers.push_back (optarg);
1025 else
1026 specified_servers.push_back ("");
1027 break;
1028 case LONG_OPT_USE_SERVER_ON_ERROR:
1029 if (client_options)
1030 client_options_disallowed += client_options_disallowed.empty () ? "--use-server-on-error" : ", --use-server-on-error";
1031 if (optarg)
1032 {
1033 string arg = optarg;
1034 for (unsigned i = 0; i < arg.size (); ++i)
1035 arg[i] = tolower (arg[i]);
1036 if (arg == "yes" || arg == "ye" || arg == "y")
1037 use_server_on_error = true;
1038 else if (arg == "no" || arg == "n")
1039 use_server_on_error = false;
1040 else
1041 cerr << _F("Invalid argument '%s' for --use-server-on-error.", optarg) << endl;
1042 }
1043 else
1044 use_server_on_error = true;
1045 break;
1046 case LONG_OPT_LIST_SERVERS:
1047 if (client_options)
1048 client_options_disallowed += client_options_disallowed.empty () ? "--list-servers" : ", --list-servers";
1049 if (optarg)
1050 server_status_strings.push_back (optarg);
1051 else
1052 server_status_strings.push_back ("");
1053 break;
1054 case LONG_OPT_TRUST_SERVERS:
1055 if (client_options)
1056 client_options_disallowed += client_options_disallowed.empty () ? "--trust-servers" : ", --trust-servers";
1057 if (optarg)
1058 server_trust_spec = optarg;
1059 else
1060 server_trust_spec = "ssl";
1061 break;
1062 case LONG_OPT_HELP:
1063 usage (0);
1064 break;
1065
1066 // The caching options should not be available to server clients
1067 case LONG_OPT_DISABLE_CACHE:
1068 if (client_options) {
1069 cerr << _F("ERROR: %s is invalid with %s", "--disable-cache", "--client-options") << endl;
1070 return 1;
1071 }
1072 use_cache = use_script_cache = false;
1073 break;
1074 case LONG_OPT_POISON_CACHE:
1075 if (client_options) {
1076 cerr << _F("ERROR: %s is invalid with %s", "--poison-cache", "--client-options") << endl;
1077 return 1;
1078 }
1079 poison_cache = true;
1080 break;
1081 case LONG_OPT_CLEAN_CACHE:
1082 if (client_options) {
1083 cerr << _F("ERROR: %s is invalid with %s", "--clean-cache", "--client-options") << endl;
1084 return 1;
1085 }
1086 clean_cache(*this);
1087 exit(0);
1088
1089 case LONG_OPT_COMPATIBLE:
1090 push_server_opt = true;
1091 compatible = optarg;
1092 break;
1093
1094 case LONG_OPT_LDD:
1095 if (client_options) {
1096 cerr << _F("ERROR: %s is invalid with %s", "--ldd", "--client-options") << endl;
1097 return 1;
1098 }
1099 push_server_opt = true;
1100 unwindsym_ldd = true;
1101 break;
1102
1103 case LONG_OPT_ALL_MODULES:
1104 if (client_options) {
1105 cerr << _F("ERROR: %s is invalid with %s", "--all-modules", "--client-options") << endl;
1106 return 1;
1107 }
1108 insert_loaded_modules();
1109 break;
1110
1111 case LONG_OPT_REMOTE:
1112 if (client_options) {
1113 cerr << _F("ERROR: %s is invalid with %s", "--remote", "--client-options") << endl;
1114 return 1;
1115 }
1116
1117 remote_uris.push_back(optarg);
1118 break;
1119
1120 case LONG_OPT_REMOTE_PREFIX:
1121 if (client_options) {
1122 cerr << _F("ERROR: %s is invalid with %s", "--remote-prefix", "--client-options") << endl;
1123 return 1;
1124 }
1125
1126 use_remote_prefix = true;
1127 break;
1128
1129 case LONG_OPT_CHECK_VERSION:
1130 push_server_opt = true;
1131 systemtap_v_check = true;
1132 break;
1133
1134 case LONG_OPT_DUMP_PROBE_TYPES:
1135 push_server_opt = true;
1136 dump_probe_types = true;
1137 break;
1138
1139 case LONG_OPT_SUPPRESS_HANDLER_ERRORS:
1140 suppress_handler_errors = true;
1141 break;
1142
1143 case LONG_OPT_MODINFO:
1144 // Make sure the global option is only composed of the
1145 // following chars: [_=a-zA-Z0-9]
1146 if (client_options) {
1147 cerr << _F("ERROR: %s is invalid with %s", "--modinfo", "--client-options") << endl;
1148 return 1;
1149 }
1150 assert_regexp_match("--modinfo parameter", optarg, "^[a-z_][a-z0-9_]*=.+$");
1151 modinfos.push_back (string(optarg));
1152 break;
1153
1154 default:
1155 // NOTREACHED unless one added a getopt option but not a corresponding switch/case:
1156 cerr << _F("Unhandled long argument id %d", long_opt) << endl;
1157 return 1;
1158 }
1159 break;
1160
1161 case '?':
1162 // Invalid/unrecognized option given or argument required, but
1163 // not given. In both cases getopt_long() will have printed the
1164 // appropriate error message to stderr already.
1165 return 1;
1166 break;
1167
1168 default:
1169 // NOTREACHED unless one added a getopt option but not a corresponding switch/case:
1170 cerr << _F("Unhandled argument code %d", (char)grc) << endl;
1171 return 1;
1172 break;
1173 }
1174
1175 // Pass selected options on to the server, if any.
1176 if (push_server_opt)
1177 {
1178 if (grc == 0)
1179 {
1180 // Make sure the '=' is passed with any argument. The server expects it.
1181 if (optarg)
1182 server_args.push_back (string ("--") +
1183 long_options[long_opt - 1].name +
1184 "=" + optarg);
1185 else
1186 server_args.push_back (string ("--") +
1187 long_options[long_opt - 1].name);
1188 }
1189 else
1190 {
1191 server_args.push_back (string ("-") + (char)grc);
1192 if (optarg)
1193 server_args.push_back (optarg);
1194 }
1195 }
1196 }
1197
1198 return 0;
1199 }
1200
1201 void
1202 systemtap_session::check_options (int argc, char * const argv [])
1203 {
1204 for (int i = optind; i < argc; i++)
1205 {
1206 if (! have_script)
1207 {
1208 script_file = string (argv[i]);
1209 have_script = true;
1210 }
1211 else
1212 args.push_back (string (argv[i]));
1213 }
1214
1215 // need a user file
1216 // NB: this is also triggered if stap is invoked with no arguments at all
1217 if (! have_script)
1218 {
1219 // We don't need a script if --list-servers, --trust-servers or --dump-probe-types was
1220 // specified.
1221 if (server_status_strings.empty () && server_trust_spec.empty () && ! dump_probe_types)
1222 {
1223 cerr << _("A script must be specified.") << endl;
1224 usage(1);
1225 }
1226 }
1227
1228 #if ! HAVE_NSS
1229 if (client_options)
1230 cerr << _("WARNING: --client-options is not supported by this version of systemtap") << endl;
1231
1232 if (! server_trust_spec.empty ())
1233 {
1234 cerr << _("WARNING: --trust-servers is not supported by this version of systemtap") << endl;
1235 server_trust_spec.clear ();
1236 }
1237 #endif
1238
1239 if (runtime_specified && ! specified_servers.empty ())
1240 {
1241 cerr << _("Warning: Ignoring --use-server due to the use of -R") << endl;
1242 specified_servers.clear ();
1243 }
1244
1245 if (client_options && last_pass > 4)
1246 {
1247 last_pass = 4; /* Quietly downgrade. Server passed through -p5 naively. */
1248 }
1249
1250 // If phase 5 has been requested, automatically adjust the --privilege setting to match the
1251 // user's actual privilege level and add --use-server, if necessary.
1252 // XXX Eventually we could check remote hosts, but disable that case for now.
1253 if (last_pass > 4 && have_script && remote_uris.empty())
1254 {
1255 // What is the user's privilege level?
1256 privilege_t credentials = get_privilege_credentials ();
1257 if (! pr_contains (credentials, privilege)) {
1258 {
1259 // We do not have the privilege credentials specified on the command line. Lower
1260 // the privilege level to match our credentials.
1261 if (pr_contains (credentials, pr_stapsys))
1262 {
1263 if (perpass_verbose[0] > 1)
1264 cerr << _("Using --privilege=stapsys for member of the group stapsys") << endl;
1265 privilege = pr_stapsys;
1266 server_args.push_back ("--privilege=stapsys");
1267 }
1268 else if (pr_contains (credentials, pr_stapusr))
1269 {
1270 if (perpass_verbose[0] > 1)
1271 cerr << _("Using --privilege=stapusr for member of the group stapusr") << endl;
1272 privilege = pr_stapusr;
1273 server_args.push_back ("--privilege=stapusr");
1274 }
1275 else
1276 {
1277 // Completely unprivileged user.
1278 cerr << _("You are trying to run systemtap as a normal user.\n"
1279 "You should either be root, or be part of "
1280 "the group \"stapusr\" and possibly one of the groups \"stapsys\" or \"stapdev\".\n");
1281 usage (1); // does not return.
1282 }
1283 }
1284 }
1285 // Add --use-server if not already specified and the user's (lack of) credentials require
1286 // it for pass 5.
1287 if (! pr_contains (credentials, pr_stapdev))
1288 {
1289 if (specified_servers.empty ())
1290 {
1291 if (perpass_verbose[0] > 1)
1292 cerr << _F("Using --use-server for user with privilege level %s",
1293 pr_name (privilege))
1294 << endl;
1295 specified_servers.push_back ("");
1296 }
1297 }
1298 }
1299
1300 if (client_options && ! pr_contains (privilege, pr_stapdev) && ! client_options_disallowed.empty ())
1301 {
1302 cerr << _F("You can't specify %s when --privilege=%s is specified.",
1303 client_options_disallowed.c_str(),
1304 pr_name (privilege))
1305 << endl;
1306 usage (1);
1307 }
1308 if ((cmd != "") && (target_pid))
1309 {
1310 cerr << _F("You can't specify %s and %s together.", "-c", "-x") << endl;
1311 usage (1);
1312 }
1313 if (! pr_contains (privilege, pr_stapdev) && guru_mode)
1314 {
1315 cerr << _F("You can't specify %s and --privilege=%s together.", "-g", pr_name (privilege))
1316 << endl;
1317 usage (1);
1318 }
1319 if (!kernel_symtab_path.empty())
1320 {
1321 if (consult_symtab)
1322 {
1323 cerr << _F("You can't specify %s and %s together.", "--kelf", "--kmap") << endl;
1324 usage (1);
1325 }
1326 consult_symtab = true;
1327 if (kernel_symtab_path == PATH_TBD)
1328 kernel_symtab_path = string("/boot/System.map-") + kernel_release;
1329 }
1330 // Can't use --remote and --tmpdir together because with --remote,
1331 // there may be more than one tmpdir needed.
1332 if (!remote_uris.empty() && tmpdir_opt_set)
1333 {
1334 cerr << _F("You can't specify %s and %s together.", "--remote", "--tmpdir") << endl;
1335 usage(1);
1336 }
1337 // Warn in case the target kernel release doesn't match the running one.
1338 native_build = (release == kernel_release &&
1339 machine == architecture); // NB: squashed ARCH by PR4186 logic
1340
1341 if (last_pass > 4 && !native_build)
1342 {
1343 if(! suppress_warnings)
1344 cerr << _("WARNING: kernel release/architecture mismatch with host forces last-pass 4.") << endl;
1345 last_pass = 4;
1346 }
1347 if(download_dbinfo != 0 && access ("/usr/bin/abrt-action-install-debuginfo-to-abrt-cache", X_OK) < 0)
1348 {
1349 if(! suppress_warnings)
1350 cerr << _("WARNING: abrt-action-install-debuginfo-to-abrt-cache is not installed. Continuing without downloading debuginfo.") << endl;
1351 download_dbinfo = 0;
1352 }
1353
1354 // translate path of runtime to absolute path
1355 if (runtime_path[0] != '/')
1356 {
1357 char cwd[PATH_MAX];
1358 if (getcwd(cwd, sizeof(cwd)))
1359 {
1360 runtime_path = string(cwd) + "/" + runtime_path;
1361 }
1362 }
1363
1364 // Abnormal characters in our temp path can break us, including parts out
1365 // of our control like Kbuild. Let's enforce nice, safe characters only.
1366 const char *tmpdir = getenv("TMPDIR");
1367 if (tmpdir != NULL)
1368 assert_regexp_match("TMPDIR", tmpdir, "^[-/._0-9a-z]+$");
1369 }
1370
1371
1372 void
1373 systemtap_session::init_try_server ()
1374 {
1375 #if HAVE_NSS
1376 // If the option is disabled or we are a server or we are already using a
1377 // server, then never retry compilation using a server.
1378 if (! use_server_on_error || client_options || ! specified_servers.empty ())
1379 try_server_status = dont_try_server;
1380 else
1381 try_server_status = try_server_unset;
1382 #else
1383 // No client, so don't bother.
1384 try_server_status = dont_try_server;
1385 #endif
1386 }
1387
1388 void
1389 systemtap_session::set_try_server (int t)
1390 {
1391 if (try_server_status != dont_try_server)
1392 try_server_status = t;
1393 }
1394
1395
1396 void systemtap_session::insert_loaded_modules()
1397 {
1398 char line[1024];
1399 ifstream procmods ("/proc/modules");
1400 while (procmods.good()) {
1401 procmods.getline (line, sizeof(line));
1402 strtok(line, " \t");
1403 if (line[0] == '\0')
1404 break; // maybe print a warning?
1405 unwindsym_modules.insert (string (line));
1406 }
1407 procmods.close();
1408 unwindsym_modules.insert ("kernel");
1409 }
1410
1411 void
1412 systemtap_session::setup_kernel_release (const char* kstr)
1413 {
1414 // Sometimes we may get dupes here... e.g. a server may have a full
1415 // -r /path/to/kernel followed by a client's -r kernel.
1416 if (kernel_release == kstr)
1417 return; // nothing new here...
1418
1419 kernel_release = kernel_build_tree = kernel_source_tree = "";
1420 if (kstr[0] == '/') // fully specified path
1421 {
1422 kernel_build_tree = kstr;
1423 kernel_release = kernel_release_from_build_tree (kernel_build_tree, verbose);
1424
1425 // PR10745
1426 // Maybe it's a full kernel source tree, for purposes of PR10745.
1427 // In case CONFIG_DEBUG_INFO was set, we'd find it anyway with the
1428 // normal search in tapsets.cxx. Without CONFIG_DEBUG_INFO, we'd
1429 // need heuristics such as this one:
1430
1431 string some_random_source_only_file = kernel_build_tree + "/COPYING";
1432 ifstream epic (some_random_source_only_file.c_str());
1433 if (! epic.fail())
1434 {
1435 kernel_source_tree = kernel_build_tree;
1436 if (verbose > 2)
1437 clog << _F("Located kernel source tree (COPYING) at '%s'", kernel_source_tree.c_str()) << endl;
1438 }
1439 }
1440 else
1441 {
1442 kernel_release = string (kstr);
1443 if (!kernel_release.empty())
1444 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
1445
1446 // PR10745
1447 // Let's not look for the kernel_source_tree; it's definitely
1448 // not THERE. tapsets.cxx might try to find it later if tracepoints
1449 // need it.
1450 }
1451 }
1452
1453
1454 // Register all the aliases we've seen in library files, and the user
1455 // file, as patterns.
1456 void
1457 systemtap_session::register_library_aliases()
1458 {
1459 vector<stapfile*> files(library_files);
1460 files.push_back(user_file);
1461
1462 for (unsigned f = 0; f < files.size(); ++f)
1463 {
1464 stapfile * file = files[f];
1465 for (unsigned a = 0; a < file->aliases.size(); ++a)
1466 {
1467 probe_alias * alias = file->aliases[a];
1468 try
1469 {
1470 for (unsigned n = 0; n < alias->alias_names.size(); ++n)
1471 {
1472 probe_point * name = alias->alias_names[n];
1473 match_node * mn = pattern_root;
1474 for (unsigned c = 0; c < name->components.size(); ++c)
1475 {
1476 probe_point::component * comp = name->components[c];
1477 // XXX: alias parameters
1478 if (comp->arg)
1479 throw semantic_error(_F("alias component %s contains illegal parameter",
1480 comp->functor.c_str()));
1481 mn = mn->bind(comp->functor);
1482 }
1483 // PR 12916: All probe aliases are OK for all users. The actual
1484 // referenced probe points will be checked when the alias is resolved.
1485 mn->bind_privilege (pr_all);
1486 mn->bind(new alias_expansion_builder(alias));
1487 }
1488 }
1489 catch (const semantic_error& e)
1490 {
1491 semantic_error* er = new semantic_error (e); // copy it
1492 stringstream msg;
1493 msg << e.msg2;
1494 msg << _(" while registering probe alias ");
1495 alias->printsig(msg);
1496 er->msg2 = msg.str();
1497 print_error (* er);
1498 delete er;
1499 }
1500 }
1501 }
1502 }
1503
1504
1505 // Print this given token, but abbreviate it if the last one had the
1506 // same file name.
1507 void
1508 systemtap_session::print_token (ostream& o, const token* tok)
1509 {
1510 assert (tok);
1511
1512 if (last_token && last_token->location.file == tok->location.file)
1513 {
1514 stringstream tmpo;
1515 tmpo << *tok;
1516 string ts = tmpo.str();
1517 // search & replace the file name with nothing
1518 size_t idx = ts.find (tok->location.file->name);
1519 if (idx != string::npos)
1520 ts.replace (idx, tok->location.file->name.size(), "");
1521
1522 o << ts;
1523 }
1524 else
1525 o << *tok;
1526
1527 last_token = tok;
1528 }
1529
1530
1531
1532 void
1533 systemtap_session::print_error (const semantic_error& e)
1534 {
1535 string message_str[2];
1536 string align_semantic_error (" ");
1537
1538 // We generate two messages. The second one ([1]) is printed
1539 // without token compression, for purposes of duplicate elimination.
1540 // This way, the same message that may be generated once with a
1541 // compressed and once with an uncompressed token still only gets
1542 // printed once.
1543 for (int i=0; i<2; i++)
1544 {
1545 stringstream message;
1546
1547 message << _F("semantic error: %s", e.what ());
1548 if (e.tok1 || e.tok2)
1549 message << ": ";
1550 if (e.tok1)
1551 {
1552 if (i == 0) print_token (message, e.tok1);
1553 else message << *e.tok1;
1554 }
1555 message << e.msg2;
1556 if (e.tok2)
1557 {
1558 if (i == 0) print_token (message, e.tok2);
1559 else message << *e.tok2;
1560 }
1561 message << endl;
1562 message_str[i] = message.str();
1563 }
1564
1565 // Duplicate elimination
1566 if (seen_errors.find (message_str[1]) == seen_errors.end())
1567 {
1568 seen_errors.insert (message_str[1]);
1569 cerr << message_str[0];
1570
1571 if (e.tok1)
1572 print_error_source (cerr, align_semantic_error, e.tok1);
1573
1574 if (e.tok2)
1575 print_error_source (cerr, align_semantic_error, e.tok2);
1576 }
1577
1578 if (e.chain)
1579 print_error (* e.chain);
1580 }
1581
1582 void
1583 systemtap_session::print_error_source (std::ostream& message,
1584 std::string& align, const token* tok)
1585 {
1586 unsigned i = 0;
1587
1588 assert (tok);
1589 if (!tok->location.file)
1590 //No source to print, silently exit
1591 return;
1592
1593 unsigned line = tok->location.line;
1594 unsigned col = tok->location.column;
1595 const string &file_contents = tok->location.file->file_contents;
1596
1597 size_t start_pos = 0, end_pos = 0;
1598 //Navigate to the appropriate line
1599 while (i != line && end_pos != std::string::npos)
1600 {
1601 start_pos = end_pos;
1602 end_pos = file_contents.find ('\n', start_pos) + 1;
1603 i++;
1604 }
1605 //TRANSLATORS: Here were are printing the source string of the error
1606 message << align << _("source: ") << file_contents.substr (start_pos, end_pos-start_pos-1) << endl;
1607 message << align << " ";
1608 //Navigate to the appropriate column
1609 for (i=start_pos; i<start_pos+col-1; i++)
1610 {
1611 if(isspace(file_contents[i]))
1612 message << file_contents[i];
1613 else
1614 message << ' ';
1615 }
1616 message << "^" << endl;
1617 }
1618
1619 void
1620 systemtap_session::print_warning (const string& message_str, const token* tok)
1621 {
1622 // Duplicate elimination
1623 string align_warning (" ");
1624 if (seen_warnings.find (message_str) == seen_warnings.end())
1625 {
1626 seen_warnings.insert (message_str);
1627 clog << _("WARNING: ") << message_str;
1628 if (tok) { clog << ": "; print_token (clog, tok); }
1629 clog << endl;
1630 if (tok) { print_error_source (clog, align_warning, tok); }
1631 }
1632 }
1633
1634
1635 translator_output* systemtap_session::op_create_auxiliary()
1636 {
1637 static int counter = 0;
1638 string tmpname = this->tmpdir + "/" + this->module_name + "_aux_" + lex_cast(counter++) + ".c";
1639 translator_output* n = new translator_output (tmpname);
1640 auxiliary_outputs.push_back (n);
1641 return n;
1642 }
1643
1644
1645
1646 // --------------------------------------------------------------------------
1647
1648 /*
1649 Perngrq sebz fzvyrlgnc.fit, rkcbegrq gb n 1484k1110 fzvyrlgnc.cat,
1650 gurapr catgbcnz | cazfpnyr -jvqgu 160 |
1651 cczqvgure -qvz 4 -erq 2 -terra 2 -oyhr 2 | cczgbnafv -2k4 | bq -i -j19 -g k1 |
1652 phg -s2- -q' ' | frq -r 'f,^,\\k,' -r 'f, ,\\k,t' -r 'f,^,",' -r 'f,$,",'
1653 */
1654 const char*
1655 systemtap_session::morehelp =
1656 "\x1b\x5b\x30\x6d\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1657 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1658 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1659 "\x20\x20\x20\x60\x20\x20\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1660 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20"
1661 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1662 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1663 "\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x1b\x5b"
1664 "\x33\x33\x6d\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1665 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1666 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1667 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x20\x60"
1668 "\x2e\x60\x1b\x5b\x33\x37\x6d\x20\x3a\x2c\x3a\x2e\x60\x20\x60\x20\x60\x20\x60"
1669 "\x2c\x3b\x2c\x3a\x20\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d"
1670 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
1671 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1672 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33"
1673 "\x33\x6d\x20\x60\x20\x60\x20\x3a\x27\x60\x1b\x5b\x33\x37\x6d\x20\x60\x60\x60"
1674 "\x20\x20\x20\x60\x20\x60\x60\x60\x20\x1b\x5b\x33\x33\x6d\x60\x3a\x60\x20\x60"
1675 "\x20\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1676 "\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1677 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1678 "\x20\x2e\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x20\x1b\x5b\x33"
1679 "\x37\x6d\x20\x3a\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x2e\x1b\x5b\x33\x33"
1680 "\x6d\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20"
1681 "\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x2e\x3a\x20\x20"
1682 "\x20\x20\x20\x20\x20\x20\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1683 "\x20\x20\x2e\x76\x53\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x1b\x5b"
1684 "\x33\x31\x6d\x2b\x1b\x5b\x33\x33\x6d\x60\x20\x60\x20\x60\x20\x20\x20\x20\x1b"
1685 "\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x33\x6d\x2b\x1b\x5b"
1686 "\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x2e\x1b\x5b\x33\x30\x6d\x24\x1b\x5b"
1687 "\x33\x37\x6d\x3b\x1b\x5b\x33\x31\x6d\x7c\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
1688 "\x20\x60\x20\x60\x1b\x5b\x33\x31\x6d\x2c\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33"
1689 "\x37\x6d\x53\x53\x3e\x2c\x2e\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x2e"
1690 "\x3b\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x20\x20\x20\x20\x20\x20"
1691 "\x20\x20\x20\x2e\x2e\x3a\x1b\x5b\x33\x30\x6d\x26\x46\x46\x46\x48\x46\x1b\x5b"
1692 "\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x30\x6d\x4d\x4d"
1693 "\x46\x1b\x5b\x33\x33\x6d\x20\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x1b\x5b"
1694 "\x33\x33\x6d\x20\x3a\x1b\x5b\x33\x30\x6d\x4d\x4d\x46\x1b\x5b\x33\x33\x6d\x20"
1695 "\x20\x20\x60\x20\x60\x2e\x60\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x30\x6d\x46"
1696 "\x46\x46\x24\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
1697 "\x20\x2e\x3c\x3a\x60\x20\x20\x20\x20\x2e\x3a\x2e\x3a\x2e\x2e\x3b\x27\x20\x20"
1698 "\x20\x20\x20\x20\x2e\x60\x2e\x3a\x60\x60\x3c\x27\x1b\x5b\x33\x31\x6d\x3c\x27"
1699 "\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x3c\x1b\x5b\x33"
1700 "\x30\x6d\x26\x1b\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x33\x6d\x20\x1b\x5b\x33\x37"
1701 "\x6d\x20\x1b\x5b\x33\x33\x6d\x20\x20\x20\x20\x20\x1b\x5b\x33\x37\x6d\x60\x1b"
1702 "\x5b\x33\x30\x6d\x2a\x46\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x20\x60"
1703 "\x20\x60\x20\x60\x20\x60\x20\x1b\x5b\x33\x31\x6d\x60\x3a\x1b\x5b\x33\x37\x6d"
1704 "\x27\x3c\x1b\x5b\x33\x30\x6d\x23\x1b\x5b\x33\x37\x6d\x3c\x60\x3a\x20\x20\x20"
1705 "\x0a\x20\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x20\x60\x3a\x2e\x2e\x2e\x2e\x3c"
1706 "\x3c\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x60\x20\x20\x20\x60\x1b\x5b\x33"
1707 "\x33\x6d\x3a\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x20"
1708 "\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x37\x6d\x20\x20\x1b\x5b\x33\x33\x6d"
1709 "\x20\x60\x20\x20\x20\x60\x1b\x5b\x33\x37\x6d\x20\x60\x20\x60\x1b\x5b\x33\x33"
1710 "\x6d\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
1711 "\x20\x60\x3a\x2e\x60\x2e\x20\x0a\x20\x20\x20\x60\x3a\x60\x3a\x60\x20\x20\x20"
1712 "\x20\x20\x60\x60\x60\x60\x20\x3a\x2d\x20\x20\x20\x20\x20\x60\x20\x60\x20\x20"
1713 "\x20\x20\x20\x60\x1b\x5b\x33\x33\x6d\x3a\x60\x2e\x60\x20\x60\x20\x60\x20\x60"
1714 "\x20\x60\x20\x20\x2e\x3b\x1b\x5b\x33\x31\x6d\x76\x1b\x5b\x33\x30\x6d\x24\x24"
1715 "\x24\x1b\x5b\x33\x31\x6d\x2b\x53\x1b\x5b\x33\x33\x6d\x2c\x60\x20\x60\x20\x60"
1716 "\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x3a"
1717 "\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x2e\x60\x20\x20\x0a\x20\x20\x20\x60"
1718 "\x3a\x3a\x3a\x3a\x20\x20\x20\x20\x3a\x60\x60\x60\x60\x3a\x53\x20\x20\x20\x20"
1719 "\x20\x20\x3a\x2e\x60\x2e\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
1720 "\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20\x60"
1721 "\x20\x3a\x1b\x5b\x33\x30\x6d\x24\x46\x46\x48\x46\x46\x46\x46\x46\x1b\x5b\x33"
1722 "\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2e"
1723 "\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
1724 "\x20\x2e\x60\x2e\x3a\x20\x20\x0a\x20\x20\x20\x60\x3a\x3a\x3a\x60\x20\x20\x20"
1725 "\x60\x3a\x20\x2e\x20\x3b\x27\x3a\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x20"
1726 "\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x60\x1b"
1727 "\x5b\x33\x33\x6d\x2e\x60\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x30\x6d\x53"
1728 "\x46\x46\x46\x53\x46\x46\x46\x53\x46\x46\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
1729 "\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x20"
1730 "\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x0a\x20\x20\x20\x20\x60\x3c\x3b\x3c\x20"
1731 "\x20\x20\x20\x20\x60\x60\x60\x20\x3a\x3a\x20\x20\x20\x20\x20\x20\x20\x3a\x3a"
1732 "\x2e\x60\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d"
1733 "\x3c\x3a\x60\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x30"
1734 "\x6d\x53\x46\x53\x46\x46\x46\x53\x46\x46\x46\x53\x1b\x5b\x33\x33\x6d\x2e\x60"
1735 "\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b"
1736 "\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x3a\x3a\x60\x20\x20\x20\x0a\x20\x20"
1737 "\x20\x20\x20\x60\x3b\x3c\x20\x20\x20\x20\x20\x20\x20\x3a\x3b\x60\x20\x20\x20"
1738 "\x20\x20\x20\x20\x20\x20\x60\x3a\x60\x2e\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33"
1739 "\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33"
1740 "\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x1b\x5b\x33\x31\x6d\x3a"
1741 "\x1b\x5b\x33\x30\x6d\x46\x53\x46\x53\x46\x53\x46\x53\x46\x1b\x5b\x33\x31\x6d"
1742 "\x3f\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x2e\x3a\x3a\x1b\x5b\x33\x31\x6d\x3c"
1743 "\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x60\x20"
1744 "\x20\x20\x3a\x3a\x3a\x60\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x53\x3c"
1745 "\x20\x20\x20\x20\x20\x20\x3a\x53\x3a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1746 "\x20\x60\x3a\x3a\x60\x2e\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
1747 "\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a"
1748 "\x60\x2e\x60\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x53\x24\x53\x46\x53\x24\x1b\x5b"
1749 "\x33\x33\x6d\x60\x3a\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
1750 "\x33\x31\x6d\x3a\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b"
1751 "\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x2e\x60\x3a\x3a\x60\x20"
1752 "\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x3b\x3c\x2e\x2e\x2c\x2e\x2e\x20"
1753 "\x3a\x3c\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a"
1754 "\x60\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31"
1755 "\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33"
1756 "\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3c\x1b\x5b\x33\x30\x6d\x53\x24\x53\x1b"
1757 "\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x2e\x3a\x3b"
1758 "\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x31\x6d"
1759 "\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x20\x60\x2e\x3a"
1760 "\x3a\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x2e\x3a\x3a\x3c\x53\x3c\x3a\x60"
1761 "\x3a\x3a\x3a\x3a\x53\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33\x37\x6d\x3b\x27\x3a"
1762 "\x3c\x2c\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a\x3a\x2e\x60"
1763 "\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
1764 "\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b"
1765 "\x33\x31\x6d\x3c\x2c\x1b\x5b\x33\x33\x6d\x3c\x3b\x3a\x1b\x5b\x33\x31\x6d\x2c"
1766 "\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x53"
1767 "\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x3c\x1b\x5b\x33\x37\x6d\x3a"
1768 "\x60\x2e\x60\x2e\x3b\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x3f\x27"
1769 "\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x3a\x3c\x53\x53\x3b\x3c"
1770 "\x3a\x60\x3a\x3a\x53\x53\x53\x3c\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x1b\x5b"
1771 "\x33\x37\x6d\x2b\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x3a\x1b\x5b\x33\x34"
1772 "\x6d\x53\x1b\x5b\x33\x30\x6d\x53\x46\x24\x1b\x5b\x33\x37\x6d\x2c\x60\x3a\x3a"
1773 "\x3a\x3c\x3a\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33"
1774 "\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31"
1775 "\x6d\x53\x3b\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33"
1776 "\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37"
1777 "\x6d\x3c\x53\x3c\x3a\x3a\x3a\x3a\x3f\x1b\x5b\x33\x30\x6d\x53\x24\x48\x1b\x5b"
1778 "\x33\x37\x6d\x27\x60\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x2e"
1779 "\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x1b\x5b\x33"
1780 "\x30\x6d\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20"
1781 "\x60\x3a\x1b\x5b\x33\x30\x6d\x3c\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60"
1782 "\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3c\x3a\x60\x3a\x27\x3a\x60\x3a\x60\x3a"
1783 "\x60\x3a\x60\x3b\x1b\x5b\x33\x30\x6d\x53\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27"
1784 "\x20\x60\x20\x60\x20\x60\x20\x20\x20\x20\x0a\x20\x3c\x3b\x3a\x2e\x60\x20\x60"
1785 "\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2c\x53\x1b\x5b\x33\x32\x6d\x53\x1b"
1786 "\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1787 "\x20\x20\x60\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x46\x46\x1b\x5b\x33\x34\x6d"
1788 "\x2b\x1b\x5b\x33\x37\x6d\x3a\x20\x60\x20\x60\x20\x60\x2e\x60\x20\x60\x2e\x60"
1789 "\x20\x60\x2e\x60\x20\x60\x20\x60\x2c\x1b\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b"
1790 "\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x20"
1791 "\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3b\x3c"
1792 "\x2c\x60\x2c\x3b\x3b\x53\x3f\x53\x1b\x5b\x33\x30\x6d\x24\x46\x3c\x1b\x5b\x33"
1793 "\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x60"
1794 "\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60\x20"
1795 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x3b\x76\x1b\x5b\x33\x30\x6d"
1796 "\x48\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20"
1797 "\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x24\x1b"
1798 "\x5b\x33\x37\x6d\x53\x53\x53\x53\x53\x53\x1b\x5b\x33\x30\x6d\x53\x24\x53\x46"
1799 "\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1800 "\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x23\x46\x46\x46"
1801 "\x24\x1b\x5b\x33\x37\x6d\x76\x2c\x2c\x20\x2e\x20\x2e\x20\x2c\x2c\x76\x1b\x5b"
1802 "\x33\x30\x6d\x26\x24\x46\x46\x48\x3c\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20"
1803 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x60"
1804 "\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x46\x24\x46\x24\x46\x46\x48\x46\x53\x1b\x5b"
1805 "\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x2e\x60\x20\x60\x2e\x60\x2e\x60"
1806 "\x2e\x60\x2e\x60\x3a\x3a\x3a\x3a\x3a\x1b\x5b\x33\x30\x6d\x2a\x46\x46\x46\x48"
1807 "\x46\x48\x46\x48\x46\x46\x46\x48\x46\x48\x46\x48\x1b\x5b\x33\x37\x6d\x3c\x22"
1808 "\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x0a"
1809 "\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x48"
1810 "\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x20\x60\x2e\x60\x20\x60"
1811 "\x2e\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3a\x3a\x60\x3a\x3c\x3c"
1812 "\x1b\x5b\x33\x30\x6d\x3c\x46\x48\x46\x46\x46\x48\x46\x46\x46\x1b\x5b\x33\x37"
1813 "\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
1814 "\x60\x20\x60\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b"
1815 "\x33\x30\x6d\x2a\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x20\x20\x60\x20\x60"
1816 "\x2e\x60\x20\x60\x2e\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a"
1817 "\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x46\x46\x48\x46\x48\x46"
1818 "\x1b\x5b\x33\x37\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x3a\x60\x2e"
1819 "\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x20\x60\x0a\x20\x20\x20\x20\x20\x20\x20"
1820 "\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x1b\x5b\x33\x37\x6d"
1821 "\x2b\x60\x20\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2e\x60\x20"
1822 "\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x60\x2e\x60\x3b\x1b\x5b\x33\x30\x6d"
1823 "\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
1824 "\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x20\x20\x0a\x20"
1825 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22\x1b\x5b\x33\x30\x6d\x3c"
1826 "\x48\x46\x53\x1b\x5b\x33\x37\x6d\x2b\x3a\x20\x20\x20\x60\x20\x60\x20\x60\x20"
1827 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2c\x1b"
1828 "\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x60\x20\x60\x20"
1829 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60"
1830 "\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1831 "\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x48\x24\x46\x46\x1b\x5b\x33\x37\x6d\x3e\x2c"
1832 "\x2e\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x3b"
1833 "\x2c\x2c\x1b\x5b\x33\x30\x6d\x24\x53\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x22"
1834 "\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x20\x20"
1835 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20"
1836 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b\x33\x30\x6d\x2a\x3c\x48"
1837 "\x46\x46\x24\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3e\x3e\x3e\x3e\x3e\x53"
1838 "\x3e\x53\x1b\x5b\x33\x30\x6d\x24\x53\x24\x46\x24\x48\x46\x23\x1b\x5b\x33\x37"
1839 "\x6d\x27\x22\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1840 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20"
1841 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1842 "\x60\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x2a\x3c\x3c\x3c\x48\x46\x46\x46\x48\x46"
1843 "\x46\x46\x23\x3c\x1b\x5b\x33\x36\x6d\x3c\x1b\x5b\x33\x37\x6d\x3c\x27\x22\x22"
1844 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1845 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x1b"
1846 "\x5b\x30\x6d";
1847
1848 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.136767 seconds and 5 git commands to generate.