]> sourceware.org Git - systemtap.git/blob - main.cxx
Merge branch 'master' of ssh://sourceware.org/git/systemtap
[systemtap.git] / main.cxx
1 // systemtap translator/driver
2 // Copyright (C) 2005-2014 Red Hat Inc.
3 // Copyright (C) 2005 IBM Corp.
4 // Copyright (C) 2006 Intel Corporation.
5 //
6 // This file is part of systemtap, and is free software. You can
7 // redistribute it and/or modify it under the terms of the GNU General
8 // Public License (GPL); either version 2, or (at your option) any
9 // later version.
10
11 #include "config.h"
12 #include "staptree.h"
13 #include "parse.h"
14 #include "elaborate.h"
15 #include "translate.h"
16 #include "buildrun.h"
17 #include "session.h"
18 #include "hash.h"
19 #include "cache.h"
20 #include "util.h"
21 #include "coveragedb.h"
22 #include "rpm_finder.h"
23 #include "task_finder.h"
24 #include "csclient.h"
25 #include "remote.h"
26 #include "tapsets.h"
27 #include "setupdwfl.h"
28 #ifdef HAVE_LIBREADLINE
29 #include "interactive.h"
30 #endif
31
32 #if ENABLE_NLS
33 #include <libintl.h>
34 #include <locale.h>
35 #endif
36
37 #include "stap-probe.h"
38
39 #include <cstdlib>
40
41 extern "C" {
42 #include <glob.h>
43 #include <unistd.h>
44 #include <signal.h>
45 #include <sys/utsname.h>
46 #include <sys/times.h>
47 #include <sys/time.h>
48 #include <sys/stat.h>
49 #include <time.h>
50 #include <unistd.h>
51 #include <wordexp.h>
52 }
53
54 using namespace std;
55
56 static void
57 uniq_list(list<string>& l)
58 {
59 set<string> s;
60 list<string>::iterator i = l.begin();
61 while (i != l.end())
62 if (s.insert(*i).second)
63 ++i;
64 else
65 i = l.erase(i);
66 }
67
68 static void
69 printscript(systemtap_session& s, ostream& o)
70 {
71 if (s.dump_mode == systemtap_session::dump_matched_probes ||
72 s.dump_mode == systemtap_session::dump_matched_probes_vars)
73 {
74 // We go through some heroic measures to produce clean output.
75 // Record the alias and probe pointer as <name, set<derived_probe *> >
76 map<string,set<derived_probe *> > probe_list;
77
78 // Pre-process the probe alias
79 for (unsigned i=0; i<s.probes.size(); i++)
80 {
81 assert_no_interrupts();
82
83 derived_probe* p = s.probes[i];
84 vector<probe*> chain;
85 p->collect_derivation_chain (chain);
86
87 if (s.verbose > 2) {
88 p->printsig(cerr); cerr << endl;
89 cerr << "chain[" << chain.size() << "]:" << endl;
90 for (unsigned j=0; j<chain.size(); j++)
91 {
92 cerr << " [" << j << "]: " << endl;
93 cerr << "\tlocations[" << chain[j]->locations.size() << "]:" << endl;
94 for (unsigned k=0; k<chain[j]->locations.size(); k++)
95 {
96 cerr << "\t [" << k << "]: ";
97 chain[j]->locations[k]->print(cerr);
98 cerr << endl;
99 }
100 const probe_alias *a = chain[j]->get_alias();
101 if (a)
102 {
103 cerr << "\taliases[" << a->alias_names.size() << "]:" << endl;
104 for (unsigned k=0; k<a->alias_names.size(); k++)
105 {
106 cerr << "\t [" << k << "]: ";
107 a->alias_names[k]->print(cerr);
108 cerr << endl;
109 }
110 }
111 }
112 }
113
114 const string& pp = lex_cast(*p->script_location());
115
116 // PR16730: We should only list probes that can be traced back to the
117 // user's spec, not any auxiliary probes in the tapsets.
118 // Also, do not want to the probes that are from the additional
119 // scripts (-E SCRIPT) to be listed.
120 if (!s.is_primary_probe(p))
121 continue;
122
123 // Now duplicate-eliminate. An alias may have expanded to
124 // several actual derived probe points, but we only want to
125 // print the alias head name once.
126 probe_list[pp].insert(p);
127 }
128
129 // print probe name and variables if there
130 for (map<string, set<derived_probe *> >::iterator it=probe_list.begin(); it!=probe_list.end(); ++it)
131 {
132 o << it->first; // probe name or alias
133
134 // Print the locals and arguments for -L mode only
135 if (s.dump_mode == systemtap_session::dump_matched_probes_vars)
136 {
137 map<string,unsigned> var_count; // format <"name:type",count>
138 map<string,unsigned> arg_count;
139 list<string> var_list;
140 list<string> arg_list;
141 // traverse set<derived_probe *> to collect all locals and arguments
142 for (set<derived_probe *>::iterator ix=it->second.begin(); ix!=it->second.end(); ++ix)
143 {
144 derived_probe* p = *ix;
145 // collect available locals of the probe
146 for (unsigned j=0; j<p->locals.size(); j++)
147 {
148 stringstream tmps;
149 vardecl* v = p->locals[j];
150 v->printsig (tmps);
151 var_count[tmps.str()]++;
152 var_list.push_back(tmps.str());
153 }
154 // collect arguments of the probe if there
155 list<string> arg_set;
156 p->getargs(arg_set);
157 for (list<string>::iterator ia=arg_set.begin(); ia!=arg_set.end(); ++ia) {
158 arg_count[*ia]++;
159 arg_list.push_back(*ia);
160 }
161 }
162
163 uniq_list(arg_list);
164 uniq_list(var_list);
165
166 // print the set-intersection only
167 for (list<string>::iterator ir=var_list.begin(); ir!=var_list.end(); ++ir)
168 if (var_count.find(*ir)->second == it->second.size()) // print locals
169 o << " " << *ir;
170 for (list<string>::iterator ir=arg_list.begin(); ir!=arg_list.end(); ++ir)
171 if (arg_count.find(*ir)->second == it->second.size()) // print arguments
172 o << " " << *ir;
173 }
174 o << endl;
175 }
176 }
177 else
178 {
179 if (s.embeds.size() > 0)
180 o << _("# global embedded code") << endl;
181 for (unsigned i=0; i<s.embeds.size(); i++)
182 {
183 assert_no_interrupts();
184 embeddedcode* ec = s.embeds[i];
185 ec->print (o);
186 o << endl;
187 }
188
189 if (s.globals.size() > 0)
190 o << _("# globals") << endl;
191 for (unsigned i=0; i<s.globals.size(); i++)
192 {
193 assert_no_interrupts();
194 vardecl* v = s.globals[i];
195 v->printsig (o);
196 if (s.verbose && v->init)
197 {
198 o << " = ";
199 v->init->print(o);
200 }
201 o << endl;
202 }
203
204 if (s.functions.size() > 0)
205 o << _("# functions") << endl;
206 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
207 {
208 assert_no_interrupts();
209 functiondecl* f = it->second;
210 f->printsig (o);
211 o << endl;
212 if (f->locals.size() > 0)
213 o << _(" # locals") << endl;
214 for (unsigned j=0; j<f->locals.size(); j++)
215 {
216 vardecl* v = f->locals[j];
217 o << " ";
218 v->printsig (o);
219 o << endl;
220 }
221 if (s.verbose)
222 {
223 f->body->print (o);
224 o << endl;
225 }
226 }
227
228 if (s.probes.size() > 0)
229 o << _("# probes") << endl;
230 for (unsigned i=0; i<s.probes.size(); i++)
231 {
232 assert_no_interrupts();
233 derived_probe* p = s.probes[i];
234 p->printsig (o);
235 o << endl;
236 if (p->locals.size() > 0)
237 o << _(" # locals") << endl;
238 for (unsigned j=0; j<p->locals.size(); j++)
239 {
240 vardecl* v = p->locals[j];
241 o << " ";
242 v->printsig (o);
243 o << endl;
244 }
245 if (s.verbose)
246 {
247 p->body->print (o);
248 o << endl;
249 }
250 }
251 }
252 }
253
254
255 int pending_interrupts;
256
257 extern "C"
258 void handle_interrupt (int)
259 {
260 // This might be nice, but we don't know our current verbosity...
261 // clog << _F("Received signal %d", sig) << endl << flush;
262 kill_stap_spawn(SIGTERM);
263
264 pending_interrupts ++;
265 // Absorb the first two signals. This used to be one, but when
266 // stap is run under sudo, and then interrupted, sudo relays a
267 // redundant copy of the signal to stap, leading to an unclean shutdown.
268 if (pending_interrupts > 2) // XXX: should be configurable? time-based?
269 {
270 char msg[] = "Too many interrupts received, exiting.\n";
271 int rc = write (2, msg, sizeof(msg)-1);
272 if (rc) {/* Do nothing; we don't care if our last gasp went out. */ ;}
273 _exit (1);
274 }
275 }
276
277
278 void
279 setup_signals (sighandler_t handler)
280 {
281 struct sigaction sa;
282
283 memset(&sa, 0, sizeof(sa));
284 sa.sa_handler = handler;
285 sigemptyset (&sa.sa_mask);
286 if (handler != SIG_IGN)
287 {
288 sigaddset (&sa.sa_mask, SIGHUP);
289 sigaddset (&sa.sa_mask, SIGPIPE);
290 sigaddset (&sa.sa_mask, SIGINT);
291 sigaddset (&sa.sa_mask, SIGTERM);
292 sigaddset (&sa.sa_mask, SIGXFSZ);
293 sigaddset (&sa.sa_mask, SIGXCPU);
294 }
295 sa.sa_flags = SA_RESTART;
296
297 sigaction (SIGHUP, &sa, NULL);
298 sigaction (SIGPIPE, &sa, NULL);
299 sigaction (SIGINT, &sa, NULL);
300 sigaction (SIGTERM, &sa, NULL);
301 sigaction (SIGXFSZ, &sa, NULL);
302 sigaction (SIGXCPU, &sa, NULL);
303 }
304
305
306 static void*
307 sdt_benchmark_thread(void* p)
308 {
309 unsigned long i = *(unsigned long*)p;
310 PROBE(stap, benchmark__thread__start);
311 while (i--)
312 PROBE1(stap, benchmark, i);
313 PROBE(stap, benchmark__thread__end);
314 return NULL;
315 }
316
317
318 static int
319 run_sdt_benchmark(systemtap_session& s)
320 {
321 unsigned long loops = s.benchmark_sdt_loops ?: 10000000;
322 unsigned long threads = s.benchmark_sdt_threads ?: 1;
323
324 if (s.verbose > 0)
325 clog << _F("Beginning SDT benchmark with %lu loops in %lu threads.",
326 loops, threads) << endl;
327
328 struct tms tms_before, tms_after;
329 struct timeval tv_before, tv_after;
330 unsigned _sc_clk_tck = sysconf (_SC_CLK_TCK);
331 times (& tms_before);
332 gettimeofday (&tv_before, NULL);
333
334 PROBE(stap, benchmark__start);
335
336 pthread_t pthreads[threads];
337 for (unsigned long i = 0; i < threads; ++i)
338 pthread_create(&pthreads[i], NULL, sdt_benchmark_thread, &loops);
339 for (unsigned long i = 0; i < threads; ++i)
340 pthread_join(pthreads[i], NULL);
341
342 PROBE(stap, benchmark__end);
343
344 times (& tms_after);
345 gettimeofday (&tv_after, NULL);
346 if (s.verbose > 0)
347 clog << _F("Completed SDT benchmark in %ldusr/%ldsys/%ldreal ms.",
348 (long)(tms_after.tms_utime - tms_before.tms_utime) * 1000 / _sc_clk_tck,
349 (long)(tms_after.tms_stime - tms_before.tms_stime) * 1000 / _sc_clk_tck,
350 (long)((tv_after.tv_sec - tv_before.tv_sec) * 1000 +
351 ((long)tv_after.tv_usec - (long)tv_before.tv_usec) / 1000))
352 << endl;
353
354 return EXIT_SUCCESS;
355 }
356
357
358 // Compilation passes 0 through 4
359 int
360 passes_0_4 (systemtap_session &s)
361 {
362 int rc = 0;
363
364 // If we don't know the release, there's no hope either locally or on a server.
365 if (s.kernel_release.empty())
366 {
367 if (s.kernel_build_tree.empty())
368 cerr << _("ERROR: kernel release isn't specified") << endl;
369 else
370 cerr << _F("ERROR: kernel release isn't found in \"%s\"",
371 s.kernel_build_tree.c_str()) << endl;
372 return 1;
373 }
374
375 // Perform passes 0 through 4 using a compile server?
376 if (! s.specified_servers.empty ())
377 {
378 #if HAVE_NSS
379 compile_server_client client (s);
380 return client.passes_0_4 ();
381 #else
382 s.print_warning(_("Without NSS, using a compile-server is not supported by this version of systemtap"));
383
384 // This cannot be an attempt to use a server after a local compile failed
385 // since --use-server-on-error is locked to 'no' if we don't have
386 // NSS.
387 assert (! s.try_server ());
388 s.print_warning(_("Ignoring --use-server"));
389 #endif
390 }
391
392 // PASS 0: setting up
393 s.verbose = s.perpass_verbose[0];
394 PROBE1(stap, pass0__start, &s);
395
396 // For PR1477, we used to override $PATH and $LC_ALL and other stuff
397 // here. We seem to use complete pathnames in
398 // buildrun.cxx/tapsets.cxx now, so this is not necessary. Further,
399 // it interferes with util.cxx:find_executable(), used for $PATH
400 // resolution.
401
402 s.kernel_base_release.assign(s.kernel_release, 0, s.kernel_release.find('-'));
403
404 // Update various paths to include the sysroot, if provided.
405 if (!s.sysroot.empty())
406 {
407 if (s.update_release_sysroot && !s.sysroot.empty())
408 s.kernel_build_tree = s.sysroot + s.kernel_build_tree;
409 debuginfo_path_insert_sysroot(s.sysroot);
410 }
411
412 // Now that no further changes to s.kernel_build_tree can occur, let's use it.
413 if (s.runtime_mode == systemtap_session::kernel_runtime) {
414 if ((rc = s.parse_kernel_config ()) != 0
415 || (rc = s.parse_kernel_exports ()) != 0
416 || (rc = s.parse_kernel_functions ()) != 0)
417 {
418 // Try again with a server
419 s.set_try_server ();
420 return rc;
421 }
422 }
423
424 // Create the name of the C source file within the temporary
425 // directory. Note the _src prefix, explained in
426 // buildrun.cxx:compile_pass()
427 s.translated_source = string(s.tmpdir) + "/" + s.module_name + "_src.c";
428
429 PROBE1(stap, pass0__end, &s);
430
431 struct tms tms_before;
432 times (& tms_before);
433 struct timeval tv_before;
434 gettimeofday (&tv_before, NULL);
435
436 // PASS 1a: PARSING LIBRARY SCRIPTS
437 PROBE1(stap, pass1a__start, &s);
438
439 if (! s.pass_1a_complete)
440 {
441 // We need to handle the library scripts first because this pass
442 // gathers information on .stpm files that might be needed to
443 // parse the user script.
444
445 // We need to first ascertain the status of the user script, though.
446 struct stat user_file_stat;
447 int user_file_stat_rc = -1;
448
449 if (s.script_file == "-")
450 {
451 user_file_stat_rc = fstat (STDIN_FILENO, & user_file_stat);
452 }
453 else if (s.script_file != "")
454 {
455 user_file_stat_rc = stat (s.script_file.c_str(), & user_file_stat);
456 }
457 // otherwise, rc is 0 for a command line script
458
459 vector<string> version_suffixes;
460 if (s.runtime_mode == systemtap_session::kernel_runtime)
461 {
462 // Construct kernel-versioning search path
463 string kvr = s.kernel_release;
464
465 // add full kernel-version-release (2.6.NN-FOOBAR)
466 version_suffixes.push_back ("/" + kvr);
467
468 // add kernel version (2.6.NN)
469 if (kvr != s.kernel_base_release)
470 {
471 kvr = s.kernel_base_release;
472 version_suffixes.push_back ("/" + kvr);
473 }
474
475 // add kernel family (2.6)
476 string::size_type dot1_index = kvr.find ('.');
477 string::size_type dot2_index = kvr.rfind ('.');
478 while (dot2_index > dot1_index && dot2_index != string::npos)
479 {
480 kvr.erase(dot2_index);
481 version_suffixes.push_back ("/" + kvr);
482 dot2_index = kvr.rfind ('.');
483 }
484 }
485
486 // add empty string as last element
487 version_suffixes.push_back ("");
488
489 // Add arch variants of every path, just before each
490 const string& arch = s.architecture;
491 for (unsigned i=0; i<version_suffixes.size(); i+=2)
492 version_suffixes.insert(version_suffixes.begin() + i,
493 version_suffixes[i] + "/" + arch);
494
495 // Add runtime variants of every path, before everything else
496 string runtime_prefix;
497 if (s.runtime_mode == systemtap_session::kernel_runtime)
498 runtime_prefix = "/linux";
499 else if (s.runtime_mode == systemtap_session::dyninst_runtime)
500 runtime_prefix = "/dyninst";
501 if (!runtime_prefix.empty())
502 for (unsigned i=0; i<version_suffixes.size(); i+=2)
503 version_suffixes.insert(version_suffixes.begin() + i/2,
504 runtime_prefix + version_suffixes[i]);
505
506 // First, parse .stpm files on the include path. We need to have the
507 // resulting macro definitions available for parsing library files,
508 // but since .stpm files can consist only of '@define' constructs,
509 // we can parse each one without reference to the others.
510 set<pair<dev_t, ino_t> > seen_library_macro_files;
511 set<string> seen_library_macro_files_names;
512
513 for (unsigned i=0; i<s.include_path.size(); i++)
514 {
515 // now iterate upon it
516 for (unsigned k=0; k<version_suffixes.size(); k++)
517 {
518 glob_t globbuf;
519 string dir = s.include_path[i] + version_suffixes[k] + "/*.stpm";
520 int r = glob(dir.c_str (), 0, NULL, & globbuf);
521 if (r == GLOB_NOSPACE || r == GLOB_ABORTED)
522 rc ++;
523 // GLOB_NOMATCH is acceptable
524
525 unsigned prev_s_library_files = s.library_files.size();
526
527 for (unsigned j=0; j<globbuf.gl_pathc; j++)
528 {
529 assert_no_interrupts();
530
531 struct stat tapset_file_stat;
532 int stat_rc = stat (globbuf.gl_pathv[j], & tapset_file_stat);
533 if (stat_rc == 0 && user_file_stat_rc == 0 &&
534 user_file_stat.st_dev == tapset_file_stat.st_dev &&
535 user_file_stat.st_ino == tapset_file_stat.st_ino)
536 {
537 cerr
538 << _F("usage error: macro tapset file '%s' cannot be run directly as a session script.",
539 globbuf.gl_pathv[j]) << endl;
540 rc ++;
541 }
542
543 // PR11949: duplicate-eliminate tapset files
544 if (stat_rc == 0)
545 {
546 pair<dev_t,ino_t> here = make_pair(tapset_file_stat.st_dev,
547 tapset_file_stat.st_ino);
548 if (seen_library_macro_files.find(here) != seen_library_macro_files.end())
549 {
550 if (s.verbose>2)
551 clog << _F("Skipping tapset \"%s\", duplicate inode.", globbuf.gl_pathv[j]) << endl;
552 continue;
553 }
554 seen_library_macro_files.insert (here);
555 }
556
557 // PR12443: duplicate-eliminate harder
558 string full_path = globbuf.gl_pathv[j];
559 string tapset_base = s.include_path[i]; // not dir; it has arch suffixes too
560 if (full_path.size() > tapset_base.size())
561 {
562 string tail_part = full_path.substr(tapset_base.size());
563 if (seen_library_macro_files_names.find (tail_part) != seen_library_macro_files_names.end())
564 {
565 if (s.verbose>2)
566 clog << _F("Skipping tapset \"%s\", duplicate name.", globbuf.gl_pathv[j]) << endl;
567 continue;
568 }
569 seen_library_macro_files_names.insert (tail_part);
570 }
571
572 if (s.verbose>2)
573 clog << _F("Processing tapset \"%s\"", globbuf.gl_pathv[j]) << endl;
574
575 stapfile* f = parse_library_macros (s, globbuf.gl_pathv[j]);
576 if (f == 0)
577 s.print_warning(_F("macro tapset \"%s\" has errors, and will be skipped.", string(globbuf.gl_pathv[j]).c_str()));
578 else
579 s.library_files.push_back (f);
580 }
581
582 unsigned next_s_library_files = s.library_files.size();
583 if (s.verbose>1 && globbuf.gl_pathc > 0)
584 //TRANSLATORS: Searching through directories, 'processed' means 'examined so far'
585 clog << _F("Searched for library macro files: \"%s\", found: %zu, processed: %u",
586 dir.c_str(), globbuf.gl_pathc,
587 (next_s_library_files-prev_s_library_files)) << endl;
588
589 globfree (&globbuf);
590 }
591 }
592
593 // Next, gather and parse the library files.
594 set<pair<dev_t, ino_t> > seen_library_files;
595 set<string> seen_library_files_names;
596
597 for (unsigned i=0; i<s.include_path.size(); i++)
598 {
599 unsigned tapset_flags = pf_guru | pf_squash_errors;
600
601 // The first path is special, as it's the builtin tapset.
602 // Allow all features no matter what s.compatible says.
603 if (i == 0)
604 tapset_flags |= pf_no_compatible;
605
606 // now iterate upon it
607 for (unsigned k=0; k<version_suffixes.size(); k++)
608 {
609 glob_t globbuf;
610 string dir = s.include_path[i] + version_suffixes[k] + "/*.stp";
611 int r = glob(dir.c_str (), 0, NULL, & globbuf);
612 if (r == GLOB_NOSPACE || r == GLOB_ABORTED)
613 rc ++;
614 // GLOB_NOMATCH is acceptable
615
616 unsigned prev_s_library_files = s.library_files.size();
617
618 for (unsigned j=0; j<globbuf.gl_pathc; j++)
619 {
620 assert_no_interrupts();
621
622 struct stat tapset_file_stat;
623 int stat_rc = stat (globbuf.gl_pathv[j], & tapset_file_stat);
624 if (stat_rc == 0 && user_file_stat_rc == 0 &&
625 user_file_stat.st_dev == tapset_file_stat.st_dev &&
626 user_file_stat.st_ino == tapset_file_stat.st_ino)
627 {
628 cerr
629 << _F("usage error: tapset file '%s' cannot be run directly as a session script.",
630 globbuf.gl_pathv[j]) << endl;
631 rc ++;
632 }
633
634 // PR11949: duplicate-eliminate tapset files
635 if (stat_rc == 0)
636 {
637 pair<dev_t,ino_t> here = make_pair(tapset_file_stat.st_dev,
638 tapset_file_stat.st_ino);
639 if (seen_library_files.find(here) != seen_library_files.end())
640 {
641 if (s.verbose>2)
642 clog << _F("Skipping tapset \"%s\", duplicate inode.", globbuf.gl_pathv[j]) << endl;
643 continue;
644 }
645 seen_library_files.insert (here);
646 }
647
648 // PR12443: duplicate-eliminate harder
649 string full_path = globbuf.gl_pathv[j];
650 string tapset_base = s.include_path[i]; // not dir; it has arch suffixes too
651 if (full_path.size() > tapset_base.size())
652 {
653 string tail_part = full_path.substr(tapset_base.size());
654 if (seen_library_files_names.find (tail_part) != seen_library_files_names.end())
655 {
656 if (s.verbose>2)
657 clog << _F("Skipping tapset \"%s\", duplicate name.", globbuf.gl_pathv[j]) << endl;
658 continue;
659 }
660 seen_library_files_names.insert (tail_part);
661 }
662
663 if (s.verbose>2)
664 clog << _F("Processing tapset \"%s\"", globbuf.gl_pathv[j]) << endl;
665
666 // NB: we don't need to restrict privilege only for
667 // /usr/share/systemtap, i.e., excluding
668 // user-specified $XDG_DATA_DIRS. That's because
669 // stapdev gets root-equivalent privileges anyway;
670 // stapsys and stapusr use a remote compilation with
671 // a trusted environment, where client-side
672 // $XDG_DATA_DIRS are not passed.
673
674 stapfile* f = parse (s, globbuf.gl_pathv[j], tapset_flags);
675 if (f == 0)
676 s.print_warning(_F("tapset \"%s\" has errors, and will be skipped", string(globbuf.gl_pathv[j]).c_str()));
677 else
678 s.library_files.push_back (f);
679 }
680
681 unsigned next_s_library_files = s.library_files.size();
682 if (s.verbose>1 && globbuf.gl_pathc > 0)
683 //TRANSLATORS: Searching through directories, 'processed' means 'examined so far'
684 clog << _F("Searched: \"%s\", found: %zu, processed: %u",
685 dir.c_str(), globbuf.gl_pathc,
686 (next_s_library_files-prev_s_library_files)) << endl;
687
688 globfree (& globbuf);
689 }
690 }
691 if (s.num_errors())
692 rc ++;
693
694 // Now that we've made it through pass 1a, remember this so we
695 // don't have to do this again in interactive mode. This doesn't
696 // effect non-interactive mode.
697 s.pass_1a_complete = true;
698 }
699
700 // PASS 1b: PARSING USER SCRIPT
701 PROBE1(stap, pass1b__start, &s);
702
703 // Only try to parse a user script if the user provided one, or if we have to
704 // make one (as is the case for listing mode). Otherwise, s.user_script
705 // remains NULL.
706 if (!s.script_file.empty() ||
707 !s.cmdline_script.empty() ||
708 s.dump_mode == systemtap_session::dump_matched_probes ||
709 s.dump_mode == systemtap_session::dump_matched_probes_vars)
710 {
711 unsigned user_flags = s.guru_mode ? pf_guru : 0;
712 if (s.script_file == "-")
713 {
714 s.user_files.push_back (parse (s, "<input>", cin, user_flags));
715 }
716 else if (s.script_file != "")
717 {
718 s.user_files.push_back (parse (s, s.script_file, user_flags));
719 }
720 else if (s.cmdline_script != "")
721 {
722 istringstream ii (s.cmdline_script);
723 s.user_files.push_back(parse (s, "<input>", ii, user_flags));
724 }
725 else // listing mode
726 {
727 istringstream ii ("probe " + s.dump_matched_pattern + " {}");
728 s.user_files.push_back (parse (s, "<input>", ii, user_flags));
729 }
730
731 // parses the additional script(s) (-E script). does so even if in listing
732 // mode, incase there is something special in the additional script(s),
733 // like a macro or alias. give them a unique name to differentiate the
734 // scripts that were inputted.
735 unsigned count = 1;
736 for (vector<string>::iterator script = s.additional_scripts.begin(); script != s.additional_scripts.end(); script++)
737 {
738 string input_name = "<input" + lex_cast(count) + ">";
739 istringstream ii (*script);
740 s.user_files.push_back(parse (s, input_name, ii, user_flags));
741 count ++;
742 }
743
744 for(vector<stapfile*>::iterator it = s.user_files.begin(); it != s.user_files.end(); it++)
745 {
746 if (!(*it))
747 {
748 // Syntax errors already printed.
749 rc ++;
750 }
751 }
752 }
753
754 // Dump a list of probe aliases picked up, if requested
755 if (s.dump_mode == systemtap_session::dump_probe_aliases)
756 {
757 set<string> aliases;
758 vector<stapfile*>::const_iterator file;
759 for (file = s.library_files.begin();
760 file != s.library_files.end(); ++file)
761 {
762 vector<probe_alias*>::const_iterator alias;
763 for (alias = (*file)->aliases.begin();
764 alias != (*file)->aliases.end(); ++alias)
765 {
766 stringstream ss;
767 (*alias)->printsig(ss);
768 string str = ss.str();
769 if (!s.verbose && startswith(str, "_"))
770 continue;
771 aliases.insert(str);
772 }
773 }
774
775 set<string>::iterator alias;
776 for (alias = aliases.begin();
777 alias != aliases.end(); ++alias)
778 {
779 cout << *alias << endl;
780 }
781 }
782 // Dump the parse tree if this is the last pass
783 else if (rc == 0 && s.last_pass == 1)
784 {
785 cout << _("# parse tree dump") << endl;
786 for (vector<stapfile*>::iterator it = s.user_files.begin(); it != s.user_files.end(); it++)
787 (*it)->print (cout);
788 cout << endl;
789 if (s.verbose)
790 for (unsigned i=0; i<s.library_files.size(); i++)
791 {
792 s.library_files[i]->print (cout);
793 cout << endl;
794 }
795 }
796
797 struct tms tms_after;
798 times (& tms_after);
799 unsigned _sc_clk_tck = sysconf (_SC_CLK_TCK);
800 struct timeval tv_after;
801 gettimeofday (&tv_after, NULL);
802
803 #define TIMESPRINT _("in ") << \
804 (tms_after.tms_cutime + tms_after.tms_utime \
805 - tms_before.tms_cutime - tms_before.tms_utime) * 1000 / (_sc_clk_tck) << "usr/" \
806 << (tms_after.tms_cstime + tms_after.tms_stime \
807 - tms_before.tms_cstime - tms_before.tms_stime) * 1000 / (_sc_clk_tck) << "sys/" \
808 << ((tv_after.tv_sec - tv_before.tv_sec) * 1000 + \
809 ((long)tv_after.tv_usec - (long)tv_before.tv_usec) / 1000) << "real ms."
810
811 // syntax errors, if any, are already printed
812 if (s.verbose)
813 {
814 // XXX also include a count of helper macro files loaded (.stpm)?
815 int n = int(s.library_files.size());
816 clog << _("Pass 1: parsed user script and ")
817 << _NF("%d library script ", "%d library scripts ", n, n)
818 << getmemusage()
819 << TIMESPRINT
820 << endl;
821 }
822
823 if (rc && !s.dump_mode)
824 cerr << _("Pass 1: parse failed. [man error::pass1]") << endl;
825
826 PROBE1(stap, pass1__end, &s);
827
828 assert_no_interrupts();
829 if (rc || s.last_pass == 1 ||
830 s.dump_mode == systemtap_session::dump_probe_aliases)
831 return rc;
832
833 times (& tms_before);
834 gettimeofday (&tv_before, NULL);
835
836 // PASS 2: ELABORATION
837 s.verbose = s.perpass_verbose[1];
838 PROBE1(stap, pass2__start, &s);
839 rc = semantic_pass (s);
840
841 // Dump a list of known probe point types, if requested.
842 if (s.dump_mode == systemtap_session::dump_probe_types)
843 s.pattern_root->dump (s);
844 // Dump a list of functions we picked up, if requested.
845 else if (s.dump_mode == systemtap_session::dump_functions)
846 {
847 map<string,functiondecl*>::const_iterator func;
848 for (func = s.functions.begin();
849 func != s.functions.end(); ++func)
850 {
851 functiondecl& curfunc = *func->second;
852 if (curfunc.synthetic)
853 continue;
854 if (!startswith(curfunc.name, "__global_"))
855 continue;
856 if (!s.verbose && startswith(curfunc.name, "__global__"))
857 continue;
858 curfunc.printsigtags(cout, s.verbose>0 /* all_tags */ );
859 cout << endl;
860 }
861 }
862 // Dump the whole script if requested, or if we stop at 2
863 else if (s.dump_mode == systemtap_session::dump_matched_probes ||
864 s.dump_mode == systemtap_session::dump_matched_probes_vars ||
865 (rc == 0 && s.last_pass == 2))
866 printscript(s, cout);
867
868 times (& tms_after);
869 gettimeofday (&tv_after, NULL);
870
871 if (s.verbose) {
872 int np = s.probes.size();
873 int nf = s.functions.size();
874 int ne = s.embeds.size();
875 int ng = s.globals.size();
876 clog << _("Pass 2: analyzed script: ")
877 << _NF("%d probe, ", "%d probes, ", np, np)
878 << _NF("%d function, ", "%d functions, ", nf, nf)
879 << _NF("%d embed, ", "%d embeds, ", ne, ne)
880 << _NF("%d global ", "%d globals ", ng, ng)
881 << getmemusage()
882 << TIMESPRINT
883 << endl;
884 }
885
886 if (rc && !s.dump_mode && !s.try_server ())
887 cerr << _("Pass 2: analysis failed. [man error::pass2]") << endl;
888
889 PROBE1(stap, pass2__end, &s);
890
891 assert_no_interrupts();
892 // NB: none of the dump modes need to go beyond pass-2. If this changes, break
893 // into individual modes here.
894 if (rc || s.last_pass == 2 || s.dump_mode)
895 return rc;
896
897 rc = prepare_translate_pass (s);
898 assert_no_interrupts();
899 if (rc) return rc;
900
901 // Generate hash. There isn't any point in generating the hash
902 // if last_pass is 2, since we'll quit before using it.
903 if (s.use_script_cache)
904 {
905 ostringstream o;
906 unsigned saved_verbose;
907
908 {
909 // Make sure we're in verbose mode, so that printscript()
910 // will output function/probe bodies.
911 saved_verbose = s.verbose;
912 s.verbose = 3;
913 printscript(s, o); // Print script to 'o'
914 s.verbose = saved_verbose;
915 }
916
917 // Generate hash
918 find_script_hash (s, o.str());
919
920 // See if we can use cached source/module.
921 if (get_script_from_cache(s))
922 {
923 // We may still need to build uprobes, if it's not also cached.
924 if (s.need_uprobes)
925 rc = uprobes_pass(s);
926
927 // If our last pass isn't 5, we're done (since passes 3 and
928 // 4 just generate what we just pulled out of the cache).
929 assert_no_interrupts();
930 if (rc || s.last_pass < 5) return rc;
931
932 // Short-circuit to pass 5.
933 return 0;
934 }
935 }
936
937 // PASS 3: TRANSLATION
938 s.verbose = s.perpass_verbose[2];
939 times (& tms_before);
940 gettimeofday (&tv_before, NULL);
941 PROBE1(stap, pass3__start, &s);
942
943 rc = translate_pass (s);
944 if (! rc && s.last_pass == 3)
945 {
946 ifstream i (s.translated_source.c_str());
947 cout << i.rdbuf();
948 }
949
950 times (& tms_after);
951 gettimeofday (&tv_after, NULL);
952
953 if (s.verbose)
954 clog << _("Pass 3: translated to C into \"")
955 << s.translated_source
956 << "\" "
957 << getmemusage()
958 << TIMESPRINT
959 << endl;
960
961 if (rc && ! s.try_server ())
962 cerr << _("Pass 3: translation failed. [man error::pass3]") << endl;
963
964 PROBE1(stap, pass3__end, &s);
965
966 assert_no_interrupts();
967 if (rc || s.last_pass == 3) return rc;
968
969 // PASS 4: COMPILATION
970 s.verbose = s.perpass_verbose[3];
971 times (& tms_before);
972 gettimeofday (&tv_before, NULL);
973 PROBE1(stap, pass4__start, &s);
974
975 if (s.use_cache)
976 {
977 find_stapconf_hash(s);
978 get_stapconf_from_cache(s);
979 }
980 rc = compile_pass (s);
981 if (! rc && s.last_pass == 4)
982 {
983 cout << ((s.hash_path == "") ? s.module_filename() : s.hash_path);
984 cout << endl;
985 }
986
987 times (& tms_after);
988 gettimeofday (&tv_after, NULL);
989
990 if (s.verbose) clog << _("Pass 4: compiled C into \"")
991 << s.module_filename()
992 << "\" "
993 << TIMESPRINT
994 << endl;
995
996 if (rc && ! s.try_server ())
997 cerr << _("Pass 4: compilation failed. [man error::pass4]") << endl;
998
999 else
1000 {
1001 // Update cache. Cache cleaning is kicked off at the beginning of this function.
1002 if (s.use_script_cache)
1003 add_script_to_cache(s);
1004 if (s.use_cache && !s.runtime_usermode_p())
1005 add_stapconf_to_cache(s);
1006
1007 // We may need to save the module in $CWD if the cache was
1008 // inaccessible for some reason.
1009 if (! s.use_script_cache && s.last_pass == 4)
1010 s.save_module = true;
1011
1012 // Copy module to the current directory.
1013 if (s.save_module && !pending_interrupts)
1014 {
1015 string module_src_path = s.tmpdir + "/" + s.module_filename();
1016 string module_dest_path = s.module_filename();
1017 copy_file(module_src_path, module_dest_path, s.verbose > 1);
1018 }
1019
1020 // Copy uprobes module to the current directory.
1021 if (s.save_uprobes && !s.uprobes_path.empty() && !pending_interrupts)
1022 {
1023 rc = create_dir("uprobes");
1024 if (! rc)
1025 copy_file(s.uprobes_path, "uprobes/uprobes.ko", s.verbose > 1);
1026 }
1027 }
1028
1029 PROBE1(stap, pass4__end, &s);
1030
1031 return rc;
1032 }
1033
1034 int
1035 pass_5 (systemtap_session &s, vector<remote*> targets)
1036 {
1037 // PASS 5: RUN
1038 s.verbose = s.perpass_verbose[4];
1039 struct tms tms_before;
1040 times (& tms_before);
1041 struct timeval tv_before;
1042 gettimeofday (&tv_before, NULL);
1043 // NB: this message is a judgement call. The other passes don't emit
1044 // a "hello, I'm starting" message, but then the others aren't interactive
1045 // and don't take an indefinite amount of time.
1046 PROBE1(stap, pass5__start, &s);
1047 if (s.verbose) clog << _("Pass 5: starting run.") << endl;
1048 int rc = remote::run(targets);
1049 struct tms tms_after;
1050 times (& tms_after);
1051 unsigned _sc_clk_tck = sysconf (_SC_CLK_TCK);
1052 struct timeval tv_after;
1053 gettimeofday (&tv_after, NULL);
1054 if (s.verbose) clog << _("Pass 5: run completed ")
1055 << TIMESPRINT
1056 << endl;
1057
1058 if (rc)
1059 cerr << _("Pass 5: run failed. [man error::pass5]") << endl;
1060 else
1061 // Interrupting pass-5 to quit is normal, so we want an EXIT_SUCCESS below.
1062 pending_interrupts = 0;
1063
1064 PROBE1(stap, pass5__end, &s);
1065
1066 return rc;
1067 }
1068
1069 static void
1070 cleanup (systemtap_session &s, int rc)
1071 {
1072 // PASS 6: cleaning up
1073 PROBE1(stap, pass6__start, &s);
1074
1075 for (systemtap_session::session_map_t::iterator it = s.subsessions.begin();
1076 it != s.subsessions.end(); ++it)
1077 cleanup (*it->second, rc);
1078
1079 // update the database information
1080 if (!rc && s.tapset_compile_coverage && !pending_interrupts) {
1081 #ifdef HAVE_LIBSQLITE3
1082 update_coverage_db(s);
1083 #else
1084 cerr << _("Coverage database not available without libsqlite3") << endl;
1085 #endif
1086 }
1087
1088 s.report_suppression();
1089
1090 PROBE1(stap, pass6__end, &s);
1091 }
1092
1093 static int
1094 passes_0_4_again_with_server (systemtap_session &s)
1095 {
1096 // Not a server and not already using a server.
1097 assert (! s.client_options);
1098 assert (s.specified_servers.empty ());
1099
1100 // Specify default server(s).
1101 s.specified_servers.push_back ("");
1102
1103 // Reset the previous temporary directory and start fresh
1104 s.reset_tmp_dir();
1105
1106 // Try to compile again, using the server
1107 clog << _("Attempting compilation using a compile server")
1108 << endl;
1109
1110 int rc = passes_0_4 (s);
1111 return rc;
1112 }
1113
1114 int
1115 main (int argc, char * const argv [])
1116 {
1117 // Initialize defaults.
1118 try {
1119 systemtap_session s;
1120 #if ENABLE_NLS
1121 setlocale (LC_ALL, "");
1122 bindtextdomain (PACKAGE, LOCALEDIR);
1123 textdomain (PACKAGE);
1124 #endif
1125
1126 // Set up our handler to catch routine signals, to allow clean
1127 // and reasonably timely exit.
1128 setup_signals(&handle_interrupt);
1129
1130 // PR13520: Parse $SYSTEMTAP_DIR/rc for extra options
1131 string rc_file = s.data_path + "/rc";
1132 ifstream rcf (rc_file.c_str());
1133 string rcline;
1134 wordexp_t words;
1135 memset (& words, 0, sizeof(words));
1136 int rc = 0;
1137 int linecount = 0;
1138 while (getline (rcf, rcline))
1139 {
1140 rc = wordexp (rcline.c_str(), & words, WRDE_NOCMD|WRDE_UNDEF|
1141 (linecount > 0 ? WRDE_APPEND : 0));
1142 // NB: WRDE_APPEND automagically reallocates words.* as more options are added.
1143 linecount ++;
1144 if (rc) break;
1145 }
1146 int extended_argc = words.we_wordc + argc;
1147 char **extended_argv = (char**) calloc (extended_argc + 1, sizeof(char*));
1148 if (rc || !extended_argv)
1149 {
1150 clog << _F("Error processing extra options in %s", rc_file.c_str());
1151 return EXIT_FAILURE;
1152 }
1153 // Copy over the arguments *by reference*, first the ones from the rc file.
1154 char **p = & extended_argv[0];
1155 *p++ = argv[0];
1156 for (unsigned i=0; i<words.we_wordc; i++) *p++ = words.we_wordv[i];
1157 for (int j=1; j<argc; j++) *p++ = argv[j];
1158 *p++ = NULL;
1159
1160 // Process the command line.
1161 rc = s.parse_cmdline (extended_argc, extended_argv);
1162 if (rc != 0)
1163 return rc;
1164
1165 if (words.we_wordc > 0 && s.verbose > 1)
1166 clog << _F("Extra options in %s: %d\n", rc_file.c_str(), (int)words.we_wordc);
1167
1168 // Check for options conflicts. Exits if errors are detected.
1169 s.check_options (extended_argc, extended_argv);
1170
1171 // We don't need these strings any more.
1172 wordfree (& words);
1173 free (extended_argv);
1174
1175 // arguments parsed; get down to business
1176 if (s.verbose > 1)
1177 s.version ();
1178
1179 // Need to send the verbose message here, rather than in the session ctor, since
1180 // we didn't know if verbose was set.
1181 if (rc == 0 && s.verbose>1)
1182 clog << _F("Created temporary directory \"%s\"", s.tmpdir.c_str()) << endl;
1183
1184 // Run the benchmark and quit right away.
1185 if (s.benchmark_sdt_loops || s.benchmark_sdt_threads)
1186 return run_sdt_benchmark(s);
1187
1188 // Prepare connections for each specified remote target.
1189 vector<remote*> targets;
1190 bool fake_remote=false;
1191 if (s.remote_uris.empty())
1192 {
1193 fake_remote=true;
1194 s.remote_uris.push_back("direct:");
1195 }
1196 for (unsigned i = 0; rc == 0 && i < s.remote_uris.size(); ++i)
1197 {
1198 // PR13354: pass remote id#/url only in non --remote=HOST cases
1199 remote *target = remote::create(s, s.remote_uris[i],
1200 fake_remote ? -1 : (int)i);
1201 if (target)
1202 targets.push_back(target);
1203 else
1204 rc = 1;
1205 }
1206
1207 // Discover and loop over each unique session created by the remote targets.
1208 set<systemtap_session*> sessions;
1209 for (unsigned i = 0; i < targets.size(); ++i)
1210 sessions.insert(targets[i]->get_session());
1211
1212 // FIXME: For now, only attempt local interactive use.
1213 if (s.interactive_mode && fake_remote)
1214 {
1215 #ifdef HAVE_LIBREADLINE
1216 rc = interactive_mode (s, targets);
1217 #endif
1218 }
1219 else
1220 {
1221 for (set<systemtap_session*>::iterator it = sessions.begin();
1222 rc == 0 && !pending_interrupts && it != sessions.end(); ++it)
1223 {
1224 systemtap_session& ss = **it;
1225 if (ss.verbose > 1)
1226 clog << _F("Session arch: %s release: %s",
1227 ss.architecture.c_str(), ss.kernel_release.c_str())
1228 << endl;
1229
1230 #if HAVE_NSS
1231 // If requested, query server status. This is independent
1232 // of other tasks.
1233 query_server_status (ss);
1234
1235 // If requested, manage trust of servers. This is
1236 // independent of other tasks.
1237 manage_server_trust (ss);
1238 #endif
1239
1240 // Run the passes only if a script has been specified or
1241 // if we're dumping something. The requirement for a
1242 // script has already been checked in
1243 // systemtap_session::check_options.
1244 if (ss.have_script || ss.dump_mode)
1245 {
1246 // Run passes 0-4 for each unique session, either
1247 // locally or using a compile-server.
1248 ss.init_try_server ();
1249 if ((rc = passes_0_4 (ss)))
1250 {
1251 // Compilation failed.
1252 // Try again using a server if appropriate.
1253 if (ss.try_server ())
1254 rc = passes_0_4_again_with_server (ss);
1255 }
1256 if (rc || s.perpass_verbose[0] >= 1)
1257 s.explain_auto_options ();
1258 }
1259 }
1260
1261 // Run pass 5, if requested
1262 if (rc == 0 && s.have_script && s.last_pass >= 5 && ! pending_interrupts)
1263 rc = pass_5 (s, targets);
1264 }
1265
1266 // Pass 6. Cleanup
1267 for (unsigned i = 0; i < targets.size(); ++i)
1268 delete targets[i];
1269 cleanup (s, rc);
1270
1271 assert_no_interrupts();
1272 return (rc) ? EXIT_FAILURE : EXIT_SUCCESS;
1273 }
1274 catch (const interrupt_exception& e) {
1275 // User entered ctrl-c, exit quietly.
1276 return EXIT_FAILURE;
1277 }
1278 catch (const exit_exception& e) {
1279 // Exiting for any quiet reason.
1280 return e.rc;
1281 }
1282 catch (const exception &e) {
1283 // Some other uncaught exception.
1284 cerr << e.what() << endl;
1285 return EXIT_FAILURE;
1286 }
1287 catch (...) {
1288 // Catch all other unknown exceptions.
1289 cerr << _("ERROR: caught unknown exception!") << endl;
1290 return EXIT_FAILURE;
1291 }
1292 }
1293
1294 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.100508 seconds and 6 git commands to generate.