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