Home | History | Annotate | Download | only in ftrace
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "src/traced/probes/ftrace/ftrace_config.h"
     18 
     19 #include "perfetto/base/logging.h"
     20 
     21 namespace perfetto {
     22 namespace {
     23 
     24 bool IsGoodFtracePunctuation(char c) {
     25   return c == '_' || c == '/' || c == '*';
     26 }
     27 
     28 bool IsGoodAtracePunctuation(char c) {
     29   return c == '_' || c == '.' || c == '*';
     30 }
     31 
     32 bool IsValidAtraceEventName(const std::string& str) {
     33   for (size_t i = 0; i < str.size(); i++) {
     34     if (!isalnum(str[i]) && !IsGoodAtracePunctuation(str[i]))
     35       return false;
     36   }
     37   return true;
     38 }
     39 
     40 bool IsValidFtraceEventName(const std::string& str) {
     41   int slash_count = 0;
     42   for (size_t i = 0; i < str.size(); i++) {
     43     if (!isalnum(str[i]) && !IsGoodFtracePunctuation(str[i]))
     44       return false;
     45     if (str[i] == '/') {
     46       slash_count++;
     47       // At most one '/' allowed and not at the beginning or end.
     48       if (slash_count > 1 || i == 0 || i == str.size() - 1)
     49         return false;
     50     }
     51     if (str[i] == '*' && i != str.size() - 1)
     52       return false;
     53   }
     54   return true;
     55 }
     56 
     57 }  // namespace
     58 
     59 FtraceConfig CreateFtraceConfig(std::set<std::string> names) {
     60   FtraceConfig config;
     61   for (const std::string& name : names)
     62     *config.add_ftrace_events() = name;
     63   return config;
     64 }
     65 
     66 bool RequiresAtrace(const FtraceConfig& config) {
     67   return !config.atrace_categories().empty() || !config.atrace_apps().empty();
     68 }
     69 
     70 bool ValidConfig(const FtraceConfig& config) {
     71   for (const std::string& event_name : config.ftrace_events()) {
     72     if (!IsValidFtraceEventName(event_name)) {
     73       PERFETTO_ELOG("Bad event name '%s'", event_name.c_str());
     74       return false;
     75     }
     76   }
     77   for (const std::string& category : config.atrace_categories()) {
     78     if (!IsValidAtraceEventName(category)) {
     79       PERFETTO_ELOG("Bad category name '%s'", category.c_str());
     80       return false;
     81     }
     82   }
     83   for (const std::string& app : config.atrace_apps()) {
     84     if (!IsValidAtraceEventName(app)) {
     85       PERFETTO_ELOG("Bad app '%s'", app.c_str());
     86       return false;
     87     }
     88   }
     89   return true;
     90 }
     91 
     92 }  // namespace perfetto
     93