1#!/usr/bin/env python 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. 15 16import codecs 17import sys 18import os 19import re 20import time 21 22files = [] 23trace_regex = "\s*(.*?)-(\d+?)\s+\(\s*(\d+?)\)\s+\[\d+\]\s+(.*?)\s+(.*?):\s+" 24all_traces_dict = {} # {"deviceName": [(timestamp, line) ...]} 25all_real_time_dict = {} 26default_real_time = 7983849599000 # 2222-12-31 23:59:59 27 28def compare_timestamp(time1, time2): 29 return float(time1) < float(time2) 30 31def read_files(file, devices_name): 32 traces = [] 33 with codecs.open(file, 'r', encoding='utf-8') as fp: 34 for line in fp: 35 if line.find("binder_transaction") > -1 \ 36 or line.find("tracing_mark_write") > -1: 37 line = line.replace("\n", "") 38 trace_match = re.match(trace_regex, line) 39 if trace_match: 40 traces.append((float(trace_match.group(5)), line)) 41 if line.find("realtime_ts") > -1: 42 time_regex = "{}{}".format(trace_regex, \ 43 "tracing_mark_write:\s+trace_event_clock_sync: realtime_ts=(.*)") 44 time_match = re.match(time_regex, line) 45 all_real_time_dict[devices_name] = { \ 46 "realtime_ts": int(time_match.group(6)), \ 47 "timestamp": float(time_match.group(5))} 48 if (not all_real_time_dict.__contains__(devices_name)) and traces: 49 line = traces[-1][1] 50 trace_match = re.match(trace_regex, line) 51 all_real_time_dict[devices_name] = { \ 52 "realtime_ts": default_real_time, \ 53 "timestamp": float(trace_match.group(5))} 54 return traces 55 56def handle_option(): 57 if len(sys.argv) < 2: 58 print("eg: python bytrace_multi.py file1.ftrace file2.ftrace ...") 59 exit(0) 60 for i in range(len(sys.argv)): 61 if i == 0: 62 continue 63 if sys.argv[i] == "-h" or sys.argv[i] == "--help": 64 print("eg: python bytrace_multi.py file1.ftrace file2.ftrace ...") 65 exit(0) 66 elif not os.path.exists(sys.argv[i]): 67 print("Warning: {} is not found.".format(sys.argv[i])) 68 else: 69 files.append(sys.argv[i]) 70 71def change_trace_time(all_trace_list, \ 72 base_real_time, \ 73 base_time_stamp, \ 74 target_device): 75 target_real_time = all_real_time_dict[target_device]["realtime_ts"] 76 target_time_stamp = all_real_time_dict[target_device]["timestamp"] 77 if not target_real_time == default_real_time: 78 diff_real_time = float(target_real_time - base_real_time) / 1000 79 target_time_stamp_ = base_time_stamp + diff_real_time 80 diff_time = target_time_stamp - target_time_stamp_ 81 else: 82 # If the file does not have realtime, the difference is 0.5s. 83 diff_real_time = 0.5 84 target_time_stamp_ = base_time_stamp + diff_real_time 85 diff_time = target_time_stamp - target_time_stamp_ 86 traces = all_traces_dict[target_device] 87 for mtuple in traces: 88 timestamp = float(mtuple[0]) 89 line = mtuple[1] 90 timestamp_ = "{:.6f}".format(timestamp - diff_time) 91 line_ = target_device + \ 92 line.replace("{:.6f}".format(timestamp), str(timestamp_)) 93 all_trace_list.append((timestamp_, line_)) 94 95def write_to_file(data, file_name): 96 with codecs.open(file_name, 'w+', encoding='utf-8') as fp: 97 fp.write("# tracer: nop\n") 98 fp.write("#\n") 99 fp.write("# _-----=> irqs-off\n") 100 fp.write("# / _----=> need-resched\n") 101 fp.write("# | / _---=> hardirq/softirq\n") 102 fp.write("# || / _--=> preempt-depth\n") 103 fp.write("# ||| / delay\n") 104 fp.write("# TASK-PID TGID CPU# |||| TIMESTAMP FUNCTION\n") 105 fp.write("# | | | | |||| | |\n") 106 for mtuple in data: 107 fp.write(mtuple[1]) 108 fp.write("\n") 109 110def main(): 111 handle_option() 112 if len(files) == 0: 113 exit(-1) 114 115 for i, val in enumerate(files): 116 device_name = "[device_{}]".format(str(i)) 117 all_traces_dict[device_name] = read_files(val, device_name) 118 119 all_time_sorted_list = sorted(all_real_time_dict.items(), key=lambda \ 120 all_real_time_dict: all_real_time_dict[1]["realtime_ts"]) 121 base_real_time = all_time_sorted_list[0][1]["realtime_ts"] 122 base_time_stamp = all_time_sorted_list[0][1]["timestamp"] 123 all_trace_list = [] # [(timestamp, line)] 124 for mtuple in all_time_sorted_list: 125 target_device = mtuple[0] 126 change_trace_time(all_trace_list, \ 127 base_real_time, \ 128 base_time_stamp, \ 129 target_device) 130 # Sort by timestamp from small to large 131 all_trace_sorted_list = sorted(all_trace_list, key=lambda x: x[0]) 132 curtime = time.strftime("%Y%m%d_%H%M%S", time.localtime()) 133 write_to_file(all_trace_sorted_list, "multi_trace_{}.ftrace".format(str(curtime))) 134 135if __name__ == '__main__': 136 main() 137