Home | History | Annotate | Download | only in quipper
      1 // Copyright 2015 The Chromium OS Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 #include "perf_option_parser.h"
      5 
      6 #include <algorithm>
      7 #include <map>
      8 
      9 #include "compat/string.h"
     10 
     11 namespace quipper {
     12 
     13 namespace {
     14 
     15 enum class OptionType {
     16   Boolean,  // has no value
     17   Value,    // Uses another argument.
     18 };
     19 
     20 const std::map<string, OptionType>& GetPerfRecordOptions() {
     21   static const auto* kPerfRecordOptions = new std::map<string, OptionType>{
     22       {"-e", OptionType::Value},
     23       {"--event", OptionType::Value},
     24       {"--filter", OptionType::Value},
     25       {"-p", OptionType::Value},
     26       {"--pid", OptionType::Value},
     27       {"-t", OptionType::Value},
     28       {"--tid", OptionType::Value},
     29       {"-r", OptionType::Value},
     30       {"--realtime", OptionType::Value},
     31       /* Banned: {"--no-buffering", OptionType::Boolean}, */
     32       {"-R", OptionType::Boolean},
     33       {"--raw-samples", OptionType::Boolean},
     34       {"-a", OptionType::Boolean},
     35       {"--all-cpus", OptionType::Boolean},
     36       {"-C", OptionType::Value},
     37       {"--cpu", OptionType::Value},
     38       {"-c", OptionType::Value},
     39       {"--count", OptionType::Value},
     40       /* Banned: {"-o", OptionType::Value},
     41        * {"--output", OptionType::Value}, */
     42       {"-i", OptionType::Boolean},
     43       {"--no-inherit", OptionType::Boolean},
     44       {"-F", OptionType::Value},
     45       {"--freq", OptionType::Value},
     46       /* Banned: {"-m", OptionType::Value},
     47        * {"--mmap-pages", OptionType::Value}, */
     48       {"--group", OptionType::Boolean}, /* new? */
     49       {"-g", OptionType::Boolean}, /* NB: in stat, this is short for --group */
     50       {"--call-graph", OptionType::Value},
     51       /* Banned: {"-v", OptionType::Boolean},
     52        * {"--verbose", OptionType::Boolean}, */
     53       /* Banned: {"-q", OptionType::Boolean},
     54        * {"--quiet", OptionType::Boolean}, */
     55       {"-s", OptionType::Boolean},
     56       {"--stat", OptionType::Boolean},
     57       {"-d", OptionType::Boolean},
     58       {"--data", OptionType::Boolean},
     59       {"-T", OptionType::Boolean},
     60       {"--timestamp", OptionType::Boolean},
     61       {"-P", OptionType::Boolean},       /* new? */
     62       {"--period", OptionType::Boolean}, /* new? */
     63       {"-n", OptionType::Boolean},
     64       {"--no-samples", OptionType::Boolean},
     65       {"-N", OptionType::Boolean},
     66       {"--no-buildid-cache", OptionType::Boolean},
     67       {"-B", OptionType::Boolean},           /* new? */
     68       {"--no-buildid", OptionType::Boolean}, /* new? */
     69       {"-G", OptionType::Value},
     70       {"--cgroup", OptionType::Value},
     71       /* Changed between v3.13 to v3.14 from:
     72       {"-D", OptionType::Boolean},
     73       {"--no-delay", OptionType::Boolean},
     74        * to:
     75       {"-D", OptionType::Value},
     76       {"--delay", OptionType::Value},
     77        * ... So just ban it until the new option is universal on ChromeOS perf.
     78        */
     79       {"-u", OptionType::Value},
     80       {"--uid", OptionType::Value},
     81       {"-b", OptionType::Boolean},
     82       {"--branch-any", OptionType::Boolean},
     83       {"-j", OptionType::Value},
     84       {"--branch-filter", OptionType::Value},
     85       {"-W", OptionType::Boolean},
     86       {"--weight", OptionType::Boolean},
     87       {"--transaction", OptionType::Boolean},
     88       /* Banned: {"--per-thread", OptionType::Boolean},
     89        * Only briefly present in v3.12-v3.13, but also banned:
     90        * {"--force-per-cpu", OptionType::Boolean}, */
     91       /* Banned: {"-I", OptionType::Boolean},  // may reveal PII
     92       {"--intr-regs", OptionType::Boolean}, */
     93       {"--running-time", OptionType::Boolean},
     94       {"-k", OptionType::Value},
     95       {"--clockid", OptionType::Value},
     96       {"-S", OptionType::Value},
     97       {"--snapshot", OptionType::Value},
     98 
     99       {"--pfm-events", OptionType::Value},
    100   };
    101   return *kPerfRecordOptions;
    102 }
    103 
    104 const std::map<string, OptionType>& GetPerfStatOptions() {
    105   static const auto* kPerfStatOptions = new std::map<string, OptionType>{
    106       {"-T", OptionType::Boolean},
    107       {"--transaction", OptionType::Boolean},
    108       {"-e", OptionType::Value},
    109       {"--event", OptionType::Value},
    110       {"--filter", OptionType::Value},
    111       {"-i", OptionType::Boolean},
    112       {"--no-inherit", OptionType::Boolean},
    113       {"-p", OptionType::Value},
    114       {"--pid", OptionType::Value},
    115       {"-t", OptionType::Value},
    116       {"--tid", OptionType::Value},
    117       {"-a", OptionType::Boolean},
    118       {"--all-cpus", OptionType::Boolean},
    119       {"-g", OptionType::Boolean},
    120       {"--group", OptionType::Boolean},
    121       {"-c", OptionType::Boolean},
    122       {"--scale", OptionType::Boolean},
    123       /* Banned: {"-v", OptionType::Boolean},
    124        * {"--verbose", OptionType::Boolean}, */
    125       /* Banned: {"-r", OptionType::Value},
    126        * {"--repeat", OptionType::Value}, */
    127       /* Banned: {"-n", OptionType::Boolean},
    128        * {"--null", OptionType::Boolean}, */
    129       /* Banned: {"-d", OptionType::Boolean},
    130        * {"--detailed", OptionType::Boolean}, */
    131       /* Banned: {"-S", OptionType::Boolean},
    132        * {"--sync", OptionType::Boolean}, */
    133       /* Banned: {"-B", OptionType::Boolean},
    134        * {"--big-num", OptionType::Boolean}, */
    135       {"-C", OptionType::Value},
    136       {"--cpu", OptionType::Value},
    137       {"-A", OptionType::Boolean},
    138       {"--no-aggr", OptionType::Boolean},
    139       /* Banned: {"-x", OptionType::Value},
    140        * {"--field-separator", OptionType::Value}, */
    141       {"-G", OptionType::Value},
    142       {"--cgroup", OptionType::Value},
    143       /* Banned: {"-o", OptionType::Value},
    144        * {"--output", OptionType::Value}, */
    145       /* Banned: {"--append", OptionType::Value}, */
    146       /* Banned: {"--log-fd", OptionType::Value}, */
    147       /* Banned: {"--pre", OptionType::Value}, */
    148       /* Banned: {"--post", OptionType::Value}, */
    149       /* Banned: {"-I", OptionType::Value},
    150        * {"--interval-print", OptionType::Value}, */
    151       {"--per-socket", OptionType::Boolean},
    152       {"--per-core", OptionType::Boolean},
    153       {"-D", OptionType::Value},
    154       {"--delay", OptionType::Value},
    155   };
    156   return *kPerfStatOptions;
    157 }
    158 
    159 const std::map<string, OptionType>& GetPerfMemOptions() {
    160   static const auto* kPerfMemOptions = new std::map<string, OptionType>{
    161       {"-t", OptionType::Value},   {"--type", OptionType::Value},
    162       {"-D", OptionType::Boolean}, {"--dump-raw-samples", OptionType::Boolean},
    163       {"-x", OptionType::Value},   {"--field-separator", OptionType::Value},
    164       {"-C", OptionType::Value},   {"--cpu-list", OptionType::Value},
    165   };
    166   return *kPerfMemOptions;
    167 }
    168 
    169 bool ValidatePerfCommandLineOptions(
    170     std::vector<string>::const_iterator begin_arg,
    171     std::vector<string>::const_iterator end_arg,
    172     const std::map<string, OptionType>& options) {
    173   for (auto args_iter = begin_arg; args_iter != end_arg; ++args_iter) {
    174     const auto& it = options.find(*args_iter);
    175     if (it == options.end()) {
    176       return false;
    177     }
    178     if (it->second == OptionType::Value) {
    179       ++args_iter;
    180       if (args_iter == end_arg) {
    181         return false;  // missing value
    182       }
    183     }
    184   }
    185   return true;
    186 }
    187 
    188 }  // namespace
    189 
    190 bool ValidatePerfCommandLine(const std::vector<string>& args) {
    191   if (args.size() < 2) {
    192     return false;
    193   }
    194   if (args[0] != "perf") {
    195     return false;
    196   }
    197   if (args[1] == "record") {
    198     return ValidatePerfCommandLineOptions(args.begin() + 2, args.end(),
    199                                           GetPerfRecordOptions());
    200   }
    201   if (args[1] == "mem") {
    202     auto record_arg_iter = std::find(args.begin(), args.end(), "record");
    203     if (record_arg_iter == args.end()) return false;
    204 
    205     return ValidatePerfCommandLineOptions(args.begin() + 2, record_arg_iter,
    206                                           GetPerfMemOptions()) &&
    207            ValidatePerfCommandLineOptions(record_arg_iter + 1, args.end(),
    208                                           GetPerfRecordOptions());
    209   }
    210   if (args[1] == "stat") {
    211     return ValidatePerfCommandLineOptions(args.begin() + 2, args.end(),
    212                                           GetPerfStatOptions());
    213   }
    214   return false;
    215 }
    216 
    217 }  // namespace quipper
    218