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