main.cc revision 6e4e0383b0baf72512e5d44339c43808179808ca
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 "ftrace_proto_gen.h" 26#include "perfetto/ftrace_reader/format_parser.h" 27#include "perfetto/trace/ftrace/ftrace_event.pbzero.h" 28 29int main(int argc, const char** argv) { 30 if (argc != 4) { 31 fprintf(stderr, "Usage: ./%s whitelist_dir input_dir output_dir\n", 32 argv[0]); 33 return 1; 34 } 35 36 const char* whitelist_path = argv[1]; 37 const char* input_dir = argv[2]; 38 const char* output_dir = argv[3]; 39 40 std::set<std::string> events = perfetto::GetWhitelistedEvents(whitelist_path); 41 std::vector<std::string> events_info; 42 43 // proto_field_id for each event is read from this file. 44 std::ifstream input("protos/perfetto/trace/ftrace/ftrace_event.proto", 45 std::ios::in | std::ios::binary); 46 if (!input) { 47 fprintf(stderr, "Failed to open %s\n", 48 "protos/perfetto/trace/ftrace/ftrace_event.proto"); 49 return 1; 50 } 51 std::ostringstream ftrace_stream; 52 ftrace_stream << input.rdbuf(); 53 54 std::set<std::string> new_events; 55 for (auto event : events) { 56 std::string file_name = 57 event.substr(event.find('/') + 1, std::string::npos); 58 struct stat buf; 59 if (stat(("protos/perfetto/trace/ftrace/" + file_name + ".proto").c_str(), 60 &buf) == -1) { 61 new_events.insert(file_name); 62 } 63 } 64 65 if (!new_events.empty()) { 66 perfetto::PrintFtraceEventProtoAdditions(new_events); 67 perfetto::PrintTraceToTextMain(new_events); 68 perfetto::PrintTraceToTextUsingStatements(new_events); 69 perfetto::PrintTraceToTextFunctions(new_events); 70 } 71 72 for (auto event : events) { 73 std::string proto_file_name = 74 event.substr(event.find('/') + 1, std::string::npos) + ".proto"; 75 std::string group = event.substr(0, event.find('/')); 76 std::string input_path = input_dir + event + std::string("/format"); 77 std::string output_path = output_dir + std::string("/") + proto_file_name; 78 79 std::ifstream fin(input_path.c_str(), std::ios::in); 80 if (!fin) { 81 fprintf(stderr, "Failed to open %s\n", input_path.c_str()); 82 return 1; 83 } 84 std::ostringstream stream; 85 stream << fin.rdbuf(); 86 fin.close(); 87 std::string contents = stream.str(); 88 89 perfetto::FtraceEvent format; 90 if (!perfetto::ParseFtraceEvent(contents, &format)) { 91 fprintf(stderr, "Could not parse file %s.\n", input_path.c_str()); 92 return 1; 93 } 94 95 perfetto::Proto proto; 96 if (!perfetto::GenerateProto(format, &proto)) { 97 fprintf(stderr, "Could not generate proto for file %s\n", 98 input_path.c_str()); 99 return 1; 100 } 101 102 std::smatch match; 103 std::string ftrace = 104 ftrace_stream.str(); // regex_search requires a non-temporary string 105 std::regex event_regex(format.name + "\\s*=\\s*(\\d+)"); 106 std::regex_search(ftrace, match, event_regex); 107 std::string proto_field_id = match[1].str().c_str(); 108 if (proto_field_id == "") { 109 fprintf(stderr, 110 "Could not find proto_field_id for %s in ftrace_event.proto. " 111 "Please add it.\n", 112 format.name.c_str()); 113 return 1; 114 } 115 116 events_info.push_back( 117 perfetto::SingleEventInfo(format, proto, group, proto_field_id)); 118 119 std::ofstream fout(output_path.c_str(), std::ios::out); 120 if (!fout) { 121 fprintf(stderr, "Failed to open %s\n", output_path.c_str()); 122 return 1; 123 } 124 125 fout << proto.ToString(); 126 fout.close(); 127 } 128 129 input.close(); 130 perfetto::GenerateEventInfo(events_info); 131} 132