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