2 // Copyright (C) 2010-2017 Red Hat Inc.
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
12 #include "stapregex.h"
13 #include "elaborate.h"
14 #include "translate.h"
16 #include "coveragedb.h"
18 #include "setupdwfl.h"
19 #include "task_finder.h"
21 #include "rpm_finder.h"
24 #include "git_version.h"
26 #include "stringtable.h"
38 #include <sys/utsname.h>
39 #include <sys/resource.h>
40 #include <elfutils/libdwfl.h>
41 #include <elfutils/version.h>
57 /* getopt variables */
60 #define PATH_TBD string("__TBD__")
63 bool systemtap_session::NSPR_Initialized
= false;
66 systemtap_session::systemtap_session ():
67 // NB: pointer members must be manually initialized!
68 // NB: don't forget the copy constructor too!
69 runtime_mode(kernel_runtime
),
71 pattern_root(new match_node
),
75 need_tagged_dfa (false),
77 generic_kprobe_derived_probes(0),
78 hwbkpt_derived_probes(0),
79 perf_derived_probes(0),
80 uprobe_derived_probes(0),
81 utrace_derived_probes(0),
82 itrace_derived_probes(0),
83 task_finder_derived_probes(0),
84 timer_derived_probes(0),
85 netfilter_derived_probes(0),
86 profile_derived_probes(0),
87 mark_derived_probes(0),
88 tracepoint_derived_probes(0),
89 hrtimer_derived_probes(0),
90 procfs_derived_probes(0),
91 dynprobe_derived_probes(0),
92 python_derived_probes(0),
94 sym_kprobes_text_start (0),
95 sym_kprobes_text_end (0),
98 benchmark_sdt_loops(0),
99 benchmark_sdt_threads(0),
100 suppressed_warnings(0),
101 suppressed_errors(0),
103 target_namespaces_pid(0),
107 (void) uname (& buf
);
108 kernel_release
= string (buf
.release
);
109 release
= kernel_release
;
110 kernel_build_tree
= "/lib/modules/" + kernel_release
+ "/build";
111 architecture
= machine
= normalize_machine(buf
.machine
);
113 for (unsigned i
=0; i
<5; i
++) perpass_verbose
[i
]=0;
117 runtime_specified
= false;
118 include_arg_start
= -1;
123 suppress_warnings
= false;
124 panic_warnings
= false;
125 dump_mode
= systemtap_session::dump_none
;
126 dump_matched_pattern
= "";
128 #ifdef ENABLE_PROLOGUES
129 prologue_searching_mode
= prologue_searching_always
;
131 prologue_searching_mode
= prologue_searching_auto
;
136 module_name
= "stap_" + lex_cast(getpid());
137 stapconf_name
= "stapconf_" + lex_cast(getpid()) + ".h";
138 output_file
= ""; // -o FILE
139 tmpdir_opt_set
= false;
141 monitor_interval
= 1;
144 save_uprobes
= false;
145 modname_given
= false;
150 use_script_cache
= true;
151 poison_cache
= false;
152 tapset_compile_coverage
= false;
153 need_uprobes
= false;
155 need_symbols
= false;
159 skip_badvars
= false;
160 privilege
= pr_stapdev
;
161 privilege_set
= false;
162 compatible
= VERSION
; // XXX: perhaps also process GIT_SHAID if available?
163 unwindsym_ldd
= false;
164 client_options
= false;
166 auto_privilege_level_msg
= "";
167 auto_server_msgs
.clear ();
168 use_server_on_error
= false;
169 try_server_status
= try_server_unset
;
170 use_remote_prefix
= false;
171 systemtap_v_check
= false;
173 suppress_handler_errors
= false;
174 native_build
= true; // presumed
176 update_release_sysroot
= false;
177 suppress_time_limits
= false;
178 target_namespaces_pid
= 0;
179 color_mode
= color_auto
;
180 color_errors
= isatty(STDERR_FILENO
) // conditions for coloring when
181 && strcmp(getenv("TERM") ?: "notdumb", "dumb"); // on auto
182 interactive_mode
= false;
184 pass_1a_complete
= false;
187 // PR12443: put compiled-in / -I paths in front, to be preferred during
188 // tapset duplicate-file elimination
189 const char* s_p
= getenv ("SYSTEMTAP_TAPSET");
192 include_path
.push_back (s_p
);
196 include_path
.push_back (string(PKGDATADIR
) + "/tapset");
199 /* adding in the XDG_DATA_DIRS variable path,
200 * this searches in conjunction with SYSTEMTAP_TAPSET
201 * to locate stap scripts, either can be disabled if
202 * needed using env $PATH=/dev/null where $PATH is the
203 * path you want disabled
205 const char* s_p1
= getenv ("XDG_DATA_DIRS");
209 tokenize(s_p1
, dirs
, ":");
210 for(vector
<string
>::iterator i
= dirs
.begin(); i
!= dirs
.end(); ++i
)
212 include_path
.push_back(*i
+ "/systemtap/tapset");
216 const char* s_r
= getenv ("SYSTEMTAP_RUNTIME");
220 runtime_path
= string(PKGDATADIR
) + "/runtime";
222 const char* s_d
= getenv ("SYSTEMTAP_DIR");
226 data_path
= get_home_directory() + string("/.systemtap");
227 if (create_dir(data_path
.c_str()) == 1)
229 const char* e
= strerror (errno
);
230 print_warning("failed to create systemtap data directory \"" + data_path
+ "\" " + e
+ ", disabling cache support.");
231 use_cache
= use_script_cache
= false;
236 cache_path
= data_path
+ "/cache";
237 if (create_dir(cache_path
.c_str()) == 1)
239 const char* e
= strerror (errno
);
240 print_warning("failed to create cache directory (\" " + cache_path
+ " \") " + e
+ ", disabling cache support.");
241 use_cache
= use_script_cache
= false;
245 const char* s_tc
= getenv ("SYSTEMTAP_COVERAGE");
247 tapset_compile_coverage
= true;
249 const char* s_kr
= getenv ("SYSTEMTAP_RELEASE");
251 setup_kernel_release(s_kr
);
255 systemtap_session::systemtap_session (const systemtap_session
& other
,
258 // NB: pointer members must be manually initialized!
259 // NB: this needs to consider everything that the base ctor does,
260 // plus copying any wanted implicit fields (strings, vectors, etc.)
261 runtime_mode(other
.runtime_mode
),
263 pattern_root(new match_node
),
264 user_files (other
.user_files
),
268 need_tagged_dfa(other
.need_tagged_dfa
),
269 be_derived_probes(0),
270 generic_kprobe_derived_probes(0),
271 hwbkpt_derived_probes(0),
272 perf_derived_probes(0),
273 uprobe_derived_probes(0),
274 utrace_derived_probes(0),
275 itrace_derived_probes(0),
276 task_finder_derived_probes(0),
277 timer_derived_probes(0),
278 netfilter_derived_probes(0),
279 profile_derived_probes(0),
280 mark_derived_probes(0),
281 tracepoint_derived_probes(0),
282 hrtimer_derived_probes(0),
283 procfs_derived_probes(0),
284 dynprobe_derived_probes(0),
285 python_derived_probes(0),
287 sym_kprobes_text_start (0),
288 sym_kprobes_text_end (0),
291 benchmark_sdt_loops(other
.benchmark_sdt_loops
),
292 benchmark_sdt_threads(other
.benchmark_sdt_threads
),
293 suppressed_warnings(0),
294 suppressed_errors(0),
296 target_namespaces_pid(0),
299 release
= kernel_release
= kern
;
300 kernel_build_tree
= "/lib/modules/" + kernel_release
+ "/build";
301 kernel_extra_cflags
= other
.kernel_extra_cflags
;
302 architecture
= machine
= normalize_machine(arch
);
303 setup_kernel_release(kern
.c_str());
304 native_build
= false; // assumed; XXX: could be computed as in check_options()
306 // These are all copied in the same order as the default ctor did above.
308 copy(other
.perpass_verbose
, other
.perpass_verbose
+ 5, perpass_verbose
);
309 verbose
= other
.verbose
;
311 have_script
= other
.have_script
;
312 runtime_specified
= other
.runtime_specified
;
313 include_arg_start
= other
.include_arg_start
;
314 timing
= other
.timing
;
315 guru_mode
= other
.guru_mode
;
316 bulk_mode
= other
.bulk_mode
;
317 unoptimized
= other
.unoptimized
;
318 suppress_warnings
= other
.suppress_warnings
;
319 panic_warnings
= other
.panic_warnings
;
320 dump_mode
= other
.dump_mode
;
321 dump_matched_pattern
= other
.dump_matched_pattern
;
323 prologue_searching_mode
= other
.prologue_searching_mode
;
325 buffer_size
= other
.buffer_size
;
326 last_pass
= other
.last_pass
;
327 module_name
= other
.module_name
;
328 stapconf_name
= other
.stapconf_name
;
329 output_file
= other
.output_file
; // XXX how should multiple remotes work?
330 tmpdir_opt_set
= false;
331 monitor
= other
.monitor
;
332 monitor_interval
= other
.monitor_interval
;
333 save_module
= other
.save_module
;
334 save_uprobes
= other
.save_uprobes
;
335 modname_given
= other
.modname_given
;
336 keep_tmpdir
= other
.keep_tmpdir
;
338 target_pid
= other
.target_pid
; // XXX almost surely nonsense for multiremote
339 use_cache
= other
.use_cache
;
340 use_script_cache
= other
.use_script_cache
;
341 poison_cache
= other
.poison_cache
;
342 tapset_compile_coverage
= other
.tapset_compile_coverage
;
343 need_uprobes
= false;
345 need_symbols
= false;
348 load_only
= other
.load_only
;
349 skip_badvars
= other
.skip_badvars
;
350 privilege
= other
.privilege
;
351 privilege_set
= other
.privilege_set
;
352 compatible
= other
.compatible
;
353 unwindsym_ldd
= other
.unwindsym_ldd
;
354 client_options
= other
.client_options
;
356 use_server_on_error
= other
.use_server_on_error
;
357 try_server_status
= other
.try_server_status
;
358 use_remote_prefix
= other
.use_remote_prefix
;
359 systemtap_v_check
= other
.systemtap_v_check
;
360 download_dbinfo
= other
.download_dbinfo
;
361 suppress_handler_errors
= other
.suppress_handler_errors
;
362 sysroot
= other
.sysroot
;
363 update_release_sysroot
= other
.update_release_sysroot
;
364 sysenv
= other
.sysenv
;
365 suppress_time_limits
= other
.suppress_time_limits
;
366 color_errors
= other
.color_errors
;
367 color_mode
= other
.color_mode
;
368 interactive_mode
= other
.interactive_mode
;
369 run_example
= other
.run_example
;
370 pass_1a_complete
= other
.pass_1a_complete
;
371 timeout
= other
.timeout
;
373 include_path
= other
.include_path
;
374 runtime_path
= other
.runtime_path
;
376 // NB: assuming that "other" created these already
377 data_path
= other
.data_path
;
378 cache_path
= other
.cache_path
;
380 tapset_compile_coverage
= other
.tapset_compile_coverage
;
383 // These are fields that were left to their default ctor, but now we want to
384 // copy them from "other". In the same order as declared...
385 script_file
= other
.script_file
;
386 cmdline_script
= other
.cmdline_script
;
387 additional_scripts
= other
.additional_scripts
;
388 stdin_script
.str() = other
.stdin_script
.str();
389 c_macros
= other
.c_macros
;
391 kbuildflags
= other
.kbuildflags
;
393 globalopts
= other
.globalopts
;
394 modinfos
= other
.modinfos
;
396 client_options_disallowed_for_unprivileged
= other
.client_options_disallowed_for_unprivileged
;
397 server_status_strings
= other
.server_status_strings
;
398 specified_servers
= other
.specified_servers
;
399 server_trust_spec
= other
.server_trust_spec
;
400 server_args
= other
.server_args
;
401 mok_fingerprints
= other
.mok_fingerprints
;
403 // HTTP client/server
404 http_servers
= other
.http_servers
;
406 unwindsym_modules
= other
.unwindsym_modules
;
407 auto_privilege_level_msg
= other
.auto_privilege_level_msg
;
408 auto_server_msgs
= other
.auto_server_msgs
;
413 systemtap_session::~systemtap_session ()
416 delete_map(subsessions
);
421 systemtap_session::module_filename() const
424 switch (runtime_mode
)
429 case dyninst_runtime
:
438 return module_name
+ suffix
;
443 systemtap_session::NSPR_init ()
445 if (! NSPR_Initialized
)
447 PR_Init (PR_SYSTEM_THREAD
, PR_PRIORITY_NORMAL
, 1);
448 NSPR_Initialized
= true;
454 systemtap_session::clone(const string
& arch
, const string
& release
)
456 const string norm_arch
= normalize_machine(arch
);
457 if (this->architecture
== norm_arch
&& this->kernel_release
== release
)
460 systemtap_session
*& s
= subsessions
[make_pair(norm_arch
, release
)];
462 s
= new systemtap_session(*this, norm_arch
, release
);
468 systemtap_session::version_string ()
470 string elfutils_version1
;
471 #ifdef _ELFUTILS_VERSION
472 elfutils_version1
= "0." + lex_cast(_ELFUTILS_VERSION
); /* BUILD */
474 string elfutils_version2
= dwfl_version(NULL
); /* RUN */
476 if (elfutils_version1
!= elfutils_version2
)
477 elfutils_version2
+= string("/") + elfutils_version1
; /* RUN/BUILD */
479 return string (VERSION
) + "/" + elfutils_version2
+ ", " + STAP_EXTENDED_VERSION
;
483 systemtap_session::version ()
486 cout
<< _F("Systemtap translator/driver (version %s)\n"
487 "Copyright (C) 2005-2018 Red Hat, Inc. and others\n"
488 "This is free software; see the source for copying conditions.\n",
489 version_string().c_str());
491 cout
<< _F("tested kernel versions: %s ... %s\n", "2.6.18", "4.16");
493 cout
<< _("enabled features:")
497 #ifdef HAVE_BOOST_UTILITY_STRING_REF_HPP
498 << " BOOST_STRING_REF"
503 #ifdef HAVE_BPF_DECLS
509 #ifdef HAVE_PYTHON2_PROBES
512 #ifdef HAVE_PYTHON3_PROBES
518 #ifdef HAVE_LIBSQLITE3
533 #ifdef ENABLE_PROLOGUES
536 #ifdef HAVE_LIBREADLINE
543 systemtap_session::usage (int exitcode
)
545 // For error cases, just suggest --help, so we don't obscure
546 // the actual error message with all the help text.
547 if (exitcode
!= EXIT_SUCCESS
)
549 clog
<< _("Try '--help' for more information.") << endl
;
550 throw exit_exception(exitcode
);
557 "Usage: stap [options] FILE Run script in file.\n"
558 " or: stap [options] - Run script on stdin.\n"
559 " or: stap [options] -e SCRIPT Run given script.\n"
560 " or: stap [options] -l PROBE List matching probes.\n"
561 " or: stap [options] -L PROBE List matching probes and local variables.\n"
562 " or: stap [options] --dump-probe-types List available probe types.\n"
563 " or: stap [options] --dump-probe-aliases List available probe aliases.\n"
564 " or: stap [options] --dump-functions List available functions.\n\n"
565 "Options (in %s/rc and on command line):\n"
566 " -- end of translator options, script options follow\n"
567 " -h --help show help\n"
570 " -p NUM stop after pass NUM 1-5, instead of %d\n"
571 " (parse, elaborate, translate, compile, run)\n"
572 " -v add verbosity to all passes\n"
573 " --vp {N}+ add per-pass verbosity [", data_path
.c_str(), last_pass
);
574 for (unsigned i
=0; i
<5; i
++)
575 cout
<< (perpass_verbose
[i
] <= 9 ? perpass_verbose
[i
] : 9);
578 cout
<< _F(" -k keep temporary directory\n"
579 " -u unoptimized translation %s\n"
580 " -w suppress warnings %s\n"
581 " -W turn warnings into errors %s\n"
583 " -P prologue-searching for function probes %s\n"
584 " -b bulk (percpu file) mode %s\n"
585 #ifdef HAVE_LIBREADLINE
586 " -i --interactive\n"
587 " interactive mode %s\n"
589 " -s NUM buffer size in megabytes, instead of %d\n"
590 " -I DIR look in DIR for additional .stp script files", (unoptimized
? _(" [set]") : ""),
591 (suppress_warnings
? _(" [set]") : ""), (panic_warnings
? _(" [set]") : ""),
592 (guru_mode
? _(" [set]") : ""), (prologue_searching_mode
== prologue_searching_always
? _(" [set]") : ""),
593 (bulk_mode
? _(" [set]") : ""),
594 #ifdef HAVE_LIBREADLINE
595 (interactive_mode
? _(" [set]") : ""),
598 if (include_path
.size() == 0)
601 cout
<< _(", in addition to") << endl
;
602 for (unsigned i
=0; i
<include_path
.size(); i
++)
603 cout
<< " " << include_path
[i
].c_str() << endl
;
605 << _F(" -D NM=VAL emit macro definition into generated C code\n"
606 " -B NM=VAL pass option to kbuild make\n"
607 " --modinfo NM=VAL\n"
608 " include a MODULE_INFO(NM,VAL) in the generated C code\n"
609 " -G VAR=VAL set global variable to value\n"
610 //TRANSLATORS: translating 'runtime' is not advised
611 " -R DIR look in DIR for runtime, instead of\n"
613 " -r DIR cross-compile to kernel with given build tree; or else\n"
614 " -r RELEASE cross-compile to kernel /lib/modules/RELEASE/build, instead of\n"
616 " -a ARCH cross-compile to given architecture, instead of %s\n"
617 " -m MODULE set probe module name, instead of \n"
619 " -o FILE send script output to file, instead of stdout. This supports\n"
620 " strftime(3) formats for FILE\n"
621 " -E SCRIPT run the SCRIPT in addition to the main script specified\n"
622 " through -e or a script file\n"
623 " -c CMD start the probes, run CMD, and exit when it finishes\n"
624 " -x PID sets target() to PID\n"
625 " -F run as on-file flight recorder with -o.\n"
626 " run as on-memory flight recorder without -o.\n"
627 " -S size[,n] set maximum of the size and the number of files.\n"
628 " -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());
629 if (unwindsym_modules
.size() == 0)
632 cout
<< _(", in addition to") << endl
;
634 vector
<string
> syms (unwindsym_modules
.begin(), unwindsym_modules
.end());
635 for (unsigned i
=0; i
<syms
.size(); i
++)
636 cout
<< " " << syms
[i
].c_str() << endl
;
639 << _F(" --ldd add unwind/symbol data for referenced user-space objects.\n"
641 " add unwind/symbol data for all loaded kernel objects.\n"
642 " -t collect probe timing information\n"
643 " -T TIME terminate the script after TIME seconds\n"
644 #ifdef HAVE_LIBSQLITE3
645 " -q generate information on tapset coverage\n"
646 #endif /* HAVE_LIBSQLITE3 */
648 " set the pass-5 runtime mode, instead of kernel\n"
651 " shorthand for --runtime=dyninst\n"
652 #endif /* HAVE_DYNINST */
653 #ifdef HAVE_BPF_DECLS
655 " shorthand for --runtime=bpf\n"
656 #endif /* HAVE_BPF_DECLS */
657 " --prologue-searching[=WHEN]\n"
658 " prologue-searching for function probes\n"
659 " --privilege=PRIVILEGE_LEVEL\n"
660 " check the script for constructs not allowed at the given privilege level\n"
662 " equivalent to --privilege=stapusr\n"
663 " --compatible=VERSION\n"
664 " suppress incompatible language/tapset changes beyond VERSION,\n"
667 " displays warnings where a syntax element may be \n"
668 " version dependent\n"
670 " substitute zero for bad context $variables\n"
671 " --suppress-handler-errors\n"
672 " catch all runtime errors, quietly skip probe handlers\n"
673 " --use-server[=SERVER-SPEC]\n"
674 " specify systemtap compile-servers\n"
675 " --list-servers[=PROPERTIES]\n"
676 " report on the status of the specified compile-servers:\n"
677 " all,specified,online,trusted,signer,compatible\n"
679 " --trust-servers[=TRUST-SPEC]\n"
680 " add/revoke trust of specified compile-servers:\n"
681 " ssl,signer,all-users,revoke,no-prompt\n"
682 " --use-server-on-error[=yes/no]\n"
683 " retry compilation using a compile server upon compilation error\n"
685 #ifdef HAVE_HTTP_SUPPORT
686 " --use-http-server=SERVER-SPEC\n"
687 " specify systemtap http compile server\n"
689 " --remote=HOSTNAME\n"
690 " run pass 5 on the specified ssh host.\n"
691 " may be repeated for targeting multiple hosts.\n"
693 " prefix each line of remote output with a host index.\n"
695 " specify name of temporary directory to be used.\n"
696 " --download-debuginfo[=OPTION]\n"
697 " automatically download debuginfo using ABRT.\n"
698 " yes,no,ask,<timeout value>\n"
699 " --dump-probe-types\n"
700 " show a list of available probe types.\n"
702 " specify sysroot directory where target files (executables,\n" " libraries, etc.) are located.\n"
703 " --sysenv=VAR=VALUE\n"
704 " provide an alternate value for an environment variable\n"
705 " where the value on a remote system differs. Path\n"
706 " variables (e.g. PATH, LD_LIBRARY_PATH) are assumed to be\n"
707 " relative to the sysroot.\n"
708 " --suppress-time-limits\n"
709 " disable -DSTP_OVERLOAD, -DMAXACTION, and -DMAXTRYACTION limits\n"
711 " save uprobes.ko to current directory if it is built from source\n"
712 " --target-namesapce=PID\n"
713 " sets the target namespaces pid to PID\n"
714 #if HAVE_MONITOR_LIBS
715 " --monitor=INTERVAL\n"
716 " enables monitor interfaces\n"
718 , compatible
.c_str()) << endl
723 struct tm
* t
= localtime (& now
);
724 if (t
&& t
->tm_mon
*3 + t
->tm_mday
*173 == 0xb6)
725 cout
<< morehelp
<< endl
;
727 throw exit_exception (exitcode
);
731 systemtap_session::parse_cmdline (int argc
, char * const argv
[])
733 client_options_disallowed_for_unprivileged
= "";
734 std::set
<std::string
> additional_unwindsym_modules
;
735 struct rlimit our_rlimit
;
736 bool sysroot_option_seen
= false;
737 string kernel_release_value
;
742 int grc
= getopt_long (argc
, argv
, STAP_SHORT_OPTIONS
, stap_long_options
, NULL
);
744 // NB: when adding new options, consider very carefully whether they
745 // should be restricted from stap clients (after --client-options)!
753 throw exit_exception (EXIT_SUCCESS
);
756 server_args
.push_back (string ("-") + (char)grc
);
757 for (unsigned i
=0; i
<5; i
++)
758 perpass_verbose
[i
] ++;
763 // Make sure the global option is only composed of the
764 // following chars: [_=a-zA-Z0-9.-]
766 assert_regexp_match("-G parameter", optarg
, "^[a-z_][a-z0-9_]*=[a-z0-9_.-]+$");
767 globalopts
.push_back (string(optarg
));
771 server_args
.push_back (string ("-") + (char)grc
);
776 server_args
.push_back (string ("-") + (char)grc
);
777 suppress_warnings
= true;
781 server_args
.push_back (string ("-") + (char)grc
);
782 panic_warnings
= true;
787 last_pass
= (int)strtoul(optarg
, &num_endptr
, 10);
788 if (*num_endptr
!= '\0' || last_pass
< 1 || last_pass
> 5)
790 cerr
<< _("Invalid pass number (should be 1-5).") << endl
;
793 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
799 client_options_disallowed_for_unprivileged
+= client_options_disallowed_for_unprivileged
.empty () ? "-I" : ", -I";
800 if (include_arg_start
== -1)
801 include_arg_start
= include_path
.size ();
802 include_path
.push_back (string (optarg
));
807 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
809 // Make sure an empty data object wasn't specified (-d "")
810 if (strlen (optarg
) == 0)
812 cerr
<< _("Data object (-d) cannot be empty.") << endl
;
815 // At runtime user module names are resolved through their
816 // canonical (absolute) path, or else it's a kernel module name.
817 // The sysroot option might change the path to a user module.
818 additional_unwindsym_modules
.insert (resolve_path (optarg
));
819 // NB: we used to enable_vma_tracker() here for PR10228, but now
820 // we'll leave that to pragma:vma functions which actually use it.
828 cerr
<< _("Only one script can be given on the command line.")
832 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
833 cmdline_script
= string (optarg
);
839 server_args
.push_back (string("-") + (char)grc
+ optarg
);
840 additional_scripts
.push_back(string (optarg
));
841 // don't set have_script to true, since this script is meant to be
842 // given in addition to a script/script_file.
847 // NB: client_options not a problem, since pass 1-4 does not use output_file.
848 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
849 output_file
= string (optarg
);
854 if (client_options
) { cerr
<< _F("ERROR: %s invalid with %s", "-R", "--client-options") << endl
; return 1; }
855 runtime_specified
= true;
856 runtime_path
= string (optarg
);
862 client_options_disallowed_for_unprivileged
+= client_options_disallowed_for_unprivileged
.empty () ? "-m" : ", -m";
863 module_name
= string (optarg
);
865 modname_given
= true;
867 // If the module name ends with '.ko', chop it off since
868 // modutils doesn't like modules named 'foo.ko.ko'.
869 if (endswith(module_name
, ".ko") || endswith(module_name
, ".so"))
871 module_name
.erase(module_name
.size() - 3);
872 cerr
<< _F("Truncating module name to '%s'", module_name
.c_str()) << endl
;
875 // Make sure an empty module name wasn't specified (-m "")
876 if (module_name
.empty())
878 cerr
<< _("Module name cannot be empty.") << endl
;
882 // Make sure the module name is only composed of the
883 // following chars: [a-z0-9_]
884 assert_regexp_match("-m parameter", module_name
, "^[a-z0-9_]+$");
886 // Make sure module name isn't too long.
887 if (module_name
.size() >= (MODULE_NAME_LEN
- 1))
889 module_name
.resize(MODULE_NAME_LEN
- 1);
890 cerr
<< _F("Truncating module name to '%s'", module_name
.c_str()) << endl
;
894 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
895 use_script_cache
= false;
900 if (client_options
) // NB: no paths!
901 // Note that '-' must come last in a regex bracket expression.
902 assert_regexp_match("-r parameter from client", optarg
, "^[a-z0-9_.+-]+$");
903 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
904 kernel_release_value
= optarg
;
909 assert_regexp_match("-a parameter", optarg
, "^[a-z0-9_-]+$");
910 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
911 architecture
= string(optarg
);
915 if (client_options
) { cerr
<< _F("ERROR: %s invalid with %s", "-k", "--client-options") << endl
; return 1; }
917 use_script_cache
= false; /* User wants to keep a usable build tree. */
921 server_args
.push_back (string ("-") + (char)grc
);
926 case LONG_OPT_INTERACTIVE
:
927 #ifdef HAVE_LIBREADLINE
928 if (client_options
) { cerr
<< _F("ERROR: %s invalid with %s", "-i", "--client-options") << endl
; return 1; }
929 interactive_mode
= true;
934 server_args
.push_back (string ("-") + (char)grc
);
935 prologue_searching_mode
= prologue_searching_always
;
939 server_args
.push_back (string ("-") + (char)grc
);
944 server_args
.push_back (string ("-") + (char)grc
);
950 buffer_size
= (int) strtoul (optarg
, &num_endptr
, 10);
951 if (*num_endptr
!= '\0' || buffer_size
< 1 || buffer_size
> 4095)
953 cerr
<< _("Invalid buffer size (should be 1-4095).") << endl
;
956 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
961 cmd
= string (optarg
);
964 // This would mess with later code deciding to pass -c
965 // through to staprun
966 cerr
<< _("Empty CMD string invalid.") << endl
;
969 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
974 target_pid
= (int) strtoul(optarg
, &num_endptr
, 10);
975 if (*num_endptr
!= '\0')
977 cerr
<< _("Invalid target process ID number.") << endl
;
980 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
985 assert_regexp_match ("-D parameter", optarg
, "^[a-z_][a-z_0-9]*(=-?[a-z_0-9]+)?$");
987 client_options_disallowed_for_unprivileged
+= client_options_disallowed_for_unprivileged
.empty () ? "-D" : ", -D";
988 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
989 c_macros
.push_back (string (optarg
));
994 assert_regexp_match ("-S parameter", optarg
, "^[0-9]+(,[0-9]+)?$");
995 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
996 size_option
= string (optarg
);
1001 timeout
= (int) 1000*strtod(optarg
, &num_endptr
); // convert to ms
1002 if (*num_endptr
!= '\0' || timeout
< 1)
1004 cerr
<< _("Invalid timeout interval.") << endl
;
1010 if (client_options
) { cerr
<< _F("ERROR: %s invalid with %s", "-q", "--client-options") << endl
; return 1; }
1011 server_args
.push_back (string ("-") + (char)grc
);
1012 tapset_compile_coverage
= true;
1022 cerr
<< _("ERROR: only one of the -l/-L/--dump-* "
1023 "switches may be specified") << endl
;
1027 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
1028 dump_mode
= systemtap_session::dump_matched_probes_vars
;
1029 dump_matched_pattern
= optarg
;
1030 unoptimized
= true; // This causes retention of vars for listing
1031 suppress_warnings
= true;
1037 cerr
<< _("ERROR: only one of the -l/-L/--dump-* "
1038 "switches may be specified") << endl
;
1042 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
1043 dump_mode
= systemtap_session::dump_matched_probes
;
1044 dump_matched_pattern
= optarg
;
1045 suppress_warnings
= true;
1049 server_args
.push_back (string ("-") + (char)grc
);
1054 if (client_options
) { cerr
<< _F("ERROR: %s invalid with %s", "-B", "--client-options") << endl
; return 1; }
1056 server_args
.push_back (string ("-") + (char)grc
+ optarg
);
1057 kbuildflags
.push_back (string (optarg
));
1060 case LONG_OPT_VERSION
:
1062 throw exit_exception (EXIT_SUCCESS
);
1064 case LONG_OPT_VERBOSE_PASS
:
1068 if (strlen(optarg
) < 1 || strlen(optarg
) > 5)
1072 for (unsigned i
=0; i
<strlen(optarg
); i
++)
1073 if (isdigit (optarg
[i
]))
1074 perpass_verbose
[i
] += optarg
[i
]-'0';
1080 cerr
<< _("Invalid --vp argument: it takes 1 to 5 digits.") << endl
;
1083 // NB: we don't do this: last_pass = strlen(optarg);
1084 server_args
.push_back ("--vp=" + string(optarg
));
1088 case LONG_OPT_SKIP_BADVARS
:
1089 server_args
.push_back ("--skip-badvars");
1090 skip_badvars
= true;
1093 case LONG_OPT_PRIVILEGE
:
1095 // We allow only multiple privilege-setting options if they all specify the same
1096 // privilege level. The server also expects and depends on this behaviour when
1097 // examining the client-side options passed to it.
1098 privilege_t newPrivilege
;
1100 if (strcmp (optarg
, "stapdev") == 0)
1101 newPrivilege
= pr_stapdev
;
1102 else if (strcmp (optarg
, "stapsys") == 0)
1103 newPrivilege
= pr_stapsys
;
1104 else if (strcmp (optarg
, "stapusr") == 0)
1105 newPrivilege
= pr_stapusr
;
1108 cerr
<< _F("Invalid argument '%s' for --privilege.", optarg
) << endl
;
1111 if (privilege_set
&& newPrivilege
!= privilege
)
1113 cerr
<< _("Privilege level may be set only once.") << endl
;
1116 privilege
= newPrivilege
;
1117 privilege_set
= true;
1118 server_args
.push_back ("--privilege=" + string(optarg
));
1120 /* NB: for server security, it is essential that once this flag is
1121 set, no future flag be able to unset it. */
1124 case LONG_OPT_UNPRIVILEGED
:
1125 // We allow only multiple privilege-setting options if they all specify the same
1126 // privilege level. The server also expects and depends on this behaviour when
1127 // examining the client-side options passed to it.
1128 if (privilege_set
&& pr_unprivileged
!= privilege
)
1130 cerr
<< _("Privilege level may be set only once.") << endl
;
1133 privilege
= pr_unprivileged
;
1134 privilege_set
= true;
1135 server_args
.push_back ("--unprivileged");
1136 /* NB: for server security, it is essential that once this flag is
1137 set, no future flag be able to unset it. */
1140 case LONG_OPT_CLIENT_OPTIONS
:
1141 client_options
= true;
1144 case LONG_OPT_TMPDIR
:
1145 if (client_options
) {
1146 cerr
<< _F("ERROR: %s is invalid with %s", "--tmpdir", "--client-options") << endl
;
1149 tmpdir_opt_set
= true;
1153 case LONG_OPT_DOWNLOAD_DEBUGINFO
:
1156 if(strcmp(optarg
, "no") == 0)
1157 download_dbinfo
= 0; //Disable feature
1158 else if (strcmp(optarg
, "yes") == 0)
1159 download_dbinfo
= INT_MAX
; //Enable, No Timeout
1160 /* NOTE: Timeout and Asking for Confirmation features below are not supported yet by abrt
1161 * in version abrt-2.0.3-1.fc15.x86_64, Bugzilla: BZ730107 (timeout), BZ726192 ('-y') */
1162 else if(atoi(optarg
) > 0)
1163 download_dbinfo
= atoi(optarg
); //Enable, Set timeout to optarg
1164 else if (strcmp(optarg
, "ask") == 0)
1165 download_dbinfo
= -1; //Enable, Ask for confirmation
1168 cerr
<< _F("ERROR: %s is not a valid value. Use 'yes', 'no', 'ask' or a timeout value.", optarg
) << endl
;
1173 download_dbinfo
= INT_MAX
; //Enable, No Timeout
1176 case LONG_OPT_USE_SERVER
:
1177 if (client_options
) {
1178 cerr
<< _F("ERROR: %s is invalid with %s", "--use-server", "--client-options") << endl
;
1182 specified_servers
.push_back (optarg
);
1184 specified_servers
.push_back ("");
1187 case LONG_OPT_USE_SERVER_ON_ERROR
:
1188 if (client_options
) {
1189 cerr
<< _F("ERROR: %s is invalid with %s", "--use-server-on-error", "--client-options") << endl
;
1194 string arg
= optarg
;
1195 for (unsigned i
= 0; i
< arg
.size (); ++i
)
1196 arg
[i
] = tolower (arg
[i
]);
1197 if (arg
== "yes" || arg
== "ye" || arg
== "y")
1198 use_server_on_error
= true;
1199 else if (arg
== "no" || arg
== "n")
1200 use_server_on_error
= false;
1202 cerr
<< _F("Invalid argument '%s' for --use-server-on-error.", optarg
) << endl
;
1205 use_server_on_error
= true;
1208 case LONG_OPT_LIST_SERVERS
:
1209 if (client_options
) {
1210 cerr
<< _F("ERROR: %s is invalid with %s", "--list-servers", "--client-options") << endl
;
1214 server_status_strings
.push_back (optarg
);
1216 server_status_strings
.push_back ("");
1219 case LONG_OPT_TRUST_SERVERS
:
1220 if (client_options
) {
1221 cerr
<< _F("ERROR: %s is invalid with %s", "--trust-servers", "--client-options") << endl
;
1225 server_trust_spec
= optarg
;
1227 server_trust_spec
= "ssl";
1231 #ifdef HAVE_HTTP_SUPPORT
1232 case LONG_OPT_USE_HTTP_SERVER
:
1233 if (client_options
) {
1234 cerr
<< _F("ERROR: %s is invalid with %s", "--use-http-server", "--client-options") << endl
;
1237 http_servers
.push_back (optarg
);
1245 case LONG_OPT_RUN_EXAMPLE
:
1249 // The caching options should not be available to server clients
1250 case LONG_OPT_DISABLE_CACHE
:
1251 if (client_options
) {
1252 cerr
<< _F("ERROR: %s is invalid with %s", "--disable-cache", "--client-options") << endl
;
1255 use_cache
= use_script_cache
= false;
1258 case LONG_OPT_POISON_CACHE
:
1259 if (client_options
) {
1260 cerr
<< _F("ERROR: %s is invalid with %s", "--poison-cache", "--client-options") << endl
;
1263 poison_cache
= true;
1266 case LONG_OPT_CLEAN_CACHE
:
1267 if (client_options
) {
1268 cerr
<< _F("ERROR: %s is invalid with %s", "--clean-cache", "--client-options") << endl
;
1272 throw exit_exception(EXIT_SUCCESS
);
1274 case LONG_OPT_COMPATIBLE
:
1276 server_args
.push_back ("--compatible=" + string(optarg
));
1277 if (strverscmp(optarg
, VERSION
) > 0) {
1278 cerr
<< _F("ERROR: systemtap version %s cannot be compatible with future version %s", VERSION
, optarg
)
1282 compatible
= optarg
;
1286 if (client_options
) {
1287 cerr
<< _F("ERROR: %s is invalid with %s", "--ldd", "--client-options") << endl
;
1290 unwindsym_ldd
= true;
1293 case LONG_OPT_ALL_MODULES
:
1294 if (client_options
) {
1295 cerr
<< _F("ERROR: %s is invalid with %s", "--all-modules", "--client-options") << endl
;
1298 insert_loaded_modules();
1301 case LONG_OPT_REMOTE
:
1302 if (client_options
) {
1303 cerr
<< _F("ERROR: %s is invalid with %s", "--remote", "--client-options") << endl
;
1307 remote_uris
.push_back(optarg
);
1310 case LONG_OPT_REMOTE_PREFIX
:
1311 if (client_options
) {
1312 cerr
<< _F("ERROR: %s is invalid with %s", "--remote-prefix", "--client-options") << endl
;
1316 use_remote_prefix
= true;
1319 case LONG_OPT_CHECK_VERSION
:
1320 server_args
.push_back ("--check-version");
1321 systemtap_v_check
= true;
1324 case LONG_OPT_DUMP_PROBE_TYPES
:
1327 cerr
<< _("ERROR: only one of the -l/-L/--dump-* "
1328 "switches may be specified") << endl
;
1331 server_args
.push_back ("--dump-probe-types");
1332 dump_mode
= systemtap_session::dump_probe_types
;
1335 case LONG_OPT_DUMP_PROBE_ALIASES
:
1338 cerr
<< _("ERROR: only one of the -l/-L/--dump-* "
1339 "switches may be specified") << endl
;
1342 server_args
.push_back ("--dump-probe-aliases");
1343 suppress_warnings
= true;
1344 dump_mode
= systemtap_session::dump_probe_aliases
;
1347 case LONG_OPT_DUMP_FUNCTIONS
:
1350 cerr
<< _("ERROR: only one of the -l/-L/--dump-* "
1351 "switches may be specified") << endl
;
1354 server_args
.push_back ("--dump-functions");
1355 suppress_warnings
= true;
1356 dump_mode
= systemtap_session::dump_functions
;
1357 unoptimized
= true; // Keep unused functions (which is all of them)
1360 case LONG_OPT_SUPPRESS_HANDLER_ERRORS
:
1361 suppress_handler_errors
= true;
1362 c_macros
.push_back (string ("STAP_SUPPRESS_HANDLER_ERRORS"));
1365 case LONG_OPT_MODINFO
:
1366 // Make sure the global option is only composed of the
1367 // following chars: [_=a-zA-Z0-9]
1368 if (client_options
) {
1369 cerr
<< _F("ERROR: %s is invalid with %s", "--modinfo", "--client-options") << endl
;
1373 assert_regexp_match("--modinfo parameter", optarg
, "^[a-z_][a-z0-9_]*=.+$");
1374 modinfos
.push_back (string(optarg
));
1377 case LONG_OPT_RLIMIT_AS
:
1379 if(getrlimit(RLIMIT_AS
, & our_rlimit
))
1380 cerr
<< _F("Unable to obtain resource limits for rlimit-as : %s", strerror (errno
)) << endl
;
1381 if (strlen(optarg
) == 0) {
1382 cerr
<< _("An --rlimit-as option value must be specified.") << endl
;
1385 our_rlimit
.rlim_max
= our_rlimit
.rlim_cur
= strtoul (optarg
, &num_endptr
, 0);
1387 cerr
<< _F("Unable to convert rlimit-as resource limit '%s'.", optarg
) << endl
;
1390 if(setrlimit (RLIMIT_AS
, & our_rlimit
)) {
1391 int saved_errno
= errno
;
1392 cerr
<< _F("Unable to set resource limits for rlimit-as : %s", strerror (errno
)) << endl
;
1393 if (saved_errno
!= EPERM
)
1397 /* Disable core dumps, since exhaustion results in uncaught bad_alloc etc. exceptions */
1398 our_rlimit
.rlim_max
= our_rlimit
.rlim_cur
= 0;
1399 (void) setrlimit (RLIMIT_CORE
, & our_rlimit
);
1402 case LONG_OPT_RLIMIT_CPU
:
1404 if(getrlimit(RLIMIT_CPU
, & our_rlimit
))
1405 cerr
<< _F("Unable to obtain resource limits for rlimit-cpu : %s", strerror (errno
)) << endl
;
1406 if (strlen(optarg
) == 0) {
1407 cerr
<< _("An --rlimit-cpu option value must be specified.") << endl
;
1410 our_rlimit
.rlim_max
= our_rlimit
.rlim_cur
= strtoul (optarg
, &num_endptr
, 0);
1412 cerr
<< _F("Unable to convert resource limit '%s' for rlimit-cpu", optarg
) << endl
;
1415 if(setrlimit (RLIMIT_CPU
, & our_rlimit
)) {
1416 int saved_errno
= errno
;
1417 cerr
<< _F("Unable to set resource limits for rlimit-cpu : %s", strerror (errno
)) << endl
;
1418 if (saved_errno
!= EPERM
)
1423 case LONG_OPT_RLIMIT_NPROC
:
1425 if(getrlimit(RLIMIT_NPROC
, & our_rlimit
))
1426 cerr
<< _F("Unable to obtain resource limits for rlimit-nproc : %s", strerror (errno
)) << endl
;
1427 if (strlen(optarg
) == 0) {
1428 cerr
<< _("An --rlimit-nproc option value must be specified.") << endl
;
1431 our_rlimit
.rlim_max
= our_rlimit
.rlim_cur
= strtoul (optarg
, &num_endptr
, 0);
1433 cerr
<< _F("Unable to convert resource limit '%s' for rlimit-nproc", optarg
) << endl
;
1436 if(setrlimit (RLIMIT_NPROC
, & our_rlimit
)) {
1437 int saved_errno
= errno
;
1438 cerr
<< _F("Unable to set resource limits for rlimit-nproc : %s", strerror (errno
)) << endl
;
1439 if (saved_errno
!= EPERM
)
1444 case LONG_OPT_RLIMIT_STACK
:
1446 if(getrlimit(RLIMIT_STACK
, & our_rlimit
))
1447 cerr
<< _F("Unable to obtain resource limits for rlimit-stack : %s", strerror (errno
)) << endl
;
1448 if (strlen(optarg
) == 0) {
1449 cerr
<< _("An --rlimit-stack option value must be specified.") << endl
;
1452 our_rlimit
.rlim_max
= our_rlimit
.rlim_cur
= strtoul (optarg
, &num_endptr
, 0);
1454 cerr
<< _F("Unable to convert resource limit '%s' for rlimit-stack", optarg
) << endl
;
1457 if(setrlimit (RLIMIT_STACK
, & our_rlimit
)) {
1458 int saved_errno
= errno
;
1459 cerr
<< _F("Unable to set resource limits for rlimit-stack : %s", strerror (errno
)) << endl
;
1460 if (saved_errno
!= EPERM
)
1464 /* Disable core dumps, since exhaustion results in SIGSEGV */
1465 our_rlimit
.rlim_max
= our_rlimit
.rlim_cur
= 0;
1466 (void) setrlimit (RLIMIT_CORE
, & our_rlimit
);
1469 case LONG_OPT_RLIMIT_FSIZE
:
1471 if(getrlimit(RLIMIT_FSIZE
, & our_rlimit
))
1472 cerr
<< _F("Unable to obtain resource limits for rlimit-fsize : %s", strerror (errno
)) << endl
;
1473 if (strlen(optarg
) == 0) {
1474 cerr
<< _("An --rlimit-fsize option value must be specified.") << endl
;
1477 our_rlimit
.rlim_max
= our_rlimit
.rlim_cur
= strtoul (optarg
, &num_endptr
, 0);
1479 cerr
<< _F("Unable to convert resource limit '%s' for rlimit-fsize", optarg
) << endl
;
1482 if(setrlimit (RLIMIT_FSIZE
, & our_rlimit
)) {
1483 int saved_errno
= errno
;
1484 cerr
<< _F("Unable to set resource limits for rlimit-fsize : %s", strerror (errno
)) << endl
;
1485 if (saved_errno
!= EPERM
)
1490 case LONG_OPT_SYSROOT
:
1491 if (client_options
) {
1492 cerr
<< _F("ERROR: %s invalid with %s", "--sysroot", "--client-options") << endl
;
1494 } else if (sysroot_option_seen
) {
1495 cerr
<< "ERROR: multiple --sysroot options not supported" << endl
;
1500 spath
= canonicalize_file_name (optarg
);
1501 if (spath
== NULL
) {
1502 cerr
<< _F("ERROR: %s is an invalid directory for --sysroot", optarg
) << endl
;
1506 sysroot
= string(spath
);
1509 // We do path creation like this:
1510 // sysroot + "/lib/modules"
1511 // So, we don't want the sysroot path to end with a '/',
1512 // otherwise we'll end up with '/foo//lib/modules'.
1513 if (!sysroot
.empty() && *(sysroot
.end() - 1) == '/') {
1514 sysroot
.erase(sysroot
.end() - 1);
1517 sysroot_option_seen
= true;
1520 case LONG_OPT_SYSENV
:
1521 if (client_options
) {
1522 cerr
<< _F("ERROR: %s invalid with %s", "--sysenv", "--client-options") << endl
;
1525 string sysenv_str
= optarg
;
1528 if (! sysroot_option_seen
) {
1529 cerr
<< "ERROR: --sysenv must follow --sysroot" << endl
;
1533 pos
= sysenv_str
.find("=");
1534 if (pos
== string::npos
) {
1535 cerr
<< _F("ERROR: %s is an invalid argument for --sysenv", optarg
) << endl
;
1539 value
= sysenv_str
.substr(pos
+ 1);
1540 sysenv
[sysenv_str
.substr(0, pos
)] = value
;
1545 case LONG_OPT_SUPPRESS_TIME_LIMITS
: //require guru_mode to use
1546 if (guru_mode
== false)
1548 cerr
<< _F("ERROR %s requires guru mode (-g)", "--suppress-time-limits") << endl
;
1553 suppress_time_limits
= true;
1554 server_args
.push_back (string ("--suppress-time-limits"));
1555 c_macros
.push_back (string ("STAP_SUPPRESS_TIME_LIMITS_ENABLE"));
1559 case LONG_OPT_RUNTIME
:
1560 if (!parse_cmdline_runtime (optarg
))
1564 case LONG_OPT_RUNTIME_DYNINST
:
1565 if (!parse_cmdline_runtime ("dyninst"))
1569 case LONG_OPT_RUNTIME_BPF
:
1570 if (!parse_cmdline_runtime ("bpf"))
1574 case LONG_OPT_BENCHMARK_SDT
:
1575 // XXX This option is secret, not supported, subject to change at our whim
1576 benchmark_sdt_threads
= thread::hardware_concurrency();
1579 case LONG_OPT_BENCHMARK_SDT_LOOPS
:
1580 assert(optarg
!= 0); // optarg can't be NULL (or getopt would choke)
1581 // XXX This option is secret, not supported, subject to change at our whim
1582 benchmark_sdt_loops
= strtoul(optarg
, NULL
, 10);
1585 case LONG_OPT_BENCHMARK_SDT_THREADS
:
1586 assert(optarg
!= 0); // optarg can't be NULL (or getopt would choke)
1587 // XXX This option is secret, not supported, subject to change at our whim
1588 benchmark_sdt_threads
= strtoul(optarg
, NULL
, 10);
1591 case LONG_OPT_COLOR_ERRS
:
1592 // --color without arg is equivalent to always
1593 if (!optarg
|| !strcmp(optarg
, "always"))
1594 color_mode
= color_always
;
1595 else if (!strcmp(optarg
, "auto"))
1596 color_mode
= color_auto
;
1597 else if (!strcmp(optarg
, "never"))
1598 color_mode
= color_never
;
1600 cerr
<< _F("Invalid argument '%s' for --color.", optarg
) << endl
;
1603 color_errors
= color_mode
== color_always
1604 || (color_mode
== color_auto
&& isatty(STDERR_FILENO
) &&
1605 strcmp(getenv("TERM") ?: "notdumb", "dumb"));
1608 case LONG_OPT_PROLOGUE_SEARCHING
:
1609 // --prologue-searching without arg is equivalent to always
1610 if (!optarg
|| !strcmp(optarg
, "always"))
1611 prologue_searching_mode
= prologue_searching_always
;
1612 else if (!strcmp(optarg
, "auto"))
1613 prologue_searching_mode
= prologue_searching_auto
;
1614 else if (!strcmp(optarg
, "never"))
1615 prologue_searching_mode
= prologue_searching_never
;
1617 cerr
<< _F("Invalid argument '%s' for --prologue-searching.", optarg
) << endl
;
1622 case LONG_OPT_SAVE_UPROBES
:
1623 save_uprobes
= true;
1626 case LONG_OPT_TARGET_NAMESPACES
:
1628 target_namespaces_pid
= (int) strtoul(optarg
, &num_endptr
, 10);
1629 if (*num_endptr
!= '\0' || target_namespaces_pid
< 1)
1631 cerr
<< _("Invalid process ID number for target namespaces.") << endl
;
1636 case LONG_OPT_MONITOR
:
1640 monitor_interval
= (int) strtoul(optarg
, &num_endptr
, 10);
1641 if (*num_endptr
!= '\0' || monitor_interval
< 1)
1643 cerr
<< _("Invalid monitor interval.") << endl
;
1650 // Invalid/unrecognized option given or argument required, but
1651 // not given. In both cases getopt_long() will have printed the
1652 // appropriate error message to stderr already.
1657 // NOTREACHED unless one added a getopt option but not a corresponding case:
1658 cerr
<< _F("Unhandled argument code %d", (char)grc
) << endl
;
1664 for (std::set
<std::string
>::iterator it
= additional_unwindsym_modules
.begin();
1665 it
!= additional_unwindsym_modules
.end();
1668 if (is_user_module(*it
))
1670 unwindsym_modules
.insert (resolve_path(sysroot
+ *it
));
1674 unwindsym_modules
.insert (*it
);
1678 if (! kernel_release_value
.empty())
1680 setup_kernel_release(kernel_release_value
);
1682 else if (! sysroot
.empty())
1684 kernel_build_tree
= sysroot
+ "/lib/modules/" + kernel_release
+ "/build";
1691 systemtap_session::parse_cmdline_runtime (const string
& opt_runtime
)
1693 if (opt_runtime
== string("kernel"))
1694 runtime_mode
= kernel_runtime
;
1695 else if (opt_runtime
== string("bpf"))
1697 #ifndef HAVE_BPF_DECLS
1698 cerr
<< _("ERROR: --runtime=bpf unavailable; this build lacks BPF feature") << endl
;
1702 runtime_mode
= bpf_runtime
;
1703 use_cache
= use_script_cache
= false;
1706 else if (opt_runtime
== string("dyninst"))
1708 #ifndef HAVE_DYNINST
1709 cerr
<< _("ERROR: --runtime=dyninst unavailable; this build lacks DYNINST feature") << endl
;
1713 if (privilege_set
&& pr_unprivileged
!= privilege
)
1715 cerr
<< _("ERROR: --runtime=dyninst implies unprivileged mode only") << endl
;
1718 privilege
= pr_unprivileged
;
1719 privilege_set
= true;
1720 runtime_mode
= dyninst_runtime
;
1725 cerr
<< _F("ERROR: %s is an invalid argument for --runtime", opt_runtime
.c_str()) << endl
;
1733 systemtap_session::check_options (int argc
, char * const argv
[])
1735 for (int i
= optind
; i
< argc
; i
++)
1737 if (! have_script
&& ! dump_mode
)
1739 script_file
= string (argv
[i
]);
1743 args
.push_back (string (argv
[i
]));
1746 // We don't need a script with --list-servers, --trust-servers, or any dump mode
1747 bool need_script
= server_status_strings
.empty () &&
1748 server_trust_spec
.empty () &&
1749 !dump_mode
&& !interactive_mode
;
1751 if (benchmark_sdt_loops
> 0 || benchmark_sdt_threads
> 0)
1753 // Secret benchmarking options are for local use only, not servers or --remote
1754 if (client_options
|| !remote_uris
.empty())
1756 cerr
<< _("Benchmark options are only for local use.") << endl
;
1760 // Fill defaults if either is unset.
1761 if (benchmark_sdt_loops
== 0)
1762 benchmark_sdt_loops
= 10000000;
1763 if (benchmark_sdt_threads
== 0)
1764 benchmark_sdt_threads
= 1;
1766 need_script
= false;
1770 // NB: this is also triggered if stap is invoked with no arguments at all
1771 if (need_script
&& ! have_script
)
1773 cerr
<< _("A script must be specified.") << endl
;
1774 cerr
<< _("Try '-i' for building a script interactively.") << endl
;
1777 if (dump_mode
&& have_script
)
1779 cerr
<< _("Cannot specify a script with -l/-L/--dump-* switches.") << endl
;
1782 if (dump_mode
&& last_pass
!= 5)
1784 cerr
<< _("Cannot specify -p with -l/-L/--dump-* switches.") << endl
;
1787 if (dump_mode
&& interactive_mode
)
1789 cerr
<< _("Cannot specify -i with -l/-L/--dump-* switches.") << endl
;
1792 if (dump_mode
&& monitor
)
1794 cerr
<< _("Cannot specify --monitor with -l/-L/--dump-* switches.") << endl
;
1797 // FIXME: we need to think through other options that shouldn't be
1802 print_warning("--client-options is not supported by this version of systemtap");
1804 if (! server_status_strings
.empty ())
1806 print_warning("--list-servers is not supported by this version of systemtap");
1807 server_status_strings
.clear ();
1810 if (! server_trust_spec
.empty ())
1812 print_warning("--trust-servers is not supported by this version of systemtap");
1813 server_trust_spec
.clear ();
1817 #if ! HAVE_MONITOR_LIBS
1820 print_warning("Monitor mode is not supported by this version of systemtap");
1825 if (runtime_specified
&& ! specified_servers
.empty ())
1827 print_warning("Ignoring --use-server due to the use of -R");
1828 specified_servers
.clear ();
1831 if (client_options
&& last_pass
> 4)
1833 last_pass
= 4; /* Quietly downgrade. Server passed through -p5 naively. */
1836 // If phase 5 has been requested, automatically adjust the --privilege setting to match the
1837 // user's actual privilege level and add --use-server, if necessary.
1838 // Do this only if we have a script and we are not the server.
1839 // Also do this only if we're running in the kernel (e.g. not --runtime=dyninst)
1840 // XXX Eventually we could check remote hosts, but disable that case for now.
1841 if (last_pass
> 4 && have_script
&& ! client_options
&&
1842 runtime_mode
== kernel_runtime
&& remote_uris
.empty())
1844 // What is the user's privilege level?
1845 privilege_t credentials
= get_privilege_credentials ();
1846 // Don't alter specifically-requested privilege levels
1847 if (! privilege_set
&& ! pr_contains (credentials
, privilege
))
1849 // We do not have the default privilege credentials (stapdev). Lower
1850 // the privilege level to match our credentials.
1851 if (pr_contains (credentials
, pr_stapsys
))
1853 privilege
= pr_stapsys
;
1854 server_args
.push_back ("--privilege=stapsys");
1855 auto_privilege_level_msg
=
1856 _("--privilege=stapsys was automatically selected because you are a member "
1857 "of the groups stapusr and stapsys. [man stap]");
1859 else if (pr_contains (credentials
, pr_stapusr
))
1861 privilege
= pr_stapusr
;
1862 server_args
.push_back ("--privilege=stapusr");
1863 auto_privilege_level_msg
=
1864 _("--privilege=stapusr was automatically selected because you are a member "
1865 "of the group stapusr. [man stap]");
1869 // Completely unprivileged user.
1870 cerr
<< _("You are trying to run systemtap as a normal user.\n"
1871 "You should either be root, or be part of "
1872 "the group \"stapusr\" and possibly one of the groups "
1873 "\"stapsys\" or \"stapdev\". [man stap]\n");
1875 cerr
<< _("Alternatively, you may specify --runtime=dyninst for userspace probing.\n");
1877 usage (1); // does not return.
1880 // Add --use-server if not already specified and the user's (lack of) credentials require
1882 if (! pr_contains (credentials
, pr_stapdev
))
1884 enable_auto_server (
1885 _F("For users with the privilege level %s, the module created by compiling your "
1886 "script must be signed by a trusted systemtap compile-server. [man stap-server]",
1887 pr_name (credentials
)));
1891 if (client_options
&& ! pr_contains (privilege
, pr_stapdev
) && ! client_options_disallowed_for_unprivileged
.empty ())
1893 cerr
<< _F("You can't specify %s when --privilege=%s is specified.",
1894 client_options_disallowed_for_unprivileged
.c_str(),
1895 pr_name (privilege
))
1899 if ((cmd
!= "") && (target_pid
))
1901 cerr
<< _F("You can't specify %s and %s together.", "-c", "-x") << endl
;
1905 // NB: In user-mode runtimes (dyninst), we can allow guru mode any time, but we
1906 // need to restrict guru by privilege level in the kernel runtime.
1907 if (! runtime_usermode_p () && ! pr_contains (privilege
, pr_stapdev
) && guru_mode
)
1909 cerr
<< _F("You can't specify %s and --privilege=%s together.", "-g", pr_name (privilege
))
1914 // Can't use --remote and --tmpdir together because with --remote,
1915 // there may be more than one tmpdir needed.
1916 if (!remote_uris
.empty() && tmpdir_opt_set
)
1918 cerr
<< _F("You can't specify %s and %s together.", "--remote", "--tmpdir") << endl
;
1921 // Warn in case the target kernel release doesn't match the running one.
1922 native_build
= (release
== kernel_release
&&
1923 machine
== architecture
); // NB: squashed ARCH by PR4186 logic
1925 // Non-native builds can't be loaded locally, but may still work on remotes
1926 if (last_pass
> 4 && !native_build
&& remote_uris
.empty())
1928 print_warning("kernel release/architecture mismatch with host forces last-pass 4.");
1931 if(download_dbinfo
!= 0 && access ("/usr/bin/abrt-action-install-debuginfo-to-abrt-cache", X_OK
) < 0
1932 && access ("/usr/libexec/abrt-action-install-debuginfo-to-abrt-cache", X_OK
) < 0)
1934 print_warning("abrt-action-install-debuginfo-to-abrt-cache is not installed. Continuing without downloading debuginfo.");
1935 download_dbinfo
= 0;
1938 // translate path of runtime to absolute path
1939 if (runtime_path
[0] != '/')
1942 if (getcwd(cwd
, sizeof(cwd
)))
1944 runtime_path
= string(cwd
) + "/" + runtime_path
;
1948 // Abnormal characters in our temp path can break us, including parts out
1949 // of our control like Kbuild. Let's enforce nice, safe characters only.
1950 const char *tmpdir
= getenv("TMPDIR");
1952 assert_regexp_match("TMPDIR", tmpdir
, "^[-/._0-9a-z]+$");
1954 // If the kernel is using signed modules, we need to enforce server
1956 if (!client_options
&& modules_must_be_signed())
1958 // Force server use to be on, if not on already.
1959 enable_auto_server (
1960 _("The kernel on your system requires modules to be signed for loading.\n"
1961 "The module created by compiling your script must be signed by a systemtap "
1962 "compile-server. [man stap-server]"));
1964 // Cache the current system's machine owner key (MOK)
1965 // information, to pass over to the server.
1971 systemtap_session::parse_kernel_config ()
1973 // PR10702: pull config options
1974 string kernel_config_file
= kernel_build_tree
+ "/.config";
1976 int rc
= stat(kernel_config_file
.c_str(), &st
);
1979 clog
<< _F("Checking \"%s\" failed with error: %s",
1980 kernel_config_file
.c_str(), strerror(errno
)) << endl
;
1981 find_devel_rpms(*this, kernel_build_tree
.c_str());
1982 // Enable warnings, so that the rpm-installation help is sent
1983 // out. The above message is going to go to stderr anyway
1984 // in the case of stap -L without a necessary -devel available.
1985 // Might as well make the text more helpful.
1986 this->suppress_warnings
= false;
1987 missing_rpm_list_print(*this, "-devel");
1991 ifstream
kcf (kernel_config_file
.c_str());
1993 while (getline (kcf
, line
))
1995 if (!startswith(line
, "CONFIG_")) continue;
1996 size_t off
= line
.find('=');
1997 if (off
== string::npos
) continue;
1998 string key
= line
.substr(0, off
);
1999 string value
= line
.substr(off
+1, string::npos
);
2000 kernel_config
[key
] = value
;
2003 clog
<< _F("Parsed kernel \"%s\", ", kernel_config_file
.c_str())
2004 << _NF("containing %zu tuple", "containing %zu tuples",
2005 kernel_config
.size(), kernel_config
.size()) << endl
;
2014 systemtap_session::parse_kernel_exports ()
2016 string kernel_exports_file
= kernel_build_tree
+ "/Module.symvers";
2018 int rc
= stat(kernel_exports_file
.c_str(), &st
);
2021 clog
<< _F("Checking \"%s\" failed with error: %s\nEnsure kernel development headers & makefiles are installed",
2022 kernel_exports_file
.c_str(), strerror(errno
)) << endl
;
2026 ifstream
kef (kernel_exports_file
.c_str());
2028 while (getline (kef
, line
))
2030 vector
<string
> tokens
;
2031 tokenize (line
, tokens
, "\t");
2032 if (tokens
.size() == 4 &&
2033 tokens
[2] == "vmlinux" &&
2034 tokens
[3].substr(0,13) == string("EXPORT_SYMBOL"))
2035 kernel_exports
.insert (tokens
[1]);
2036 // RHEL4 Module.symvers file only has 3 tokens. No
2037 // 'EXPORT_SYMBOL' token at the end of the line.
2038 else if (tokens
.size() == 3 && tokens
[2] == "vmlinux")
2039 kernel_exports
.insert (tokens
[1]);
2042 clog
<< _NF("Parsed kernel \"%s\", containing one vmlinux export",
2043 "Parsed kernel \"%s\", containing %zu vmlinux exports",
2044 kernel_exports
.size(), kernel_exports_file
.c_str(),
2045 kernel_exports
.size()) << endl
;
2053 systemtap_session::parse_kernel_functions ()
2055 string system_map_path
= kernel_build_tree
+ "/System.map";
2056 ifstream system_map
;
2058 system_map
.open(system_map_path
.c_str(), ifstream::in
);
2059 if (! system_map
.is_open())
2062 clog
<< _F("Kernel symbol table %s unavailable, (%s)",
2063 system_map_path
.c_str(), strerror(errno
)) << endl
;
2065 system_map_path
= sysroot
+ "/boot/System.map-" + kernel_release
;
2067 system_map
.open(system_map_path
.c_str(), ifstream::in
);
2068 if (! system_map
.is_open())
2071 clog
<< _F("Kernel symbol table %s unavailable, (%s)",
2072 system_map_path
.c_str(), strerror(errno
)) << endl
;
2076 while (system_map
.good())
2078 assert_no_interrupts();
2080 string address
, type
, name
;
2081 system_map
>> address
>> type
>> name
;
2084 clog
<< "'" << address
<< "' '" << type
<< "' '" << name
2087 // 'T'/'t' are text code symbols
2088 if (type
!= "t" && type
!= "T")
2091 #ifdef __powerpc__ // XXX cross-compiling hazard
2092 // Map ".sys_foo" to "sys_foo".
2097 // FIXME: better things to do here - look for _stext before
2098 // remembering symbols. Also:
2099 // - stop remembering names at ???
2100 // - what about __kprobes_text_start/__kprobes_text_end?
2101 kernel_functions
.insert(name
);
2105 if (kernel_functions
.size() == 0)
2106 print_warning ("Kernel function symbol table missing [man warning::symbols]", 0);
2109 clog
<< _F("Parsed kernel \"%s\", ", system_map_path
.c_str())
2110 << _NF("containing %zu symbol", "containing %zu symbols",
2111 kernel_functions
.size(), kernel_functions
.size()) << endl
;
2118 systemtap_session::cmd_file ()
2123 if (target_pid
&& cmd
== "")
2125 // check that the target_pid corresponds to a running process
2127 if(!is_valid_pid (target_pid
, err_msg
))
2128 throw SEMANTIC_ERROR(err_msg
);
2130 file
= string("/proc/") + lex_cast(target_pid
) + "/exe";
2132 else // default is to assume -c flag was given
2134 int rc
= wordexp (cmd
.c_str (), &words
, WRDE_NOCMD
|WRDE_UNDEF
);
2137 if (words
.we_wordc
> 0)
2138 file
= words
.we_wordv
[0];
2146 throw SEMANTIC_ERROR(_("command contains illegal characters"));
2148 throw SEMANTIC_ERROR(_("command contains undefined shell variables"));
2150 throw SEMANTIC_ERROR(_("command contains command substitutions"));
2152 throw SEMANTIC_ERROR(_("out of memory"));
2154 throw SEMANTIC_ERROR(_("command contains shell syntax errors"));
2156 throw SEMANTIC_ERROR(_("unspecified wordexp failure"));
2165 systemtap_session::init_try_server ()
2168 // If the option is disabled or we are a server or we are already using a
2169 // server, then never retry compilation using a server.
2170 if (! use_server_on_error
|| client_options
|| ! specified_servers
.empty ())
2171 try_server_status
= dont_try_server
;
2173 try_server_status
= try_server_unset
;
2175 // No client, so don't bother.
2176 try_server_status
= dont_try_server
;
2181 systemtap_session::set_try_server (int t
)
2183 if (try_server_status
!= dont_try_server
)
2184 try_server_status
= t
;
2188 void systemtap_session::insert_loaded_modules()
2191 ifstream
procmods ("/proc/modules");
2192 while (procmods
.good()) {
2193 procmods
.getline (line
, sizeof(line
));
2194 strtok(line
, " \t");
2195 if (line
[0] == '\0')
2196 break; // maybe print a warning?
2197 unwindsym_modules
.insert (string (line
));
2200 unwindsym_modules
.insert ("kernel");
2204 systemtap_session::setup_kernel_release (const string
& kstr
)
2206 // Sometimes we may get dupes here... e.g. a server may have a full
2207 // -r /path/to/kernel followed by a client's -r kernel.
2208 if (kernel_release
== kstr
)
2209 return; // nothing new here...
2211 kernel_release
= kernel_build_tree
= kernel_source_tree
= "";
2212 if (kstr
[0] == '/') // fully specified path
2214 kernel_build_tree
= kstr
;
2215 kernel_release
= kernel_release_from_build_tree (kernel_build_tree
, verbose
);
2218 // Maybe it's a full kernel source tree, for purposes of PR10745.
2219 // In case CONFIG_DEBUG_INFO was set, we'd find it anyway with the
2220 // normal search in tapsets.cxx. Without CONFIG_DEBUG_INFO, we'd
2221 // need heuristics such as this one:
2223 string some_random_source_only_file
= kernel_build_tree
+ "/COPYING";
2224 ifstream
epic (some_random_source_only_file
.c_str());
2227 kernel_source_tree
= kernel_build_tree
;
2229 clog
<< _F("Located kernel source tree (COPYING) at '%s'", kernel_source_tree
.c_str()) << endl
;
2234 update_release_sysroot
= true;
2235 kernel_release
= kstr
;
2236 if (!kernel_release
.empty())
2237 kernel_build_tree
= "/lib/modules/" + kernel_release
+ "/build";
2240 // Let's not look for the kernel_source_tree; it's definitely
2241 // not THERE. tapsets.cxx might try to find it later if tracepoints
2247 // Register all the aliases we've seen in library files, and the user
2248 // file, as patterns.
2250 systemtap_session::register_library_aliases()
2252 vector
<stapfile
*> files(library_files
);
2253 files
.insert(files
.end(), user_files
.begin(), user_files
.end());
2255 for (unsigned f
= 0; f
< files
.size(); ++f
)
2257 stapfile
* file
= files
[f
];
2258 for (unsigned a
= 0; a
< file
->aliases
.size(); ++a
)
2260 probe_alias
* alias
= file
->aliases
[a
];
2263 for (unsigned n
= 0; n
< alias
->alias_names
.size(); ++n
)
2265 probe_point
* name
= alias
->alias_names
[n
];
2266 match_node
* mn
= pattern_root
;
2267 for (unsigned c
= 0; c
< name
->components
.size(); ++c
)
2269 probe_point::component
* comp
= name
->components
[c
];
2270 // XXX: alias parameters
2272 throw SEMANTIC_ERROR(_F("alias component %s contains illegal parameter",
2273 comp
->functor
.to_string().c_str()));
2274 mn
= mn
->bind(comp
->functor
);
2276 // PR 12916: All probe aliases are OK for all users. The actual
2277 // referenced probe points will be checked when the alias is resolved.
2278 mn
->bind_privilege (pr_all
);
2279 mn
->bind(new alias_expansion_builder(alias
));
2282 catch (const semantic_error
& e
)
2284 semantic_error
er(ERR_SRC
, _("while registering probe alias"),
2285 alias
->tok
, NULL
, &e
);
2293 // Print this given token, but abbreviate it if the last one had the
2296 systemtap_session::print_token (ostream
& o
, const token
* tok
)
2300 if (last_token
&& last_token
->location
.file
== tok
->location
.file
)
2304 string ts
= tmpo
.str();
2305 // search & replace the file name with nothing
2306 size_t idx
= ts
.find (tok
->location
.file
->name
);
2307 if (idx
!= string::npos
) {
2308 ts
.erase(idx
, tok
->location
.file
->name
.size()); // remove path
2310 string src
= ts
.substr(idx
); // keep line & col
2311 ts
.erase(idx
); // remove from output string
2312 ts
+= colorize(src
, "source"); // re-add it colorized
2326 systemtap_session::print_error (const semantic_error
& se
)
2328 // skip error message printing for listing mode with low verbosity
2329 if (this->dump_mode
&& this->verbose
<= 1)
2331 seen_errors
[se
.errsrc_chain()]++; // increment num_errors()
2335 // duplicate elimination
2336 if (verbose
> 0 || seen_errors
[se
.errsrc_chain()] < 1)
2338 seen_errors
[se
.errsrc_chain()]++;
2339 for (const semantic_error
*e
= &se
; e
!= NULL
; e
= e
->get_chain())
2340 cerr
<< build_error_msg(*e
);
2342 else suppressed_errors
++;
2346 systemtap_session::build_error_msg (const semantic_error
& e
)
2348 stringstream message
;
2349 string
align_semantic_error (" ");
2351 message
<< colorize(_("semantic error:"), "error") << ' ' << e
.what ();
2352 if (e
.tok1
|| e
.tok2
)
2356 print_error_details (message
, align_semantic_error
, e
);
2358 if (verbose
> 1) // no tokens to print, so print any errsrc right there
2359 message
<< _(" thrown from: ") << e
.errsrc
;
2364 print_token (message
, e
.tok1
);
2365 print_error_details (message
, align_semantic_error
, e
);
2368 message
<< _(" thrown from: ") << e
.errsrc
<< endl
;
2369 print_error_source (message
, align_semantic_error
, e
.tok1
);
2373 print_token (message
, e
.tok2
);
2375 print_error_source (message
, align_semantic_error
, e
.tok2
);
2378 return message
.str();
2382 systemtap_session::print_error_source (std::ostream
& message
,
2383 std::string
& align
, const token
* tok
)
2388 if (!tok
->location
.file
)
2389 //No source to print, silently exit
2392 unsigned line
= tok
->location
.line
;
2393 unsigned col
= tok
->location
.column
;
2394 interned_string file_contents
= tok
->location
.file
->file_contents
;
2396 size_t start_pos
= 0, end_pos
= 0;
2397 //Navigate to the appropriate line
2398 while (i
!= line
&& end_pos
!= std::string::npos
)
2400 start_pos
= end_pos
;
2401 end_pos
= file_contents
.find ('\n', start_pos
) + 1;
2404 //TRANSLATORS: Here we are printing the source string of the error
2405 message
<< align
<< _("source: ");
2406 interned_string srcline
= file_contents
.substr(start_pos
, end_pos
-start_pos
-1);
2409 message
<< srcline
.substr(0, col
-1);
2412 // ... hold it - the token might have been synthetic,
2413 // or expanded from a $@ command line argument, or ...
2414 // so tok->content may have nothing in common with the
2415 // contents of srcline at the same point.
2416 interned_string srcline_rest
= srcline
.substr(col
-1);
2417 interned_string srcline_tokenish
= srcline_rest
.substr(0, tok
->content
.size());
2418 if (srcline_tokenish
== tok
->content
) { // oh good
2419 message
<< colorize(tok
->content
, "token");
2420 message
<< srcline_rest
.substr(tok
->content
.size());
2425 col
+= 5; // line up with the caret
2426 message
<< colorize(tok
->content
, "token");
2427 message
<< " ... " << srcline_rest
;
2431 message
<< srcline
<< endl
;
2432 message
<< align
<< " ";
2433 //Navigate to the appropriate column
2434 for (i
=start_pos
; i
<start_pos
+col
-1; i
++)
2436 if(isspace(file_contents
[i
]))
2437 message
<< file_contents
[i
];
2441 message
<< colorize("^", "caret") << endl
;
2443 // print chained macro invocations and synthesized code
2446 if (tok
->location
.file
->synthetic
)
2447 message
<< _("\tin synthesized code from: ");
2449 message
<< _("\tin expansion of macro: ");
2450 message
<< colorize(tok
->chain
) << endl
;
2451 print_error_source (message
, align
, tok
->chain
);
2456 systemtap_session::print_error_details (std::ostream
& message
,
2458 const semantic_error
& e
)
2460 for (size_t i
= 0; i
< e
.details
.size(); ++i
)
2461 message
<< endl
<< align
<< e
.details
[i
];
2465 systemtap_session::print_warning (const string
& message_str
, const token
* tok
)
2467 // Only output in dump mode if -vv is supplied:
2468 if (suppress_warnings
&& (!dump_mode
|| verbose
<= 1))
2469 return; // NB: don't count towards suppressed_warnings count
2471 // Duplicate elimination
2472 string
align_warning (" ");
2473 if (verbose
> 0 || seen_warnings
.find (message_str
) == seen_warnings
.end())
2475 seen_warnings
.insert (message_str
);
2476 clog
<< colorize(_("WARNING:"), "warning") << ' ' << message_str
;
2477 if (tok
) { clog
<< ": "; print_token (clog
, tok
); }
2479 if (tok
) { print_error_source (clog
, align_warning
, tok
); }
2481 else suppressed_warnings
++;
2486 systemtap_session::print_error (const parse_error
&pe
,
2488 const std::string
&input_name
,
2491 // duplicate elimination
2492 if (verbose
> 0 || seen_errors
[pe
.errsrc_chain()] < 1)
2494 // Sometimes, we need to print parse errors that should not be considered
2495 // critical. For example, when we parse tapsets and macros. In those
2496 // cases, is_warningerr is true, and we cancel out the increase in
2497 // seen_errors.size() by also increasing warningerr_count, so that the
2498 // net num_errors() value is unchanged.
2499 seen_errors
[pe
.errsrc_chain()]++; // can be simplified if we
2500 if (seen_errors
[pe
.errsrc_chain()] == 1 && is_warningerr
) // change map to a set (and
2501 warningerr_count
++; // settle on threshold of 1)
2502 cerr
<< build_error_msg(pe
, tok
, input_name
);
2503 for (const parse_error
*e
= pe
.chain
; e
!= NULL
; e
= e
->chain
)
2504 cerr
<< build_error_msg(*e
, e
->tok
, input_name
);
2506 else suppressed_errors
++;
2510 systemtap_session::build_error_msg (const parse_error
& pe
,
2512 const std::string
&input_name
)
2514 stringstream message
;
2515 string
align_parse_error (" ");
2517 // print either pe.what() or a deferred error from the lexer
2518 bool found_junk
= false;
2519 if (tok
&& tok
->type
== tok_junk
&& tok
->junk_type
!= tok_junk_unknown
)
2522 message
<< colorize(_("parse error:"), "error") << ' '
2523 << tok
->junk_message(*this) << endl
;
2527 message
<< colorize(_("parse error:"), "error") << ' ' << pe
.what() << endl
;
2530 // NB: It makes sense for lexer errors to always override parser
2531 // errors, since the original obvious scheme was for the lexer to
2532 // throw an exception before the token reached the parser.
2534 if (pe
.tok
|| found_junk
)
2536 message
<< align_parse_error
<< _(" at: ") << colorize(tok
) << endl
;
2537 print_error_source (message
, align_parse_error
, tok
);
2539 else if (tok
) // "expected" type error
2541 message
<< align_parse_error
<< _(" saw: ") << colorize(tok
) << endl
;
2542 print_error_source (message
, align_parse_error
, tok
);
2546 message
<< align_parse_error
<< _(" saw: ") << input_name
<< " EOF" << endl
;
2550 return message
.str();
2554 systemtap_session::report_suppression()
2556 if (this->suppressed_errors
> 0)
2557 cerr
<< colorize(_F("Number of similar error messages suppressed: %d.",
2558 this->suppressed_errors
),
2560 if (this->suppressed_warnings
> 0)
2561 cerr
<< colorize(_F("Number of similar warning messages suppressed: %d.",
2562 this->suppressed_warnings
),
2564 if (this->suppressed_errors
> 0 || this->suppressed_warnings
> 0)
2565 cerr
<< "Rerun with -v to see them." << endl
;
2569 systemtap_session::create_tmp_dir()
2571 if (!tmpdir
.empty())
2577 // Create the temp directory
2578 const char * tmpdir_env
= getenv("TMPDIR");
2580 tmpdir_env
= "/tmp";
2582 string stapdir
= "/stapXXXXXX";
2583 string tmpdirt
= tmpdir_env
+ stapdir
;
2584 const char *tmpdir_name
= mkdtemp((char *)tmpdirt
.c_str());
2587 const char* e
= strerror(errno
);
2588 //TRANSLATORS: we can't make the directory due to the error
2589 throw runtime_error(_F("cannot create temporary directory (\" %s \"): %s", tmpdirt
.c_str(), e
));
2592 tmpdir
= tmpdir_name
;
2596 systemtap_session::remove_tmp_dir()
2601 // Remove temporary directory
2602 if (keep_tmpdir
&& !tmpdir_opt_set
)
2603 clog
<< _F("Keeping temporary directory \"%s\"", tmpdir
.c_str()) << endl
;
2604 else if (!tmpdir_opt_set
)
2606 // Mask signals while we're deleting the temporary directory.
2607 stap_sigmasker masked
;
2609 // Remove the temporary directory.
2610 vector
<string
> cleanupcmd
{ "rm", "-rf", tmpdir
};
2611 (void) stap_system(verbose
, cleanupcmd
);
2613 clog
<< _F("Removed temporary directory \"%s\"", tmpdir
.c_str()) << endl
;
2620 systemtap_session::reset_tmp_dir()
2626 translator_output
* systemtap_session::op_create_auxiliary(bool trailer_p
)
2628 static int counter
= 0;
2629 string tmpname
= this->tmpdir
+ "/" + this->module_name
+ "_aux_" + lex_cast(counter
++) + ".c";
2630 translator_output
* n
= new translator_output (tmpname
);
2631 n
->trailer_p
= trailer_p
;
2632 auxiliary_outputs
.push_back (n
);
2636 // Wrapper for checking if there are pending interrupts
2638 assert_no_interrupts()
2640 if (pending_interrupts
)
2641 throw interrupt_exception();
2645 systemtap_session::colorize(const std::string
& str
, const std::string
& type
)
2647 if (str
.empty() || !color_errors
)
2650 // Check if this type is defined in SYSTEMTAP_COLORS
2651 std::string color
= parse_stap_color(type
);
2652 if (!color
.empty()) // no need to pollute terminal if not necessary
2653 return "\033[" + color
+ "m\033[K" + str
+ "\033[m\033[K";
2659 // Colorizes the path:row:col part of the token
2661 systemtap_session::colorize(const token
* tok
)
2670 return tmp
.str(); // Might as well stop now to save time
2672 string ts
= tmp
.str();
2674 // Print token location, which is also the tail of ts
2676 loc
<< tok
->location
;
2678 // Remove token location and re-add it colorized
2679 ts
.erase(ts
.size()-loc
.str().size());
2680 return ts
+ colorize(loc
.str(), "source");
2684 /* Parse SYSTEMTAP_COLORS and returns the SGR parameter(s) for the given
2685 type. The env var SYSTEMTAP_COLORS must be in the following format:
2686 'key1=val1:key2=val2:' etc... where valid keys are 'error', 'warning',
2687 'source', 'caret', 'token' and valid values constitute SGR parameter(s).
2688 For example, the default setting would be:
2689 'error=01;31:warning=00;33:source=00;34:caret=01:token=01'
2692 systemtap_session::parse_stap_color(const std::string
& type
)
2694 const char *key
, *col
, *eq
;
2695 int n
= type
.size();
2698 key
= getenv("SYSTEMTAP_COLORS");
2700 key
= "error=01;31:warning=00;33:source=00;34:caret=01:token=01";
2701 else if (*key
== '\0')
2702 return ""; // disable colors if set but empty
2705 if (!(col
= strchr(key
, ':'))) {
2706 col
= strchr(key
, '\0');
2709 if (!((eq
= strchr(key
, '=')) && eq
< col
))
2710 return ""; /* invalid syntax: no = in range */
2711 if (!(key
< eq
&& eq
< col
-1))
2712 return ""; /* invalid syntax: key or val empty */
2713 if (strspn(eq
+1, "0123456789;") < (size_t)(col
-eq
-1))
2714 return ""; /* invalid syntax: invalid char in val */
2715 if (eq
-key
== n
&& type
.compare(0, n
, key
, n
) == 0)
2716 return string(eq
+1, col
-eq
-1);
2717 if (!done
) key
= col
+1; /* advance to next key */
2720 // Could not find the key
2725 * Returns true if this system requires modules to have signatures
2726 * (typically on a secure boot system), false otherwise.
2728 * This routine parses /sys/module/module/parameters/sig_enforce to
2729 * figure out if signatures are enforced on modules. Note that if the
2730 * file doesn't exist, we don't really care and return false.
2732 * On certain kernels (RHEL7), we also have to check
2733 * /sys/kernel/security/securelevel.
2736 systemtap_session::modules_must_be_signed()
2738 ifstream
statm("/sys/module/module/parameters/sig_enforce");
2739 ifstream
securelevel("/sys/kernel/security/securelevel");
2746 securelevel
>> status
;
2753 * Get information on the list of enrolled machine owner keys (MOKs) on
2757 systemtap_session::get_mok_info()
2762 // FIXME: In theory, we should be able to read /sys files and use
2763 // some of the guts of read_cert_info_from_file() to get the
2764 // fingerprints. This would rid us of our mokutil
2765 // dependency. However, we'd need to copy/duplicate efilib.c from
2766 // mokutil source to be able to decipher the efi data.
2768 vector
<string
> cmd
{ "mokutil", "--list-enrolled" };
2769 rc
= stap_system_read(verbose
, cmd
, out
);
2771 // If we're here, we know the client requires module signing, but
2772 // we can't get the list of MOKs. Quit.
2773 throw runtime_error(_F("failed to get list of machine owner keys (MOK) fingerprints: rc %d", rc
));
2775 string line
, fingerprint
;
2778 vector
<string
> matches
;
2780 // Get a line of the output, then try to find the fingerprint in
2783 if (! regexp_match(line
, "^SHA1 Fingerprint: ([0-9a-f:]+)$", matches
))
2785 // matches[0] is the entire line, matches[1] is the first
2786 // submatch, in this case the actual fingerprint
2788 clog
<< "MOK fingerprint found: " << matches
[1] << endl
;
2789 if (! matches
[1].empty())
2790 mok_fingerprints
.push_back(matches
[1]);
2796 systemtap_session::enable_auto_server (const string
&message
)
2798 // There may be more than one reason to enable auto server mode, so we may be called
2799 // more than once. Accumulate the messages.
2800 auto_server_msgs
.push_back (message
);
2803 // Enable auto server mode, if not enabled already.
2804 if (specified_servers
.empty())
2805 specified_servers
.push_back ("");
2807 // Compilation using a server is not supported. exit() after
2808 // the first explanation.
2809 explain_auto_options ();
2810 clog
<< _("Unable to request compilation by a compile-server\n."
2811 "Without NSS, --use-server is not supported by this version systemtap.") << endl
;
2817 systemtap_session::explain_auto_options()
2819 // Was there an automatic privilege setting?
2820 if (! auto_privilege_level_msg
.empty())
2821 clog
<< auto_privilege_level_msg
<< endl
;
2823 // Was a server was automatically requested? Handle this one after other auto_settings
2824 // which may result in an auto_server setting.
2825 if (! auto_server_msgs
.empty())
2827 for (vector
<string
>::iterator i
= auto_server_msgs
.begin(); i
!= auto_server_msgs
.end(); ++i
)
2830 clog
<< _("--use-server was automatically selected in order to request compilation by "
2831 "a compile-server.") << endl
;
2837 systemtap_session::is_user_file (const string
&name
)
2839 // base the check on the name of the user_file
2840 for (vector
<stapfile
*>::iterator it
= user_files
.begin(); it
!= user_files
.end(); it
++)
2841 if (name
== (*it
)->name
)
2843 return false; // no match
2847 systemtap_session::is_primary_probe (derived_probe
*dp
)
2849 // We check if this probe is from the primary user file by going back to its
2850 // original probe and checking if that probe was found in the primary user
2853 if (user_files
.empty())
2856 vector
<probe
*> chain
;
2857 dp
->collect_derivation_chain (chain
);
2858 const source_loc
& origin
= chain
.back()->tok
->location
;
2859 return origin
.file
== user_files
[0];
2863 systemtap_session::clear_script_data()
2865 delete pattern_root
;
2866 pattern_root
= new match_node
;
2868 // We need to be sure to reset all our error counts, so that an
2869 // error on one script won't be counted against the next script.
2870 seen_warnings
.clear();
2871 suppressed_warnings
= 0;
2872 seen_errors
.clear();
2873 suppressed_errors
= 0;
2874 warningerr_count
= 0;
2877 // --------------------------------------------------------------------------
2880 Perngrq sebz fzvyrlgnc.fit, rkcbegrq gb n 1484k1110 fzvyrlgnc.cat,
2881 gurapr catgbcnz | cazfpnyr -jvqgu 160 |
2882 cczqvgure -qvz 4 -erq 2 -terra 2 -oyhr 2 | cczgbnafv -2k4 | bq -i -j19 -g k1 |
2883 phg -s2- -q' ' | frq -r 'f,^,\\k,' -r 'f, ,\\k,t' -r 'f,^,",' -r 'f,$,",'
2886 systemtap_session::morehelp
=
2887 "\x1b\x5b\x30\x6d\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2888 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2889 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2890 "\x20\x20\x20\x60\x20\x20\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2891 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20"
2892 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2893 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2894 "\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x1b\x5b"
2895 "\x33\x33\x6d\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2896 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2897 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2898 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x20\x60"
2899 "\x2e\x60\x1b\x5b\x33\x37\x6d\x20\x3a\x2c\x3a\x2e\x60\x20\x60\x20\x60\x20\x60"
2900 "\x2c\x3b\x2c\x3a\x20\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d"
2901 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
2902 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2903 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33"
2904 "\x33\x6d\x20\x60\x20\x60\x20\x3a\x27\x60\x1b\x5b\x33\x37\x6d\x20\x60\x60\x60"
2905 "\x20\x20\x20\x60\x20\x60\x60\x60\x20\x1b\x5b\x33\x33\x6d\x60\x3a\x60\x20\x60"
2906 "\x20\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2907 "\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2908 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2909 "\x20\x2e\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x20\x1b\x5b\x33"
2910 "\x37\x6d\x20\x3a\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x2e\x1b\x5b\x33\x33"
2911 "\x6d\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20"
2912 "\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x2e\x3a\x20\x20"
2913 "\x20\x20\x20\x20\x20\x20\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2914 "\x20\x20\x2e\x76\x53\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x1b\x5b"
2915 "\x33\x31\x6d\x2b\x1b\x5b\x33\x33\x6d\x60\x20\x60\x20\x60\x20\x20\x20\x20\x1b"
2916 "\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x33\x6d\x2b\x1b\x5b"
2917 "\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x2e\x1b\x5b\x33\x30\x6d\x24\x1b\x5b"
2918 "\x33\x37\x6d\x3b\x1b\x5b\x33\x31\x6d\x7c\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
2919 "\x20\x60\x20\x60\x1b\x5b\x33\x31\x6d\x2c\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33"
2920 "\x37\x6d\x53\x53\x3e\x2c\x2e\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x2e"
2921 "\x3b\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x20\x20\x20\x20\x20\x20"
2922 "\x20\x20\x20\x2e\x2e\x3a\x1b\x5b\x33\x30\x6d\x26\x46\x46\x46\x48\x46\x1b\x5b"
2923 "\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x30\x6d\x4d\x4d"
2924 "\x46\x1b\x5b\x33\x33\x6d\x20\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x1b\x5b"
2925 "\x33\x33\x6d\x20\x3a\x1b\x5b\x33\x30\x6d\x4d\x4d\x46\x1b\x5b\x33\x33\x6d\x20"
2926 "\x20\x20\x60\x20\x60\x2e\x60\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x30\x6d\x46"
2927 "\x46\x46\x24\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
2928 "\x20\x2e\x3c\x3a\x60\x20\x20\x20\x20\x2e\x3a\x2e\x3a\x2e\x2e\x3b\x27\x20\x20"
2929 "\x20\x20\x20\x20\x2e\x60\x2e\x3a\x60\x60\x3c\x27\x1b\x5b\x33\x31\x6d\x3c\x27"
2930 "\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x3c\x1b\x5b\x33"
2931 "\x30\x6d\x26\x1b\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x33\x6d\x20\x1b\x5b\x33\x37"
2932 "\x6d\x20\x1b\x5b\x33\x33\x6d\x20\x20\x20\x20\x20\x1b\x5b\x33\x37\x6d\x60\x1b"
2933 "\x5b\x33\x30\x6d\x2a\x46\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x20\x60"
2934 "\x20\x60\x20\x60\x20\x60\x20\x1b\x5b\x33\x31\x6d\x60\x3a\x1b\x5b\x33\x37\x6d"
2935 "\x27\x3c\x1b\x5b\x33\x30\x6d\x23\x1b\x5b\x33\x37\x6d\x3c\x60\x3a\x20\x20\x20"
2936 "\x0a\x20\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x20\x60\x3a\x2e\x2e\x2e\x2e\x3c"
2937 "\x3c\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x60\x20\x20\x20\x60\x1b\x5b\x33"
2938 "\x33\x6d\x3a\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x20"
2939 "\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x37\x6d\x20\x20\x1b\x5b\x33\x33\x6d"
2940 "\x20\x60\x20\x20\x20\x60\x1b\x5b\x33\x37\x6d\x20\x60\x20\x60\x1b\x5b\x33\x33"
2941 "\x6d\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
2942 "\x20\x60\x3a\x2e\x60\x2e\x20\x0a\x20\x20\x20\x60\x3a\x60\x3a\x60\x20\x20\x20"
2943 "\x20\x20\x60\x60\x60\x60\x20\x3a\x2d\x20\x20\x20\x20\x20\x60\x20\x60\x20\x20"
2944 "\x20\x20\x20\x60\x1b\x5b\x33\x33\x6d\x3a\x60\x2e\x60\x20\x60\x20\x60\x20\x60"
2945 "\x20\x60\x20\x20\x2e\x3b\x1b\x5b\x33\x31\x6d\x76\x1b\x5b\x33\x30\x6d\x24\x24"
2946 "\x24\x1b\x5b\x33\x31\x6d\x2b\x53\x1b\x5b\x33\x33\x6d\x2c\x60\x20\x60\x20\x60"
2947 "\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x3a"
2948 "\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x2e\x60\x20\x20\x0a\x20\x20\x20\x60"
2949 "\x3a\x3a\x3a\x3a\x20\x20\x20\x20\x3a\x60\x60\x60\x60\x3a\x53\x20\x20\x20\x20"
2950 "\x20\x20\x3a\x2e\x60\x2e\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
2951 "\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20\x60"
2952 "\x20\x3a\x1b\x5b\x33\x30\x6d\x24\x46\x46\x48\x46\x46\x46\x46\x46\x1b\x5b\x33"
2953 "\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2e"
2954 "\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
2955 "\x20\x2e\x60\x2e\x3a\x20\x20\x0a\x20\x20\x20\x60\x3a\x3a\x3a\x60\x20\x20\x20"
2956 "\x60\x3a\x20\x2e\x20\x3b\x27\x3a\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x20"
2957 "\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x60\x1b"
2958 "\x5b\x33\x33\x6d\x2e\x60\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x30\x6d\x53"
2959 "\x46\x46\x46\x53\x46\x46\x46\x53\x46\x46\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
2960 "\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x20"
2961 "\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x0a\x20\x20\x20\x20\x60\x3c\x3b\x3c\x20"
2962 "\x20\x20\x20\x20\x60\x60\x60\x20\x3a\x3a\x20\x20\x20\x20\x20\x20\x20\x3a\x3a"
2963 "\x2e\x60\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d"
2964 "\x3c\x3a\x60\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x30"
2965 "\x6d\x53\x46\x53\x46\x46\x46\x53\x46\x46\x46\x53\x1b\x5b\x33\x33\x6d\x2e\x60"
2966 "\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b"
2967 "\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x3a\x3a\x60\x20\x20\x20\x0a\x20\x20"
2968 "\x20\x20\x20\x60\x3b\x3c\x20\x20\x20\x20\x20\x20\x20\x3a\x3b\x60\x20\x20\x20"
2969 "\x20\x20\x20\x20\x20\x20\x60\x3a\x60\x2e\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33"
2970 "\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33"
2971 "\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x1b\x5b\x33\x31\x6d\x3a"
2972 "\x1b\x5b\x33\x30\x6d\x46\x53\x46\x53\x46\x53\x46\x53\x46\x1b\x5b\x33\x31\x6d"
2973 "\x3f\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x2e\x3a\x3a\x1b\x5b\x33\x31\x6d\x3c"
2974 "\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x60\x20"
2975 "\x20\x20\x3a\x3a\x3a\x60\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x53\x3c"
2976 "\x20\x20\x20\x20\x20\x20\x3a\x53\x3a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2977 "\x20\x60\x3a\x3a\x60\x2e\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
2978 "\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a"
2979 "\x60\x2e\x60\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x53\x24\x53\x46\x53\x24\x1b\x5b"
2980 "\x33\x33\x6d\x60\x3a\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
2981 "\x33\x31\x6d\x3a\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b"
2982 "\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x2e\x60\x3a\x3a\x60\x20"
2983 "\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x3b\x3c\x2e\x2e\x2c\x2e\x2e\x20"
2984 "\x3a\x3c\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a"
2985 "\x60\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31"
2986 "\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33"
2987 "\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3c\x1b\x5b\x33\x30\x6d\x53\x24\x53\x1b"
2988 "\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x2e\x3a\x3b"
2989 "\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x31\x6d"
2990 "\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x20\x60\x2e\x3a"
2991 "\x3a\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x2e\x3a\x3a\x3c\x53\x3c\x3a\x60"
2992 "\x3a\x3a\x3a\x3a\x53\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33\x37\x6d\x3b\x27\x3a"
2993 "\x3c\x2c\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a\x3a\x2e\x60"
2994 "\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
2995 "\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b"
2996 "\x33\x31\x6d\x3c\x2c\x1b\x5b\x33\x33\x6d\x3c\x3b\x3a\x1b\x5b\x33\x31\x6d\x2c"
2997 "\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x53"
2998 "\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x3c\x1b\x5b\x33\x37\x6d\x3a"
2999 "\x60\x2e\x60\x2e\x3b\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x3f\x27"
3000 "\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x3a\x3c\x53\x53\x3b\x3c"
3001 "\x3a\x60\x3a\x3a\x53\x53\x53\x3c\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x1b\x5b"
3002 "\x33\x37\x6d\x2b\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x3a\x1b\x5b\x33\x34"
3003 "\x6d\x53\x1b\x5b\x33\x30\x6d\x53\x46\x24\x1b\x5b\x33\x37\x6d\x2c\x60\x3a\x3a"
3004 "\x3a\x3c\x3a\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33"
3005 "\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31"
3006 "\x6d\x53\x3b\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33"
3007 "\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37"
3008 "\x6d\x3c\x53\x3c\x3a\x3a\x3a\x3a\x3f\x1b\x5b\x33\x30\x6d\x53\x24\x48\x1b\x5b"
3009 "\x33\x37\x6d\x27\x60\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x2e"
3010 "\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x1b\x5b\x33"
3011 "\x30\x6d\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20"
3012 "\x60\x3a\x1b\x5b\x33\x30\x6d\x3c\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60"
3013 "\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3c\x3a\x60\x3a\x27\x3a\x60\x3a\x60\x3a"
3014 "\x60\x3a\x60\x3b\x1b\x5b\x33\x30\x6d\x53\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27"
3015 "\x20\x60\x20\x60\x20\x60\x20\x20\x20\x20\x0a\x20\x3c\x3b\x3a\x2e\x60\x20\x60"
3016 "\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2c\x53\x1b\x5b\x33\x32\x6d\x53\x1b"
3017 "\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20"
3018 "\x20\x20\x60\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x46\x46\x1b\x5b\x33\x34\x6d"
3019 "\x2b\x1b\x5b\x33\x37\x6d\x3a\x20\x60\x20\x60\x20\x60\x2e\x60\x20\x60\x2e\x60"
3020 "\x20\x60\x2e\x60\x20\x60\x20\x60\x2c\x1b\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b"
3021 "\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x20"
3022 "\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3b\x3c"
3023 "\x2c\x60\x2c\x3b\x3b\x53\x3f\x53\x1b\x5b\x33\x30\x6d\x24\x46\x3c\x1b\x5b\x33"
3024 "\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x60"
3025 "\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60\x20"
3026 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x3b\x76\x1b\x5b\x33\x30\x6d"
3027 "\x48\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20"
3028 "\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x24\x1b"
3029 "\x5b\x33\x37\x6d\x53\x53\x53\x53\x53\x53\x1b\x5b\x33\x30\x6d\x53\x24\x53\x46"
3030 "\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
3031 "\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x23\x46\x46\x46"
3032 "\x24\x1b\x5b\x33\x37\x6d\x76\x2c\x2c\x20\x2e\x20\x2e\x20\x2c\x2c\x76\x1b\x5b"
3033 "\x33\x30\x6d\x26\x24\x46\x46\x48\x3c\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20"
3034 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x60"
3035 "\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x46\x24\x46\x24\x46\x46\x48\x46\x53\x1b\x5b"
3036 "\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x2e\x60\x20\x60\x2e\x60\x2e\x60"
3037 "\x2e\x60\x2e\x60\x3a\x3a\x3a\x3a\x3a\x1b\x5b\x33\x30\x6d\x2a\x46\x46\x46\x48"
3038 "\x46\x48\x46\x48\x46\x46\x46\x48\x46\x48\x46\x48\x1b\x5b\x33\x37\x6d\x3c\x22"
3039 "\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x0a"
3040 "\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x48"
3041 "\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x20\x60\x2e\x60\x20\x60"
3042 "\x2e\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3a\x3a\x60\x3a\x3c\x3c"
3043 "\x1b\x5b\x33\x30\x6d\x3c\x46\x48\x46\x46\x46\x48\x46\x46\x46\x1b\x5b\x33\x37"
3044 "\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
3045 "\x60\x20\x60\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b"
3046 "\x33\x30\x6d\x2a\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x20\x20\x60\x20\x60"
3047 "\x2e\x60\x20\x60\x2e\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a"
3048 "\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x46\x46\x48\x46\x48\x46"
3049 "\x1b\x5b\x33\x37\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x3a\x60\x2e"
3050 "\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x20\x60\x0a\x20\x20\x20\x20\x20\x20\x20"
3051 "\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x1b\x5b\x33\x37\x6d"
3052 "\x2b\x60\x20\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2e\x60\x20"
3053 "\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x60\x2e\x60\x3b\x1b\x5b\x33\x30\x6d"
3054 "\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
3055 "\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x20\x20\x0a\x20"
3056 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22\x1b\x5b\x33\x30\x6d\x3c"
3057 "\x48\x46\x53\x1b\x5b\x33\x37\x6d\x2b\x3a\x20\x20\x20\x60\x20\x60\x20\x60\x20"
3058 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2c\x1b"
3059 "\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x60\x20\x60\x20"
3060 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60"
3061 "\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
3062 "\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x48\x24\x46\x46\x1b\x5b\x33\x37\x6d\x3e\x2c"
3063 "\x2e\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x3b"
3064 "\x2c\x2c\x1b\x5b\x33\x30\x6d\x24\x53\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x22"
3065 "\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x20\x20"
3066 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20"
3067 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b\x33\x30\x6d\x2a\x3c\x48"
3068 "\x46\x46\x24\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3e\x3e\x3e\x3e\x3e\x53"
3069 "\x3e\x53\x1b\x5b\x33\x30\x6d\x24\x53\x24\x46\x24\x48\x46\x23\x1b\x5b\x33\x37"
3070 "\x6d\x27\x22\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
3071 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20"
3072 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
3073 "\x60\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x2a\x3c\x3c\x3c\x48\x46\x46\x46\x48\x46"
3074 "\x46\x46\x23\x3c\x1b\x5b\x33\x36\x6d\x3c\x1b\x5b\x33\x37\x6d\x3c\x27\x22\x22"
3075 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
3076 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x1b"
3079 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */