• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * @file opgprof_options.cpp
3  * Options for opgprof tool
4  *
5  * @remark Copyright 2003 OProfile authors
6  * @remark Read the file COPYING
7  *
8  * @author John Levon
9  * @author Philippe Elie
10  */
11 
12 #include <cstdlib>
13 
14 #include <vector>
15 #include <list>
16 #include <iterator>
17 #include <iostream>
18 #include <cstdlib>
19 
20 #include "opgprof_options.h"
21 #include "popt_options.h"
22 #include "cverb.h"
23 #include "profile_spec.h"
24 #include "arrange_profiles.h"
25 
26 using namespace std;
27 
28 profile_classes classes;
29 inverted_profile image_profile;
30 
31 namespace options {
32 	string gmon_filename = "gmon.out";
33 
34 	// Ugly, for build only
35 	demangle_type demangle;
36 }
37 
38 
39 namespace {
40 
41 popt::option options_array[] = {
42 	popt::option(options::gmon_filename, "output-filename", 'o',
43 	             "output filename, defaults to gmon.out if not specified",
44 	             "filename"),
45 	popt::option(options::threshold_opt, "threshold", 't',
46 		     "minimum percentage needed to produce output",
47 		     "percent"),
48 };
49 
50 
try_merge_profiles(profile_spec const & spec,bool exclude_dependent)51 bool try_merge_profiles(profile_spec const & spec, bool exclude_dependent)
52 {
53 	list<string> sample_files = spec.generate_file_list(exclude_dependent, false);
54 
55 	cverb << vsfile
56 	      << "Matched sample files: " << sample_files.size() << endl;
57 	copy(sample_files.begin(), sample_files.end(),
58 	     ostream_iterator<string>(cverb << vsfile, "\n"));
59 
60 	// opgprof merge all by default
61 	merge_option merge_by;
62 	merge_by.cpu = true;
63 	merge_by.lib = true;
64 	merge_by.tid = true;
65 	merge_by.tgid = true;
66 	merge_by.unitmask = true;
67 
68 	classes	= arrange_profiles(sample_files, merge_by,
69 				   spec.extra_found_images);
70 
71 	cverb << vsfile << "profile_classes:\n" << classes << endl;
72 
73 	size_t nr_classes = classes.v.size();
74 
75 	list<inverted_profile> iprofiles = invert_profiles(classes);
76 
77 	if (nr_classes == 1 && iprofiles.size() == 1) {
78 		image_profile = *(iprofiles.begin());
79 		return true;
80 	}
81 
82 	// come round for another try
83 	if (exclude_dependent)
84 		return false;
85 
86 	if (iprofiles.empty()) {
87 		cerr << "error: no sample files found: profile specification "
88 		     "too strict ?" << endl;
89 		exit(EXIT_FAILURE);
90 	}
91 
92 	if (nr_classes > 1 || iprofiles.size() > 1) {
93 		cerr << "error: specify exactly one binary to process "
94 		     "and give an event: or count: specification if necessary"
95 		     << endl;
96 		exit(EXIT_FAILURE);
97 	}
98 
99 	return false;
100 }
101 
102 }  // anonymous namespace
103 
104 
handle_options(options::spec const & spec)105 void handle_options(options::spec const & spec)
106 {
107 	if (spec.first.size()) {
108 		cerr << "differential profiles not allowed" << endl;
109 		exit(EXIT_FAILURE);
110 	}
111 
112 	profile_spec const pspec =
113 		profile_spec::create(spec.common, options::image_path,
114 				     options::root_path);
115 
116 	cverb << vsfile << "output filename: " << options::gmon_filename
117 	      << endl;
118 
119 	// we do a first try with exclude-dependent if it fails we include
120 	// dependent. First try should catch "opgrof /usr/bin/make" whilst
121 	// the second catch "opgprof /lib/libc-2.2.5.so"
122 	if (!try_merge_profiles(pspec, true))
123 		try_merge_profiles(pspec, false);
124 }
125