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