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 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 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