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