opannotate_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 "op_config.h"
00021 #include "profile_spec.h"
00022 #include "arrange_profiles.h"
00023 #include "op_exception.h"
00024 #include "opannotate_options.h"
00025 #include "popt_options.h"
00026 #include "cverb.h"
00027 
00028 using namespace std;
00029 
00030 profile_classes classes;
00031 
00032 namespace options {
00033     demangle_type demangle = dmt_normal;
00034     string output_dir;
00035     vector<string> search_dirs;
00036     vector<string> base_dirs;
00037     merge_option merge_by;
00038     path_filter file_filter;
00039     string_filter symbol_filter;
00040     bool source;
00041     bool assembly;
00042     vector<string> objdump_params;
00043     bool exclude_dependent;
00044 }
00045 
00046 
00047 namespace {
00048 
00049 string include_symbols;
00050 string exclude_symbols;
00051 string include_file;
00052 string exclude_file;
00053 string demangle_option = "normal";
00054 vector<string> mergespec;
00055 
00056 popt::option options_array[] = {
00057     popt::option(demangle_option, "demangle", 'D',
00058              "demangle GNU C++ symbol names (default normal)",
00059                  "none|normal|smart"),
00060     popt::option(options::output_dir, "output-dir", 'o',
00061              "output directory", "directory name"),
00062     popt::option(options::search_dirs, "search-dirs", 'd',
00063                  "directories to look for source files", "comma-separated paths"),
00064     popt::option(options::base_dirs, "base-dirs", 'b',
00065                  "source file prefixes to strip", "comma-separated paths"),
00066     popt::option(include_file, "include-file", '\0',
00067              "include these comma separated filename", "filenames"),
00068     popt::option(exclude_file, "exclude-file", '\0',
00069              "exclude these comma separated filename", "filenames"),
00070     popt::option(include_symbols, "include-symbols", 'i',
00071              "include these comma separated symbols", "symbols"),
00072     popt::option(exclude_symbols, "exclude-symbols", 'e',
00073              "exclude these comma separated symbols", "symbols"),
00074     popt::option(options::objdump_params, "objdump-params", '\0',
00075              "additional params to pass to objdump", "parameters"),
00076     popt::option(options::exclude_dependent, "exclude-dependent", 'x',
00077              "exclude libs, kernel, and module samples for applications"),
00078     popt::option(mergespec, "merge", 'm',
00079              "comma separated list", "cpu,tid,tgid,unitmask,all"),
00080     popt::option(options::source, "source", 's', "output source"),
00081     popt::option(options::assembly, "assembly", 'a', "output assembly"),
00082     popt::option(options::threshold_opt, "threshold", 't',
00083              "minimum percentage needed to produce output",
00084              "percent"),
00085 };
00086 
00087 }  // anonymous namespace
00088 
00089 
00090 void handle_options(options::spec const & spec)
00091 {
00092     using namespace options;
00093     vector<string> tmp_objdump_parms;
00094 
00095     /* When passing a quoted string of options from opannotate for the
00096      * objdump command, objdump_parms consists of a single string.  Need
00097      * to break the string into a series of individual options otherwise
00098      * the call to exec_comand fails when it sees the space between the
00099      * options.
00100      */
00101     for (unsigned int i = 0; i < objdump_params.size(); i++) {
00102         string s;
00103         s = objdump_params[i];
00104         stringstream ss(s);
00105         istream_iterator<string> begin(ss);
00106         istream_iterator<string> end;
00107         vector<string> vstrings(begin, end);
00108 
00109         for (unsigned int j = 0; j < vstrings.size(); j++)
00110             tmp_objdump_parms.push_back(vstrings[j]);
00111     }
00112 
00113     // update objdump_parms.
00114     objdump_params.assign(tmp_objdump_parms.begin(), tmp_objdump_parms.end());
00115 
00116     if (spec.first.size()) {
00117         cerr << "differential profiles not allowed" << endl;
00118         exit(EXIT_FAILURE);
00119     }
00120 
00121     if (!assembly && !source) {
00122         cerr << "you must specify at least --source or --assembly\n";
00123         exit(EXIT_FAILURE);
00124     }
00125 
00126     if (!objdump_params.empty() && !assembly) {
00127         cerr << "--objdump-params is meaningless without --assembly\n";
00128         exit(EXIT_FAILURE);
00129     }
00130 
00131     if (search_dirs.empty() && !base_dirs.empty()) {
00132         cerr << "--base-dirs is useless unless you specify an "
00133             "alternative source location with --search-dirs"
00134              << endl;
00135         exit(EXIT_FAILURE);
00136     }
00137 
00138     if (assembly && !output_dir.empty()) {
00139         cerr << "--output-dir is meaningless with --assembly" << endl;
00140         exit(EXIT_FAILURE);
00141     }
00142 
00143     options::symbol_filter = string_filter(include_symbols, exclude_symbols);
00144 
00145     options::file_filter = path_filter(include_file, exclude_file);
00146 
00147     profile_spec const pspec =
00148         profile_spec::create(spec.common, options::image_path,
00149                      options::root_path);
00150 
00151     if (!was_session_dir_supplied())
00152         cerr << "Using " << op_samples_dir << " for session-dir" << endl;
00153 
00154     list<string> sample_files = pspec.generate_file_list(exclude_dependent, true);
00155 
00156     cverb << vsfile << "Archive: " << pspec.get_archive_path() << endl;
00157 
00158     cverb << vsfile << "Matched sample files: " << sample_files.size()
00159           << endl;
00160     copy(sample_files.begin(), sample_files.end(),
00161          ostream_iterator<string>(cverb << vsfile, "\n"));
00162 
00163     demangle = handle_demangle_option(demangle_option);
00164 
00165     // we always merge but this have no effect on output since at source
00166     // or assembly point of view the result will be merged anyway
00167     merge_by = handle_merge_option(mergespec, false, exclude_dependent);
00168 
00169     classes = arrange_profiles(sample_files, merge_by,
00170                    pspec.extra_found_images);
00171 
00172     cverb << vsfile << "profile_classes:\n" << classes << endl;
00173 
00174     if (classes.v.empty()) {
00175         cerr << "error: no sample files found: profile specification "
00176              "too strict ?" << endl;
00177         exit(EXIT_FAILURE);
00178     }
00179 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1