diff options
author | jknotten@chromium.org <jknotten@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-18 08:27:13 +0000 |
---|---|---|
committer | jknotten@chromium.org <jknotten@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-18 08:27:13 +0000 |
commit | 7d58329349b345d125cecb786181bdf7eeac0e8c (patch) | |
tree | b601aa05ba290e9a4f256a8077bcf456a5d0abb2 | |
parent | 9fb08399759e0025435a2853be18d259634c4d0a (diff) | |
download | chromium_src-7d58329349b345d125cecb786181bdf7eeac0e8c.zip chromium_src-7d58329349b345d125cecb786181bdf7eeac0e8c.tar.gz chromium_src-7d58329349b345d125cecb786181bdf7eeac0e8c.tar.bz2 |
Upstream IPC message resolver tool.
This is a tool to process log files and resolve IPC messages to
symbols.
Processes a log file and translates message identifiers of the form
[unknown type NNNNNN] to IPC messages. python
tools/ipc_messages_log.py logcat.txt.
e.g. logfile containing
ipc 3915.3.1370207904 2147483647 S [unknown type 66372]
will be transformed to:
ipc 3915.3.1370207904 2147483647 S ViewMsg_SetCSSColors
BUG=None
TEST=None
Review URL: https://chromiumcodereview.appspot.com/10543162
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142681 0039d316-1c4b-4281-b951-d872f2087c98
-rwxr-xr-x | tools/ipc_messages_log.py | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/tools/ipc_messages_log.py b/tools/ipc_messages_log.py new file mode 100755 index 0000000..26284d1 --- /dev/null +++ b/tools/ipc_messages_log.py @@ -0,0 +1,168 @@ +#!/usr/bin/python +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""""Processes a log file and resolves IPC message identifiers. + +Resolves IPC messages of the form [unknown type NNNNNN] to named IPC messages. + +e.g. logfile containing + +I/stderr ( 3915): ipc 3915.3.1370207904 2147483647 S [unknown type 66372] + +will be transformed to: + +I/stderr ( 3915): ipc 3915.3.1370207904 2147483647 S ViewMsg_SetCSSColors + +In order to find the message header files efficiently, it requires that +Chromium is checked out using git. +""" + +import optparse +import os +import re +import subprocess +import sys + + +def _SourceDir(): + """Get chromium's source directory.""" + return os.path.join(sys.path[0], '..') + + +def _ReadLines(f): + """Read from file f and generate right-stripped lines.""" + for line in f: + yield line.rstrip() + + +def _GetMsgStartTable(): + """Read MsgStart enumeration from ipc/ipc_message_utils.h. + + Determines the message type identifiers by reading. + header file ipc/ipc_message_utils.h and looking for + enum IPCMessageStart. Assumes following code format in header file: + enum IPCMessageStart { + Type1MsgStart ..., + Type2MsgStart, + }; + + Returns: + A dictionary mapping StartName to enumeration value. + """ + ipc_message_file = _SourceDir() + '/ipc/ipc_message_utils.h' + ipc_message_lines = _ReadLines(open(ipc_message_file)) + is_msg_start = False + count = 0 + msg_start_table = dict() + for line in ipc_message_lines: + if is_msg_start: + if line.strip() == '};': + break + msgstart_index = line.find('MsgStart') + msg_type = line[:msgstart_index] + 'MsgStart' + msg_start_table[msg_type.strip()] = count + count+=1 + elif line.strip() == 'enum IPCMessageStart {': + is_msg_start = True + + return msg_start_table + + +def _FindMessageHeaderFiles(): + """Look through the source directory for *_messages.h.""" + os.chdir(_SourceDir()) + pipe = subprocess.Popen(['git', 'ls-files', '--', '*_messages.h'], + stdout=subprocess.PIPE) + return _ReadLines(pipe.stdout) + + +def _GetMsgId(msg_start, line_number, msg_start_table): + """Construct the meessage id given the msg_start and the line number.""" + hex_str = '%x%04x' % (msg_start_table[msg_start], line_number) + return int(hex_str, 16) + + +def _ReadHeaderFile(f, msg_start_table, msg_map): + """Read a header file and construct a map from message_id to message name.""" + msg_def_re = re.compile( + '^IPC_(?:SYNC_)?MESSAGE_[A-Z0-9_]+\(([A-Za-z0-9_]+).*') + msg_start_re = re.compile( + '^\s*#define\s+IPC_MESSAGE_START\s+([a-zA-Z0-9_]+MsgStart).*') + msg_start = None + msg_name = None + line_number = 0 + + for line in f: + line_number+=1 + match = re.match(msg_start_re, line) + if match: + msg_start = match.group(1) + # print "msg_start = " + msg_start + match = re.match(msg_def_re, line) + if match: + msg_name = match.group(1) + # print "msg_name = " + msg_name + if msg_start and msg_name: + msg_id = _GetMsgId(msg_start, line_number, msg_start_table) + msg_map[msg_id] = msg_name + return msg_map + + +def _ResolveMsg(msg_type, msg_map): + """Fully resolve a message type to a name.""" + if msg_type in msg_map: + return msg_map[msg_type] + else: + return '[Unknown message %d (0x%x)]x' % (msg_type, msg_type) + + +def _ProcessLog(f, msg_map): + """Read lines from f and resolve the IPC messages according to msg_map.""" + unknown_msg_re = re.compile('\[unknown type (\d+)\]') + for line in f: + line = line.rstrip() + match = re.search(unknown_msg_re, line) + if match: + line = re.sub(unknown_msg_re, + _ResolveMsg(int(match.group(1)), msg_map), + line) + print line + + +def _GetMsgMap(): + """Returns a dictionary mapping from message number to message name.""" + msg_start_table = _GetMsgStartTable() + msg_map = dict() + for header_file in _FindMessageHeaderFiles(): + _ReadHeaderFile(open(header_file), + msg_start_table, + msg_map) + return msg_map + + +def main(): + """Processes one or more log files with IPC logging messages. + + Replaces '[unknown type NNNNNN]' with resolved + IPC messages. + + Reads from standard input if no log files specified on the + command line. + """ + parser = optparse.OptionParser('usage: %prog [LOGFILE...]') + (_, args) = parser.parse_args() + + msg_map = _GetMsgMap() + log_files = args + + if log_files: + for log_file in log_files: + _ProcessLog(open(log_file), msg_map) + else: + _ProcessLog(sys.stdin, msg_map) + + +if __name__ == '__main__': + main() |