decode_packet_trace.py revision 9617:c503acb59e51
1#!/usr/bin/env python 2 3# Copyright (c) 2013 ARM Limited 4# All rights reserved 5# 6# The license below extends only to copyright in the software and shall 7# not be construed as granting a license to any other intellectual 8# property including but not limited to intellectual property relating 9# to a hardware implementation of the functionality of the software 10# licensed hereunder. You may use the software subject to the license 11# terms below provided that you ensure that this notice is replicated 12# unmodified and in its entirety in all distributions of the software, 13# modified or unmodified, in source code or in binary form. 14# 15# Redistribution and use in source and binary forms, with or without 16# modification, are permitted provided that the following conditions are 17# met: redistributions of source code must retain the above copyright 18# notice, this list of conditions and the following disclaimer; 19# redistributions in binary form must reproduce the above copyright 20# notice, this list of conditions and the following disclaimer in the 21# documentation and/or other materials provided with the distribution; 22# neither the name of the copyright holders nor the names of its 23# contributors may be used to endorse or promote products derived from 24# this software without specific prior written permission. 25# 26# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37# 38# Copyright 2008 Google Inc. All rights reserved. 39# http://code.google.com/p/protobuf/ 40# 41# Redistribution and use in source and binary forms, with or without 42# modification, are permitted provided that the following conditions are 43# met: 44# 45# * Redistributions of source code must retain the above copyright 46# notice, this list of conditions and the following disclaimer. 47# * Redistributions in binary form must reproduce the above 48# copyright notice, this list of conditions and the following disclaimer 49# in the documentation and/or other materials provided with the 50# distribution. 51# * Neither the name of Google Inc. nor the names of its 52# contributors may be used to endorse or promote products derived from 53# this software without specific prior written permission. 54# 55# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 56# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 57# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 58# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 59# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 60# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 61# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 62# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 63# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 64# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 65# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 66# 67# Authors: Andreas Hansson 68# 69 70# This script is used to dump protobuf packet traces to ASCII 71# format. It assumes that protoc has been executed and already 72# generated the Python package for the packet messages. This can 73# be done manually using: 74# protoc --python_out=. --proto_path=src/proto src/proto/packet.proto 75# 76# The ASCII trace format uses one line per request on the format cmd, 77# addr, size, tick,flags. For example: 78# r,128,64,4000,0 79# w,232123,64,500000,0 80 81import struct 82import sys 83import packet_pb2 84 85def DecodeVarint(in_file): 86 """ 87 The decoding of the Varint32 is copied from 88 google.protobuf.internal.decoder and is only repeated here to 89 avoid depending on the internal functions in the library. If the 90 end of file is reached, return (0, 0). 91 """ 92 result = 0 93 shift = 0 94 pos = 0 95 # Use a 32-bit mask 96 mask = 0xffffffff 97 while 1: 98 c = in_file.read(1) 99 if len(c) == 0: 100 return (0, 0) 101 b = struct.unpack('<B', c)[0] 102 result |= ((b & 0x7f) << shift) 103 pos += 1 104 if not (b & 0x80): 105 if result > 0x7fffffffffffffff: 106 result -= (1 << 64) 107 result |= ~mask 108 else: 109 result &= mask 110 return (result, pos) 111 shift += 7 112 if shift >= 64: 113 raise IOError('Too many bytes when decoding varint.') 114 115def decodeMessage(in_file, message): 116 """ 117 Attempt to read a message from the file and decode it. Return 118 False if no message could be read. 119 """ 120 try: 121 size, pos = DecodeVarint(in_file) 122 if size == 0: 123 return False 124 buf = in_file.read(size) 125 message.ParseFromString(buf) 126 return True 127 except IOError: 128 return False 129 130def main(): 131 if len(sys.argv) != 3: 132 print "Usage: ", sys.argv[0], " <protobuf input> <ASCII output>" 133 exit(-1) 134 135 try: 136 proto_in = open(sys.argv[1], 'rb') 137 except IOError: 138 print "Failed to open ", sys.argv[1], " for reading" 139 exit(-1) 140 141 try: 142 ascii_out = open(sys.argv[2], 'w') 143 except IOError: 144 print "Failed to open ", sys.argv[2], " for writing" 145 exit(-1) 146 147 # Read the magic number in 4-byte Little Endian 148 magic_number = proto_in.read(4) 149 150 if magic_number != "gem5": 151 print "Unrecognized file" 152 exit(-1) 153 154 print "Parsing packet header" 155 156 # Add the packet header 157 header = packet_pb2.PacketHeader() 158 decodeMessage(proto_in, header) 159 160 print "Object id:", header.obj_id 161 print "Tick frequency:", header.tick_freq 162 163 print "Parsing packets" 164 165 num_packets = 0 166 ignored_flags = False 167 packet = packet_pb2.Packet() 168 169 # Decode the packet messages until we hit the end of the file 170 while decodeMessage(proto_in, packet): 171 num_packets += 1 172 # ReadReq is 1 and WriteReq is 4 in src/mem/packet.hh Command enum 173 cmd = 'r' if packet.cmd == 1 else ('w' if packet.cmd == 4 else 'u') 174 if packet.HasField('flags'): 175 # Currently not printing flags 176 ignored_flags = True 177 ascii_out.write('%s,%s,%s,%s\n' % (cmd, packet.addr, packet.size, 178 packet.tick)) 179 180 print "Parsed packets:", num_packets 181 if ignored_flags: 182 print "Encountered packet flags that were ignored" 183 184 # We're done 185 ascii_out.close() 186 proto_in.close() 187 188if __name__ == "__main__": 189 main() 190