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