opgprof_options.cpp

Go to the documentation of this file.
00001 
00012 #include <cstdlib>
00013 
00014 #include <vector>
00015 #include <list>
00016 #include <iterator>
00017 #include <iostream>
00018 #include <cstdlib>
00019 
00020 #include "opgprof_options.h"
00021 #include "popt_options.h"
00022 #include "cverb.h"
00023 #include "profile_spec.h"
00024 #include "arrange_profiles.h"
00025 
00026 using namespace std;
00027 
00028 profile_classes classes;
00029 inverted_profile image_profile;
00030 
00031 namespace options {
00032     string gmon_filename = "gmon.out";
00033 
00034     // Ugly, for build only
00035     demangle_type demangle;
00036 }
00037 
00038 
00039 namespace {
00040 
00041 popt::option options_array[] = {
00042     popt::option(options::gmon_filename, "output-filename", 'o',
00043                  "output filename, defaults to gmon.out if not specified",
00044                  "filename"),
00045     popt::option(options::threshold_opt, "threshold", 't',
00046              "minimum percentage needed to produce output",
00047              "percent"),
00048 };
00049 
00050 
00051 bool try_merge_profiles(profile_spec const & spec, bool exclude_dependent)
00052 {
00053     list<string> sample_files = spec.generate_file_list(exclude_dependent, false);
00054 
00055     cverb << vsfile
00056           << "Matched sample files: " << sample_files.size() << endl;
00057     copy(sample_files.begin(), sample_files.end(),
00058          ostream_iterator<string>(cverb << vsfile, "\n"));
00059 
00060     // opgprof merge all by default
00061     merge_option merge_by;
00062     merge_by.cpu = true;
00063     merge_by.lib = true;
00064     merge_by.tid = true;
00065     merge_by.tgid = true;
00066     merge_by.unitmask = true;
00067 
00068     classes = arrange_profiles(sample_files, merge_by,
00069                    spec.extra_found_images);
00070 
00071     cverb << vsfile << "profile_classes:\n" << classes << endl;
00072 
00073     size_t nr_classes = classes.v.size();
00074 
00075     list<inverted_profile> iprofiles = invert_profiles(classes);
00076 
00077     if (nr_classes == 1 && iprofiles.size() == 1) {
00078         image_profile = *(iprofiles.begin());
00079         return true;
00080     }
00081 
00082     // come round for another try
00083     if (exclude_dependent)
00084         return false;
00085 
00086     if (iprofiles.empty()) {
00087         cerr << "error: no sample files found: profile specification "
00088              "too strict ?" << endl;
00089         exit(EXIT_FAILURE);
00090     }
00091 
00092     if (nr_classes > 1 || iprofiles.size() > 1) {
00093         cerr << "error: specify exactly one binary to process "
00094              "and give an event: or count: specification if necessary"
00095              << endl;
00096         exit(EXIT_FAILURE);
00097     }
00098 
00099     return false;
00100 }
00101 
00102 }  // anonymous namespace
00103 
00104 
00105 void handle_options(options::spec const & spec)
00106 {
00107     if (spec.first.size()) {
00108         cerr << "differential profiles not allowed" << endl;
00109         exit(EXIT_FAILURE);
00110     }
00111 
00112     profile_spec const pspec =
00113         profile_spec::create(spec.common, options::image_path,
00114                      options::root_path);
00115 
00116     cverb << vsfile << "output filename: " << options::gmon_filename
00117           << endl;
00118 
00119     // we do a first try with exclude-dependent if it fails we include
00120     // dependent. First try should catch "opgrof /usr/bin/make" whilst
00121     // the second catch "opgprof /lib/libc-2.2.5.so"
00122     if (!try_merge_profiles(pspec, true))
00123         try_merge_profiles(pspec, false);
00124 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1