• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 <sys/stat.h>
18 #include <fstream>
19 #include <memory>
20 #include <regex>
21 #include <set>
22 #include <sstream>
23 #include <string>
24 
25 #include "perfetto/base/file_utils.h"
26 #include "perfetto/ftrace_reader/format_parser.h"
27 #include "perfetto/trace/ftrace/ftrace_event.pbzero.h"
28 #include "tools/ftrace_proto_gen/ftrace_proto_gen.h"
29 
main(int argc,const char ** argv)30 int main(int argc, const char** argv) {
31   if (argc != 4) {
32     fprintf(stderr, "Usage: ./%s whitelist_dir input_dir output_dir\n",
33             argv[0]);
34     return 1;
35   }
36 
37   const char* whitelist_path = argv[1];
38   const char* input_dir = argv[2];
39   const char* output_dir = argv[3];
40 
41   std::set<std::string> events = perfetto::GetWhitelistedEvents(whitelist_path);
42   std::vector<std::string> events_info;
43 
44   std::string ftrace;
45   if (!perfetto::base::ReadFile(
46           "protos/perfetto/trace/ftrace/ftrace_event.proto", &ftrace)) {
47     fprintf(stderr, "Failed to open %s\n",
48             "protos/perfetto/trace/ftrace/ftrace_event.proto");
49     return 1;
50   }
51 
52   std::set<std::string> new_events;
53   for (const auto& event : events) {
54     std::string file_name =
55         event.substr(event.find('/') + 1, std::string::npos);
56     struct stat buf;
57     if (stat(("protos/perfetto/trace/ftrace/" + file_name + ".proto").c_str(),
58              &buf) == -1) {
59       new_events.insert(file_name);
60     }
61   }
62 
63   if (!new_events.empty()) {
64     perfetto::PrintFtraceEventProtoAdditions(new_events);
65     perfetto::PrintEventFormatterMain(new_events);
66     perfetto::PrintEventFormatterUsingStatements(new_events);
67     perfetto::PrintEventFormatterFunctions(new_events);
68     printf(
69         "\nAdd output to ParseInode in "
70         "tools/ftrace_proto_gen/ftrace_inode_handler.cc\n");
71   }
72 
73   for (auto event : events) {
74     std::string proto_file_name =
75         event.substr(event.find('/') + 1, std::string::npos) + ".proto";
76     std::string group = event.substr(0, event.find('/'));
77     std::string input_path = input_dir + event + std::string("/format");
78     std::string output_path = output_dir + std::string("/") + proto_file_name;
79 
80     std::string contents;
81     if (!perfetto::base::ReadFile(input_path, &contents)) {
82       fprintf(stderr, "Failed to open %s\n", input_path.c_str());
83       return 1;
84     }
85 
86     perfetto::FtraceEvent format;
87     if (!perfetto::ParseFtraceEvent(contents, &format)) {
88       fprintf(stderr, "Could not parse file %s.\n", input_path.c_str());
89       return 1;
90     }
91 
92     perfetto::Proto proto;
93     if (!perfetto::GenerateProto(format, &proto)) {
94       fprintf(stderr, "Could not generate proto for file %s\n",
95               input_path.c_str());
96       return 1;
97     }
98 
99     std::smatch match;
100     std::regex event_regex(format.name + "\\s*=\\s*(\\d+)");
101     std::regex_search(ftrace, match, event_regex);
102     std::string proto_field_id = match[1].str().c_str();
103     if (proto_field_id == "") {
104       fprintf(stderr,
105               "Could not find proto_field_id for %s in ftrace_event.proto. "
106               "Please add it.\n",
107               format.name.c_str());
108       return 1;
109     }
110 
111     if (!new_events.empty())
112       PrintInodeHandlerMain(format.name, proto);
113 
114     events_info.push_back(
115         perfetto::SingleEventInfo(format, proto, group, proto_field_id));
116 
117     std::ofstream fout(output_path.c_str(), std::ios::out);
118     if (!fout) {
119       fprintf(stderr, "Failed to open %s\n", output_path.c_str());
120       return 1;
121     }
122 
123     fout << proto.ToString();
124     fout.close();
125   }
126 
127   perfetto::GenerateEventInfo(events_info);
128 }
129