blob: abeaeac00a734cfc67cd2b69f1a22b113ee93b71 [file] [log] [blame]
Mike Dodd8cfa7022010-11-17 11:12:26 -08001/**
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
26using namespace std;
27
28profile_classes classes;
29inverted_profile image_profile;
30
31namespace options {
32 string gmon_filename = "gmon.out";
33
34 // Ugly, for build only
35 demangle_type demangle;
36}
37
38
39namespace {
40
41popt::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
51bool 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
105void 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}