Home | History | Annotate | Download | only in pp
      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