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 }
00088
00089
00090 void handle_options(options::spec const & spec)
00091 {
00092 using namespace options;
00093 vector<string> tmp_objdump_parms;
00094
00095
00096
00097
00098
00099
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
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
00166
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 }