1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# Copyright (C) 2021 Huawei Device Co., Ltd. 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. 15import os 16import subprocess 17import sys 18import argparse 19import logging 20sys.path.append(os.getcwd()) 21sys.path.append("../../") 22from ftrace_format_parser import FtraceEventCodeGenerator 23from ftrace_format_parser import ProtoType 24 25AUTO_GENERATED_GNI = 'autogenerated.gni' 26 27THIS_FILE = os.path.basename(__file__) 28logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', 29 level=logging.INFO) 30logger = logging.getLogger(THIS_FILE) 31 32CPP_COPYRIGHT_HEADER = '''\ 33/* THIS FILE IS GENERATE BY {}, PLEASE DON'T EDIT IT! 34 * Copyright (c) 2021 Huawei Device Co., Ltd. 35 * Licensed under the Apache License, Version 2.0 (the "License"); 36 * you may not use this file except in compliance with the License. 37 * You may obtain a copy of the License at 38 * 39 * http://www.apache.org/licenses/LICENSE-2.0 40 * 41 * Unless required by applicable law or agreed to in writing, software 42 * distributed under the License is distributed on an "AS IS" BASIS, 43 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 44 * See the License for the specific language governing permissions and 45 * limitations under the License. 46 */ 47'''.format(THIS_FILE) 48 49GN_COPYRIGHT_HEADER = '''\ 50# THIS FILE IS GENERATE BY {}, PLEASE DON'T EDIT IT! 51# Copyright (C) 2021 Huawei Device Co., Ltd. 52# Licensed under the Apache License, Version 2.0 (the "License"); 53# you may not use this file except in compliance with the License. 54# You may obtain a copy of the License at 55# 56# http://www.apache.org/licenses/LICENSE-2.0 57# 58# Unless required by applicable law or agreed to in writing, software 59# distributed under the License is distributed on an "AS IS" BASIS, 60# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 61# See the License for the specific language governing permissions and 62# limitations under the License. 63'''.format(THIS_FILE) 64 65PARSE_FUNCTION_ARGS = '({}, {}, {}, {})'.format('FtraceEvent& ftraceEvent', 66 'uint8_t data[]', 'size_t size', 'const EventFormat& format') 67PARSE_REGISTER_MACRO = 'REGISTER_FTRACE_EVENT_PARSE_FUNCTION' 68 69CHECK_FUNCTION_ARGS = '(const ForStandard::FtraceEvent& event) -> bool' 70FORMAT_FUNCTION_ARGS = '(const ForStandard::FtraceEvent& event) -> std::string' 71FORMAT_REGISTER_MACRO = 'REGISTER_FTRACE_EVENT_FORMATTER' 72 73 74def to_camel_case(name): 75 return ''.join([p.capitalize() for p in name.split('_')]) 76 77 78def fix_field_name(name): 79 replace_map = { 80 'errno': 'error_code', 81 'sa_handler': 'sig_handler', 82 'sa_flags': 'sig_flags', 83 'new': 'seq_new' 84 } 85 if name in replace_map: 86 name = replace_map[name] 87 return str.lower(name) 88 89 90def ensure_dir_exists(file_path): 91 file_dir = os.path.dirname(file_path) 92 if not os.path.exists(file_dir): 93 os.mkdir(file_dir) 94 95 96class Common: 97 this_file = os.path.basename(__file__) 98 logging.basicConfig( 99 format="%(asctime)s %(levelname)s %(message)s", level=logging.INFO 100 ) 101 logger = logging.getLogger(this_file) 102 cpp_copyright_header = CPP_COPYRIGHT_HEADER 103 parse_register_macro = PARSE_REGISTER_MACRO 104 auto_generated_gni = AUTO_GENERATED_GNI 105 parse_function_args = PARSE_FUNCTION_ARGS 106 gn_copyright_header = GN_COPYRIGHT_HEADER 107 108 109class EventParserCodeGenerator(FtraceEventCodeGenerator): 110 def __init__(self, events_dir, allow_list): 111 super().__init__(events_dir, allow_list) 112 113 def parser_file_path(self, category): 114 file_name = 'ftrace_{}_event_parser.cpp'.format(category) 115 return os.path.join(self.output_dir, file_name) 116 117 def generate_code(self): 118 generated_cpp_sources = [] 119 120 for event in self.target_event_formats: 121 type_name = '{}/{}'.format(event.category, event.name) 122 logger.info('ftrace_events: "{}"'.format(type_name)) 123 124 # generate sub event parser code 125 for category in self.grouped_event_formats: 126 parser_src_file = self.parser_file_path(category) 127 generated_cpp_sources.append(parser_src_file) 128 129 logger.info('Generate {} ...'.format(parser_src_file)) 130 ensure_dir_exists(parser_src_file) 131 132 with open(parser_src_file, 'w', encoding='utf-8') as f: 133 f.write(CPP_COPYRIGHT_HEADER) 134 f.write('#include "sub_event_parser.h"\n') 135 f.write('\n') 136 f.write("FTRACE_NS_BEGIN\n") 137 f.write("namespace {\n") 138 self.generate_parse_functions(category, f) 139 f.write("} // namespace\n") 140 f.write("FTRACE_NS_END\n") 141 f.write('\n') 142 143 # generate .gni 144 generated_cpp_gni = os.path.join(self.output_dir, AUTO_GENERATED_GNI) 145 logger.info('Generate {} ...'.format(generated_cpp_gni)) 146 with open(generated_cpp_gni, 'w', encoding='utf-8') as f: 147 f.write(GN_COPYRIGHT_HEADER) 148 f.write('\n') 149 f.write('auto_generated_cpp_sources = [\n') 150 for path in generated_cpp_sources: 151 src = '{}'.format(os.path.basename(path)) 152 f.write(' "{}",\n'.format(src)) 153 f.write(']\n') 154 155 def generate_parse_functions(self, category, f): 156 count = 0 157 for event in self.grouped_event_formats[category]: 158 count += 1 159 if count > 1: 160 f.write('\n') 161 f.write('{}({},\n'.format(PARSE_REGISTER_MACRO, event.name)) 162 f.write('[] {} {{\n'.format(PARSE_FUNCTION_ARGS)) 163 f.write(' int i = 0;\n') 164 f.write(' auto msg = ftraceEvent.mutable_{}_format();\n'.format( 165 str.lower(event.name))) 166 for i in range(len(event.remain_fields)): 167 self.generate_parse_field_lines(event, f, i) 168 f.write("});\n") 169 170 @staticmethod 171 def generate_parse_field_lines(event, f, i): 172 field_info = event.remain_fields[i] 173 field_name = fix_field_name(field_info.name) 174 type_info = field_info.to_proto_type() 175 parse_func = None 176 if type_info.tid == ProtoType.STRING: 177 parse_func = 'ParseStrField' 178 elif type_info.tid == ProtoType.ARRAY: 179 parse_func = 'ParseVectorIntField' 180 elif type_info.tid == ProtoType.INTEGER: 181 assert type_info.size in [4, 8] 182 c_type = None 183 if type_info.size == 4: 184 c_type = 'int32_t' if type_info.signed else 'uint32_t' 185 elif type_info.size == 8: 186 c_type = 'int64_t' if type_info.signed else 'uint64_t' 187 parse_func = 'ParseIntField<{}>'.format(c_type) 188 else: 189 logger.warning('WARNING: unkown proto type:{} {}'.format( 190 event.name, field_name)) 191 assert parse_func 192 if (type_info.tid == ProtoType.ARRAY): 193 f.write(' std::vector<uint64_t> retvalVec = FtraceFieldParser::ParseVectorIntField<uint64_t>(format.fields, i++, data, size);') 194 f.write(' for (size_t i = 0; i < retvalVec.size(); i++) {') 195 f.write(' msg->add_{}(retvalVec[i]);'.format(field_name)) 196 f.write(' }') 197 else: 198 f.write(' msg->set_{}(FtraceFieldParser::'.format(field_name)) 199 f.write('{}(format.fields, i++, data, size));\n'.format(parse_func)) 200 201 202class EventFormatterCodeGenerator(FtraceEventCodeGenerator): 203 def __init__(self, events_dir, allow_list): 204 super().__init__(events_dir, allow_list) 205 206 def formatter_file_path(self, category): 207 file_name = 'ftrace_{}_event_formatter.cpp'.format(category) 208 return os.path.join(self.output_dir, file_name) 209 210 def generate_code(self): 211 generated_cpp_sources = [] 212 213 # generate sub event parser code 214 for category in self.grouped_event_formats: 215 formatter_src_file = self.formatter_file_path(category) 216 generated_cpp_sources.append(formatter_src_file) 217 218 logger.info('Generate {} ...'.format(formatter_src_file)) 219 ensure_dir_exists(formatter_src_file) 220 221 with open(formatter_src_file, 'w', encoding='utf-8') as f: 222 f.write(CPP_COPYRIGHT_HEADER) 223 f.write('#include <cinttypes>\n') 224 f.write('\n') 225 f.write('#include "event_formatter.h"\n') 226 if (category == "binder") : 227 f.write('#include "binder.h"\n') 228 f.write('#include "logging.h"\n') 229 if (category == "f2fs") : 230 f.write('#include "f2fs.h"\n') 231 elif (category == "power") : 232 f.write('#include "pm_qos.h"\n') 233 elif (category == "writeback") : 234 f.write('#include "pq.h"\n') 235 elif (category == "compaction") | (category == "kmem") | (category == "vmscan") : 236 f.write('#include "type.h"\n') 237 elif (category == "timer") : 238 f.write('#include "hrtimer.h"\n') 239 f.write('#include "trace_events.h"\n') 240 f.write('\n') 241 f.write("FTRACE_NS_BEGIN\n") 242 f.write("namespace {\n") 243 f.write('const int BUFFER_SIZE = 512;\n') 244 f.write('\n') 245 self.generate_format_functions(category, f) 246 f.write("} // namespace\n") 247 f.write("FTRACE_NS_END\n") 248 f.write('\n') 249 250 # generate .gni 251 generated_cpp_gni = os.path.join(self.output_dir, AUTO_GENERATED_GNI) 252 logger.info('Generate {} ...'.format(generated_cpp_gni)) 253 with open(generated_cpp_gni, 'w', encoding='utf-8') as f: 254 f.write(GN_COPYRIGHT_HEADER) 255 f.write('\n') 256 f.write('auto_generated_cpp_sources = [\n') 257 for path in generated_cpp_sources: 258 src = '{}'.format(os.path.basename(path)) 259 f.write(' "{}",\n'.format(src)) 260 f.write(']\n') 261 262 def generate_format_functions(self, category, f): 263 count = 0 264 for event in self.grouped_event_formats[category]: 265 count += 1 266 if count > 1: 267 f.write('\n') 268 f.write('{}({},\n'.format(FORMAT_REGISTER_MACRO, str.lower(event.name))) 269 f.write('[] {} {{\n'.format(CHECK_FUNCTION_ARGS, )) 270 f.write(' return event.has_{}_format();'.format( 271 str.lower(event.name))) 272 f.write('},') # end of check function 273 f.write('[] {} {{\n'.format(FORMAT_FUNCTION_ARGS)) 274 f.write(' auto msg = event.{}_format();\n'.format( 275 str.lower(event.name))) 276 f.write(" char buffer[BUFFER_SIZE];\n") 277 event.print_fmt = "\"{}: {}".format(event.name, event.print_fmt[2:]) 278 event.print_fmt = str.replace(event.print_fmt, "%zu", "%\" PRIu64 \"") 279 event.print_fmt = str.replace(event.print_fmt, "%zd", "%\" PRIu64 \"") 280 event.print_fmt = str.replace(event.print_fmt, "%llu", "%\" PRIu64 \"") 281 event.print_fmt = str.replace(event.print_fmt, "%lld", "%\" PRIu64 \"") 282 event.print_fmt = str.replace(event.print_fmt, "%lx", "%\" PRIx64 \"") 283 event.print_fmt = str.replace(event.print_fmt, "%llx", "%\" PRIx64 \"") 284 event.print_fmt = str.replace(event.print_fmt, "(unsigned long long)", "") 285 286 if (category == "kmem") | (category == "filemap") : 287 event.print_fmt = str.replace(event.print_fmt, "page=%p", "page=%s") 288 event.print_fmt = str.replace(event.print_fmt, "REC->pfn != -1UL ? (((struct page *)vmemmap_base) + (REC->pfn)) : ((void *)0)", "\"0000000000000000\"") 289 event.print_fmt = str.replace(event.print_fmt, "(((struct page *)vmemmap_base) + (REC->pfn))", "\"0000000000000000\"") 290 event.print_fmt = str.replace(event.print_fmt, " (void *)", " ") 291 event.print_fmt = str.replace(event.print_fmt, " name=%s\"", "\"") 292 event.print_fmt = str.replace(event.print_fmt, "REC->ptr, __get_str(name)", "REC->ptr") 293 event.print_fmt = str.replace(event.print_fmt, "%lu", "%\" PRIu64 \"") 294 elif (category == "filelock") : 295 event.print_fmt = str.replace(event.print_fmt, "=%lu", "=%\" PRIu64 \"") 296 event.print_fmt = str.replace(event.print_fmt, "REC->fl_blocker", "msg.fl_next()") 297 event.print_fmt = str.replace(event.print_fmt, "REC->fl_owner", "msg.fl_owner()") 298 event.print_fmt = str.replace(event.print_fmt, "REC->fl_flags", "msg.fl_flags()") 299 event.print_fmt = str.replace(event.print_fmt, "REC->fl_type", "msg.fl_type()") 300 event.print_fmt = str.replace(event.print_fmt, "REC->fl_break_time", "msg.fl_break_time()") 301 event.print_fmt = str.replace(event.print_fmt, "REC->fl_downgrade_time", "msg.fl_downgrade_time()") 302 event.print_fmt = str.replace(event.print_fmt, "REC->rcount", "msg.dcount()") 303 elif (category == "ext4") : 304 event.print_fmt = str.replace(event.print_fmt, "%lu", "%\" PRIu64 \"") 305 event.print_fmt = str.replace(event.print_fmt, ", (unsigned long)", ",") 306 elif (category == "vmscan") : 307 event.print_fmt = str.replace(event.print_fmt, "%ld", "%\" PRIu64 \"") 308 event.print_fmt = str.replace(event.print_fmt, "%lu", "%\" PRIu64 \"") 309 elif (category == "writeback") : 310 event.print_fmt = str.replace(event.print_fmt, ", (unsigned long)", ", ") 311 event.print_fmt = str.replace(event.print_fmt, "cgroup_ino=%lu", "cgroup_ino=%\" PRId32 \"") 312 event.print_fmt = str.replace(event.print_fmt, "%lu", "%\" PRIu64 \"") 313 event.print_fmt = str.replace(event.print_fmt, "%ld", "%\" PRIu64 \"") 314 elif (category == "sunrpc") : 315 event.print_fmt = str.replace(event.print_fmt, "=%lu", "=%\" PRIu64 \"") 316 elif (category == "sched") : 317 event.print_fmt = str.replace(event.print_fmt, "%Lu", "%\" PRIu64 \"") 318 elif (category == "ftrace") : 319 event.print_fmt = str.replace(event.print_fmt, "(unsigned long)", "") 320 321 if (event.name == "binder_command") : 322 event.print_fmt = "\"binder_command: cmd=0x%x\", msg.cmd()" 323 elif (event.name == "binder_return") : 324 event.print_fmt = "\"binder_return: cmd=0x%x\", msg.cmd()" 325 elif (event.name == "task_newtask") | (event.name == "task_rename") : 326 event.print_fmt = str.replace(event.print_fmt, "oom_score_adj=%hd", "oom_score_adj=%d") 327 elif (event.name == "branch_format"): 328 event.print_fmt = "\"branch: %u:%s:%s (%u)%s\", msg.line(), msg.func().c_str(), msg.file().c_str(), msg.correct(), msg.constant() ? \" CONSTANT\" : \"\"" 329 elif (event.name == "mm_lru_activate") | (event.name == "mm_lru_insertion") : 330 event.print_fmt = str.replace(event.print_fmt, "pfn=%lu", "pfn=%\" PRIu64 \"") 331 elif (event.name == "sched_stick_numa"): 332 event.print_fmt = "\"sched_stick_numa: src_pid=%d src_tgid=%d src_ngid=%d src_cpu=%d src_nid=%d dst_pid=%d dst_tgid=%d dst_ngid=%d dst_cpu=%d dst_nid=%d\", msg.pid(), msg.tgid(), msg.ngid(), msg.src_cpu(), msg.src_nid(), msg.pid(), msg.tgid(), msg.ngid(), msg.dst_cpu(), msg.dst_nid()" 333 elif (event.name == "workqueue_execute_end"): 334 event.print_fmt = "\"workqueue_execute_end: work struct %p\", msg.work()" 335 elif (event.name == "workqueue_queue_work"): 336 event.print_fmt = str.replace(event.print_fmt, "REC->workqueue", "msg.workqueue()") 337 elif (event.name == "i2c_reply") | (event.name == "i2c_write") : 338 event.print_fmt = str.replace(event.print_fmt, "l=%u [%*phD]", "l=%\" PRId32 \" [%\" PRId32 \"]") 339 event.print_fmt = str.replace(event.print_fmt, "REC->len, REC->len", "REC->len") 340 elif (event.name == "mm_compaction_isolate_freepages") | (event.name == "mm_compaction_isolate_migratepages") \ 341 | (event.name == "mm_compaction_begin") | (event.name == "mm_compaction_end") \ 342 | (event.name == "mm_compaction_migratepages") : 343 event.print_fmt = str.replace(event.print_fmt, "%lu", "=0x%\" PRIu64 \"") 344 elif (event.name == "mm_compaction_defer_compaction") | (event.name == "mm_compaction_defer_reset") \ 345 | (event.name == "mm_compaction_deferred") | (event.name == "mm_compaction_end") \ 346 | (event.name == "mm_compaction_migratepages") : 347 event.print_fmt = str.replace(event.print_fmt, "REC->order_failed", "msg.order_failed()") 348 elif (event.name == "signal_deliver") | (event.name == "signal_generate") : 349 event.print_fmt = str.replace(event.print_fmt, "REC->errno", "msg.error_code()") 350 event.print_fmt = str.replace(event.print_fmt, "REC->sa_handler", "msg.sig_handler()") 351 event.print_fmt = str.replace(event.print_fmt, "REC->sa_flags", "msg.sig_flags()") 352 elif (event.name == "sys_enter") | (event.name == "sys_exit"): 353 event.print_fmt = str.replace(event.print_fmt, "%ld", "%\" PRIu64 \"") 354 elif (event.name == "oom_score_adj_update"): 355 event.print_fmt = str.replace(event.print_fmt, "oom_score_adj=%hd", "oom_score_adj=%\" PRId32 \"") 356 elif (event.name == "ext4_da_write_pages"): 357 event.print_fmt = str.replace(event.print_fmt, "first_page %\" PRIu64 \" nr_to_write %ld", "first_page %\" PRIu64 \" nr_to_write %\" PRIu64 \"") 358 elif (event.name == "ext4_discard_preallocations"): 359 event.print_fmt = str.replace(event.print_fmt, "ino %\" PRIu64 \" len: %u needed %u", "ino %\" PRIu64 \"") 360 event.print_fmt = str.replace(event.print_fmt, " REC->ino, REC->len, REC->needed", " REC->ino") 361 elif (event.name == "ext4_ext_remove_space_done") | (event.name == "ext4_ext_rm_leaf") | (event.name == "ext4_remove_blocks") : 362 event.print_fmt = str.replace(event.print_fmt, " [pclu %\" PRIu64 \" lblk %u state %d]", "%\" PRIu64 \"") 363 event.print_fmt = str.replace(event.print_fmt, "(long long) REC->pc_pclu, (unsigned int) REC->pc_lblk, (int) REC->pc_state", "msg.partial()") 364 elif (event.name == "ext4_free_blocks"): 365 event.print_fmt = str.replace(event.print_fmt, "count %\" PRIu64 \"", "count %\" PRIu64 \"") 366 elif (event.name == "ext4_journal_start"): 367 event.print_fmt = str.replace(event.print_fmt, ", revoke_creds %d,", ",") 368 event.print_fmt = str.replace(event.print_fmt, ", REC->revoke_creds,", ",") 369 elif (event.name == "ext4_read_block_bitmap_load"): 370 event.print_fmt = str.replace(event.print_fmt, "%u prefetch %d", "%u") 371 event.print_fmt = str.replace(event.print_fmt, "REC->group, REC->prefetch", "msg.group()") 372 elif (event.name == "ext4_writepages"): 373 event.print_fmt = str.replace(event.print_fmt, "nr_to_write %ld", "nr_to_write %\" PRIu64 \"") 374 event.print_fmt = str.replace(event.print_fmt, "pages_skipped %ld", "pages_skipped %\" PRIu64 \"") 375 elif (event.name == "ext4_writepages_result"): 376 event.print_fmt = str.replace(event.print_fmt, "pages_skipped %ld", "pages_skipped %\" PRIu64 \"") 377 elif (event.name == "ext4_load_inode"): 378 event.print_fmt = str.replace(event.print_fmt, "ino %ld", "ino %\" PRIu64 \"") 379 elif (event.name == "itimer_state") : 380 event.print_fmt = str.replace(event.print_fmt, "it_value=%ld.%06ld it_interval=%ld.%06ld", "it_value=%\" PRIu64 \"it_interval=%\" PRIu64 \"") 381 event.print_fmt = str.replace(event.print_fmt, "REC->value_nsec / 1000L, REC->interval_sec, REC->interval_nsec / 1000L", "msg.interval_sec()") 382 elif (event.name == "timer_expire_entry") : 383 event.print_fmt = str.replace(event.print_fmt, "now=%lu baseclk=%lu", "now=%\" PRIu64 \"") 384 event.print_fmt = str.replace(event.print_fmt, "REC->now, REC->baseclk", "msg.now()") 385 elif (event.name == "timer_start") : 386 event.print_fmt = str.replace(event.print_fmt, "expires=%lu [timeout=%ld]", "expires=%\" PRIu64 \" [timeout=%\" PRIu64 \"]") 387 event.print_fmt = str.replace(event.print_fmt, ", (long)", ",") 388 elif (event.name == "mm_shrink_slab_end") | (event.name == "mm_shrink_slab_start") : 389 event.print_fmt = str.replace(event.print_fmt, "REC->shrink", "msg.shrink()") 390 elif (event.name == "mm_vmscan_lru_shrink_inactive") : 391 event.print_fmt = str.replace(event.print_fmt, "nr_activate_anon=%d nr_activate_file=%d", "nr_activate=%\" PRIu64 \"") 392 event.print_fmt = str.replace(event.print_fmt, "REC->nr_activate0, REC->nr_activate1", "msg.nr_activate()") 393 elif (event.name == "mm_vmscan_writepage") : 394 event.print_fmt = str.replace(event.print_fmt, "page=%p", "page=%s") 395 event.print_fmt = "{} \"0000000000000000\"{}".format(event.print_fmt[:56], event.print_fmt[3728:]) 396 elif (event.name == "mm_vmscan_lru_isolate") : 397 event.print_fmt = str.replace(event.print_fmt, "REC->highest_zoneidx", "msg.classzone_idx()") 398 elif (event.name == "balance_dirty_pages") | (event.name == "bdi_dirty_ratelimit") : 399 event.print_fmt = str.replace(event.print_fmt, "REC->bdi_dirty", "msg.bdi_dirty()") 400 event.print_fmt = str.replace(event.print_fmt, "REC->bdi_setpoint", "msg.bdi_setpoint()") 401 event.print_fmt = str.replace(event.print_fmt, "REC->dirty_ratelimit", "msg.dirty_ratelimit()") 402 event.print_fmt = str.replace(event.print_fmt, "REC->dirtied_pause", "msg.dirtied_pause()") 403 elif (event.name == "sched_migrate_task") : 404 event.print_fmt = str.replace(event.print_fmt, "dest_cpu=%d running=%d", "dest_cpu=%d") 405 event.print_fmt = str.replace(event.print_fmt, "REC->dest_cpu, REC->running", "msg.dest_cpu()") 406 elif (event.name == "ext4_find_delalloc_range") : 407 event.print_fmt = str.replace(event.print_fmt, "REC->found_blk", "msg.found_blk()") 408 elif (event.name == "mm_filemap_add_to_page_cache") | (event.name == "mm_filemap_delete_from_page_cache"): 409 event.print_fmt = "\"{}: dev %\" PRIu64 \":%\" PRIu64 \" ino %p page=%s pfn=%\" PRIu64 \" ofs=%\" PRIu64 \"\", (((msg.s_dev()) >> 20)), (((msg.s_dev()) & ((1U << 20) - 1))), msg.i_ino(), \"0000000000000000\", msg.pfn(), msg.index() << 12".format(event.name) 410 elif (event.name == "ipi_raise") : 411 event.print_fmt = str.replace(event.print_fmt, "target_mask=%s", "target_mask=%\" PRIu64 \"") 412 event.print_fmt = str.replace(event.print_fmt, "__get_bitmask(target_cpus)", "msg.target_cpus()") 413 elif (event.name == "mm_page_alloc") : 414 event.print_fmt = "{} \"0000000000000000\"{}".format(event.print_fmt[:78], event.print_fmt[3783:]) 415 elif (event.name == "mm_page_alloc_extfrag") : 416 event.print_fmt = "{} \"0000000000000000\"{}".format(event.print_fmt[:181], event.print_fmt[3853:]) 417 elif (event.name == "mm_page_alloc_zone_locked") : 418 event.print_fmt = "{} \"0000000000000000\"{}".format(event.print_fmt[:181], event.print_fmt[3853:]) 419 elif (event.name == "mm_page_free") : 420 event.print_fmt = "{} \"0000000000000000\"{}".format(event.print_fmt[:49], event.print_fmt[3721:]) 421 elif (event.name == "mm_page_free_batched") : 422 event.print_fmt = "{} \"0000000000000000\"{}".format(event.print_fmt[:56], event.print_fmt[3728:]) 423 elif (event.name == "mm_page_pcpu_drain") : 424 event.print_fmt = "{} \"0000000000000000\"{}".format(event.print_fmt[:70], event.print_fmt[3742:]) 425 elif (event.name == "xprt_transmit"): 426 event.print_fmt = "\"xprt_transmit: xid=0x%08x status=%d\", msg.xid(), msg.status()" 427 elif (event.name == "rss_stat") : 428 event.print_fmt = str.replace(event.print_fmt, "size=%ldB", "size=%\" PRIu64 \"B") 429 elif (event.name == "file_check_and_advance_wb_err") : 430 event.print_fmt = str.replace(event.print_fmt, "REC->new", "msg.seq_new()") 431 elif (event.name == "f2fs_sync_file_enter") : 432 event.print_fmt = str.replace(event.print_fmt, "i_mode = 0x%hx", "i_mode = 0x%x") 433 elif (event.name == "wakeup_source_activate") | (event.name == "wakeup_source_deactivate") : 434 event.print_fmt = str.replace(event.print_fmt, "(unsigned long)", "") 435 elif (event.name == "print") : 436 f.write(" std::string fieldBuf = msg.buf();\n") 437 f.write(" if (fieldBuf.size() > 1 && fieldBuf[fieldBuf.size() - 1] == '\\n') {\n") 438 f.write(" fieldBuf = fieldBuf.substr(0, fieldBuf.size() - 1);\n") 439 f.write(" }\n") 440 event.print_fmt = "\"print: %s\", fieldBuf.c_str()" 441 442 event.print_fmt = str.replace(event.print_fmt, "%pS", "%p") 443 444 if (event.print_fmt.find("%ps") == -1) : 445 self.handle_field_name_functions(event, f, False) 446 else : 447 if ((event.print_fmt.find("%ps") != -1) & (event.print_fmt.find("REC->function") != -1)) : 448 if (event.name != "workqueue_execute_end") : 449 self.handle_format_ps_functions(event, f, "function") 450 elif ((event.print_fmt.find("%ps") != -1) & (event.print_fmt.find("REC->ip") != -1)) : 451 self.handle_format_ps_functions(event, f, "ip", True) 452 elif ((event.print_fmt.find("%ps") != -1) & (event.print_fmt.find("REC->action") != -1)) : 453 self.handle_format_ps_functions(event, f, "action") 454 elif ((category == "cpuhp") & (event.print_fmt.find("%ps") != -1) & (event.print_fmt.find("REC->fun") != -1)) : 455 self.handle_format_ps_functions(event, f, "fun") 456 elif ((event.name == "funcgraph_entry") | (event.name == "funcgraph_exit")) : 457 self.handle_format_ps_functions(event, f, "func", True) 458 elif (event.name == "kernel_stack") | (event.name == "user_stack") : 459 f.write(" int len = 0;\n") 460 f.write(" std::string kernelSymbolsStr = \"\";\n") 461 f.write(" auto kernelSymbols = EventFormatter::GetInstance().kernelSymbols_;\n") 462 f.write(" if (kernelSymbols.count(msg.caller()[0]) > 0) {\n") 463 f.write(" kernelSymbolsStr = kernelSymbols[msg.caller()[0]];\n") 464 f.write(" }\n") 465 f.write(" if (kernelSymbolsStr != \"\") {\n ") 466 print_fmt = event.print_fmt 467 event.print_fmt = str.replace(event.print_fmt, "%ps", "%s") 468 offset = 0 469 if (event.name == "kernel_stack") : 470 offset = 2 471 event.print_fmt = "{}kernelSymbols[msg.caller()[{}]].c_str(), kernelSymbols[msg.caller()[{}]].c_str(), kernelSymbols[msg.caller()[{}]].c_str()," \ 472 " kernelSymbols[msg.caller()[{}]].c_str(), kernelSymbols[msg.caller()[{}]].c_str(), kernelSymbols[msg.caller()[{}]].c_str()," \ 473 " kernelSymbols[msg.caller()[{}]].c_str(), kernelSymbols[msg.caller()[{}]].c_str()".format(event.print_fmt[:94+offset], event.print_fmt[114+offset], 474 event.print_fmt[138+offset], event.print_fmt[162+offset], event.print_fmt[186+offset], event.print_fmt[210+offset], event.print_fmt[234+offset], 475 event.print_fmt[258+offset], event.print_fmt[282+offset]) 476 f.write(" len = snprintf_s(buffer, BUFFER_SIZE, BUFFER_SIZE - 1, {});\n".format(event.print_fmt)) 477 f.write(" } else {\n") 478 event.print_fmt = print_fmt 479 event.print_fmt = str.replace(event.print_fmt, "%ps", "%p") 480 self.handle_field_name_functions(event, f) 481 f.write(" }\n") 482 483 f.write(' if (len >= BUFFER_SIZE - 1) {\n') 484 f.write(' HILOG_WARN(LOG_CORE, "maybe, the contents of print event({}) msg had be cut off in outfile");\n'.format(event.name)) 485 f.write(' }\n') 486 f.write(" return std::string(buffer);\n") 487 f.write("});\n") # end of format function 488 489 def handle_field_name_functions(self, event, f, is_define_len=True): 490 for field_info in event.remain_fields: 491 field_name = fix_field_name(field_info.name) 492 event.print_fmt = str.replace(event.print_fmt, "__get_str({})".format(field_name), 493 "msg.{}().c_str()".format(field_name)) 494 event.print_fmt = str.replace(event.print_fmt, "__get_dynamic_array({})".format(field_name), 495 "msg.{}()".format(field_name)) 496 if field_info.field.startswith('char {}['.format(field_name)) \ 497 | field_info.field.startswith('const char {}['.format(field_name)) \ 498 | field_info.field.startswith('char *') | field_info.field.startswith('const char *'): 499 event.print_fmt = str.replace(event.print_fmt, "REC->{}".format(field_name), "msg.{}().c_str()".format(field_name)) 500 else: 501 event.print_fmt = str.replace(event.print_fmt, "REC->{}".format(field_name), "msg.{}()".format(field_name)) 502 if (event.name == "sched_switch"): 503 f.write(" int len = 0;\n") 504 f.write(" if (msg.prev_state() > 0x0400) {\n") 505 f.write(' len = snprintf_s(buffer, BUFFER_SIZE, BUFFER_SIZE - 1, "sched_switch: prev_comm=%s prev_pid=%d prev_prio=%d prev_state=? ==> next_comm=%s next_pid=%d next_prio=%d", msg.prev_comm().c_str(), msg.prev_pid(), msg.prev_prio(), msg.next_comm().c_str(), msg.next_pid(), msg.next_prio());\n') 506 f.write(" } else {\n") 507 f.write(' len = snprintf_s(buffer, BUFFER_SIZE, BUFFER_SIZE - 1, "sched_switch: prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s%s ==> next_comm=%s next_pid=%d next_prio=%d", msg.prev_comm().c_str(), msg.prev_pid(), msg.prev_prio(), (msg.prev_state() & ((((0x0000 | 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040) + 1) << 1) - 1)) ? __print_flags(msg.prev_state() & ((((0x0000 | 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040) + 1) << 1) - 1), "|", { 0x0001, "S" }, { 0x0002, "D" }, { 0x0004, "T" }, { 0x0008, "t" }, { 0x0010, "X" }, { 0x0020, "Z" }, { 0x0040, "I" }, { 0x0080, "K" }, { 0x0100, "W" }, { 0x0200, "P" }, { 0x0400, "N" }) : "R", msg.prev_state() & (((0x0000 | 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040) + 1) << 1) ? "+" : "", msg.next_comm().c_str(), msg.next_pid(), msg.next_prio());\n') 508 f.write(" }\n") 509 elif (is_define_len) : 510 f.write(" len = snprintf_s(buffer, BUFFER_SIZE, BUFFER_SIZE - 1, {});\n".format(event.print_fmt)) 511 else : 512 f.write(" int len = snprintf_s(buffer, BUFFER_SIZE, BUFFER_SIZE - 1, {});\n".format(event.print_fmt)) 513 514 def handle_format_ps_functions(self, event, f, filed_name, is_void=False): 515 f.write(" int len = 0;\n") 516 f.write(" std::string functionStr = \"\";\n") 517 f.write(" auto kernelSymbols = EventFormatter::GetInstance().kernelSymbols_;\n") 518 f.write(" if (kernelSymbols.count(msg.{}()) > 0) ".format(filed_name)) 519 f.write("{\n") 520 f.write(" functionStr = kernelSymbols[msg.{}()];\n".format(filed_name)) 521 f.write(" }\n") 522 f.write(" if (functionStr != \"\") {\n ") 523 print_fmt = event.print_fmt 524 event.print_fmt = str.replace(event.print_fmt, "%ps", "%s") 525 if (is_void) : 526 event.print_fmt = str.replace(event.print_fmt, "(void *)REC->{}".format(filed_name), "functionStr.c_str()") 527 else : 528 event.print_fmt = str.replace(event.print_fmt, "REC->{}".format(filed_name), "functionStr.c_str()") 529 self.handle_field_name_functions(event, f) 530 f.write(" } else {\n") 531 event.print_fmt = print_fmt 532 event.print_fmt = str.replace(event.print_fmt, "%ps", "%p") 533 self.handle_field_name_functions(event, f) 534 f.write(" }\n") 535 536def main(): 537 parser = argparse.ArgumentParser( 538 description='FTrace C++ code generator.') 539 parser.add_argument('-a', dest='allow_list', required=True, type=str, 540 help='event allow list file path') 541 parser.add_argument('-e', dest='events_dir', required=True, type=str, 542 help='event formats directory') 543 parser.add_argument('-p', dest='parser_out', required=False, type=str, 544 help='parser code output directory') 545 parser.add_argument('-f', dest='formatter_out', required=False, type=str, 546 help='formaater code output directory') 547 548 args = parser.parse_args(sys.argv[1:]) 549 allow_list = args.allow_list 550 events_dir = args.events_dir 551 parser_out = args.parser_out 552 formatter_out = args.formatter_out 553 554 # check arguments 555 if not os.path.isfile(allow_list): 556 parser.print_usage() 557 exit(1) 558 if not os.path.isdir(events_dir): 559 parser.print_usage() 560 exit(2) 561 562 if parser_out: 563 if not os.path.isdir(parser_out): 564 parser.print_usage() 565 exit(3) 566 parser_gen = EventParserCodeGenerator(events_dir, allow_list) 567 parser_gen.generate(os.path.join(parser_out)) 568 sh_path = "../../../format-code.sh " 569 if (os.getcwd().find("device_kernel_version") != -1): 570 sh_path = "../../{}".format(sh_path) 571 subprocess.run("{}{}".format(sh_path, parser_out), shell=True) 572 subprocess.run("chmod 775 {}*.cpp".format(parser_out), shell=True) 573 574 if formatter_out: 575 if not os.path.isdir(formatter_out): 576 parser.print_usage() 577 exit(4) 578 fmtter_gen = EventFormatterCodeGenerator(events_dir, allow_list) 579 fmtter_gen.generate(formatter_out) 580 sh_path = "../../../format-code.sh " 581 if (os.getcwd().find("device_kernel_version") != -1): 582 sh_path = "../../{}".format(sh_path) 583 subprocess.run("{}{}".format(sh_path, formatter_out), shell=True) 584 subprocess.run("chmod 775 {}*.cpp".format(formatter_out), shell=True) 585 586 587if __name__ == '__main__': 588 main() 589