blob: 7fef98e1864c0f0d3e308d0507a7570ef1b7a181 [file] [log] [blame]
Dirk Pranke4d164bb2021-03-24 06:52:401#!/usr/bin/env python
Avi Drissmandfd880852022-09-15 20:11:092# Copyright 2012 The Chromium Authors
[email protected]7d5832932012-06-18 08:27:133# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6""""Processes a log file and resolves IPC message identifiers.
7
8Resolves IPC messages of the form [unknown type NNNNNN] to named IPC messages.
9
10e.g. logfile containing
11
12I/stderr ( 3915): ipc 3915.3.1370207904 2147483647 S [unknown type 66372]
13
14will be transformed to:
15
16I/stderr ( 3915): ipc 3915.3.1370207904 2147483647 S ViewMsg_SetCSSColors
17
18In order to find the message header files efficiently, it requires that
19Chromium is checked out using git.
20"""
21
Raul Tambre26d7db42019-09-25 11:06:3522from __future__ import print_function
23
[email protected]7d5832932012-06-18 08:27:1324import optparse
25import os
26import re
27import subprocess
28import sys
29
30
31def _SourceDir():
32 """Get chromium's source directory."""
33 return os.path.join(sys.path[0], '..')
34
35
36def _ReadLines(f):
37 """Read from file f and generate right-stripped lines."""
38 for line in f:
39 yield line.rstrip()
40
41
42def _GetMsgStartTable():
43 """Read MsgStart enumeration from ipc/ipc_message_utils.h.
44
45 Determines the message type identifiers by reading.
46 header file ipc/ipc_message_utils.h and looking for
47 enum IPCMessageStart. Assumes following code format in header file:
48 enum IPCMessageStart {
49 Type1MsgStart ...,
50 Type2MsgStart,
51 };
52
53 Returns:
54 A dictionary mapping StartName to enumeration value.
55 """
56 ipc_message_file = _SourceDir() + '/ipc/ipc_message_utils.h'
57 ipc_message_lines = _ReadLines(open(ipc_message_file))
58 is_msg_start = False
59 count = 0
60 msg_start_table = dict()
61 for line in ipc_message_lines:
62 if is_msg_start:
63 if line.strip() == '};':
64 break
65 msgstart_index = line.find('MsgStart')
66 msg_type = line[:msgstart_index] + 'MsgStart'
67 msg_start_table[msg_type.strip()] = count
68 count+=1
69 elif line.strip() == 'enum IPCMessageStart {':
70 is_msg_start = True
71
72 return msg_start_table
73
74
75def _FindMessageHeaderFiles():
76 """Look through the source directory for *_messages.h."""
77 os.chdir(_SourceDir())
78 pipe = subprocess.Popen(['git', 'ls-files', '--', '*_messages.h'],
79 stdout=subprocess.PIPE)
80 return _ReadLines(pipe.stdout)
81
82
83def _GetMsgId(msg_start, line_number, msg_start_table):
84 """Construct the meessage id given the msg_start and the line number."""
85 hex_str = '%x%04x' % (msg_start_table[msg_start], line_number)
86 return int(hex_str, 16)
87
88
89def _ReadHeaderFile(f, msg_start_table, msg_map):
90 """Read a header file and construct a map from message_id to message name."""
91 msg_def_re = re.compile(
92 '^IPC_(?:SYNC_)?MESSAGE_[A-Z0-9_]+\(([A-Za-z0-9_]+).*')
93 msg_start_re = re.compile(
94 '^\s*#define\s+IPC_MESSAGE_START\s+([a-zA-Z0-9_]+MsgStart).*')
95 msg_start = None
96 msg_name = None
97 line_number = 0
98
99 for line in f:
100 line_number+=1
101 match = re.match(msg_start_re, line)
102 if match:
103 msg_start = match.group(1)
Raul Tambre26d7db42019-09-25 11:06:35104 # print("msg_start = " + msg_start)
[email protected]7d5832932012-06-18 08:27:13105 match = re.match(msg_def_re, line)
106 if match:
107 msg_name = match.group(1)
Raul Tambre26d7db42019-09-25 11:06:35108 # print("msg_name = " + msg_name)
[email protected]7d5832932012-06-18 08:27:13109 if msg_start and msg_name:
110 msg_id = _GetMsgId(msg_start, line_number, msg_start_table)
111 msg_map[msg_id] = msg_name
112 return msg_map
113
114
115def _ResolveMsg(msg_type, msg_map):
116 """Fully resolve a message type to a name."""
117 if msg_type in msg_map:
118 return msg_map[msg_type]
119 else:
120 return '[Unknown message %d (0x%x)]x' % (msg_type, msg_type)
121
122
123def _ProcessLog(f, msg_map):
124 """Read lines from f and resolve the IPC messages according to msg_map."""
125 unknown_msg_re = re.compile('\[unknown type (\d+)\]')
126 for line in f:
127 line = line.rstrip()
128 match = re.search(unknown_msg_re, line)
129 if match:
130 line = re.sub(unknown_msg_re,
131 _ResolveMsg(int(match.group(1)), msg_map),
132 line)
Raul Tambre26d7db42019-09-25 11:06:35133 print(line)
[email protected]7d5832932012-06-18 08:27:13134
135
136def _GetMsgMap():
137 """Returns a dictionary mapping from message number to message name."""
138 msg_start_table = _GetMsgStartTable()
139 msg_map = dict()
140 for header_file in _FindMessageHeaderFiles():
141 _ReadHeaderFile(open(header_file),
142 msg_start_table,
143 msg_map)
144 return msg_map
145
146
147def main():
148 """Processes one or more log files with IPC logging messages.
149
150 Replaces '[unknown type NNNNNN]' with resolved
151 IPC messages.
152
153 Reads from standard input if no log files specified on the
154 command line.
155 """
156 parser = optparse.OptionParser('usage: %prog [LOGFILE...]')
157 (_, args) = parser.parse_args()
158
159 msg_map = _GetMsgMap()
160 log_files = args
161
162 if log_files:
163 for log_file in log_files:
164 _ProcessLog(open(log_file), msg_map)
165 else:
166 _ProcessLog(sys.stdin, msg_map)
167
168
169if __name__ == '__main__':
170 main()