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