/** * @file opgprof_options.cpp * Options for opgprof tool * * @remark Copyright 2003 OProfile authors * @remark Read the file COPYING * * @author John Levon * @author Philippe Elie */ #include <cstdlib> #include <vector> #include <list> #include <iterator> #include <iostream> #include <cstdlib> #include "opgprof_options.h" #include "popt_options.h" #include "cverb.h" #include "profile_spec.h" #include "arrange_profiles.h" using namespace std; profile_classes classes; inverted_profile image_profile; namespace options { string gmon_filename = "gmon.out"; // Ugly, for build only demangle_type demangle; } namespace { popt::option options_array[] = { popt::option(options::gmon_filename, "output-filename", 'o', "output filename, defaults to gmon.out if not specified", "filename"), popt::option(options::threshold_opt, "threshold", 't', "minimum percentage needed to produce output", "percent"), }; bool try_merge_profiles(profile_spec const & spec, bool exclude_dependent) { list<string> sample_files = spec.generate_file_list(exclude_dependent, false); cverb << vsfile << "Matched sample files: " << sample_files.size() << endl; copy(sample_files.begin(), sample_files.end(), ostream_iterator<string>(cverb << vsfile, "\n")); // opgprof merge all by default merge_option merge_by; merge_by.cpu = true; merge_by.lib = true; merge_by.tid = true; merge_by.tgid = true; merge_by.unitmask = true; classes = arrange_profiles(sample_files, merge_by, spec.extra_found_images); cverb << vsfile << "profile_classes:\n" << classes << endl; size_t nr_classes = classes.v.size(); list<inverted_profile> iprofiles = invert_profiles(classes); if (nr_classes == 1 && iprofiles.size() == 1) { image_profile = *(iprofiles.begin()); return true; } // come round for another try if (exclude_dependent) return false; if (iprofiles.empty()) { cerr << "error: no sample files found: profile specification " "too strict ?" << endl; exit(EXIT_FAILURE); } if (nr_classes > 1 || iprofiles.size() > 1) { cerr << "error: specify exactly one binary to process " "and give an event: or count: specification if necessary" << endl; exit(EXIT_FAILURE); } return false; } } // anonymous namespace void handle_options(options::spec const & spec) { if (spec.first.size()) { cerr << "differential profiles not allowed" << endl; exit(EXIT_FAILURE); } profile_spec const pspec = profile_spec::create(spec.common, options::image_path, options::root_path); cverb << vsfile << "output filename: " << options::gmon_filename << endl; // we do a first try with exclude-dependent if it fails we include // dependent. First try should catch "opgrof /usr/bin/make" whilst // the second catch "opgprof /lib/libc-2.2.5.so" if (!try_merge_profiles(pspec, true)) try_merge_profiles(pspec, false); }