diff options
Diffstat (limited to 'tests/debug.py')
-rwxr-xr-x | tests/debug.py | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/tests/debug.py b/tests/debug.py new file mode 100755 index 0000000..f8c0484 --- /dev/null +++ b/tests/debug.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python2 + +import struct +import binascii + +TYPES = { + (0x700, 0x400): 'splice', + (0x7ff, 0x401): 'create', + (0x7ff, 0x4ff): 'delete', + (0x700, 0x000): 'name', + (0x7ff, 0x001): 'name reg', + (0x7ff, 0x002): 'name dir', + (0x7ff, 0x0ff): 'name superblock', + (0x700, 0x200): 'struct', + (0x7ff, 0x200): 'struct dir', + (0x7ff, 0x202): 'struct ctz', + (0x7ff, 0x201): 'struct inline', + (0x700, 0x300): 'userattr', + (0x700, 0x600): 'tail', + (0x7ff, 0x600): 'tail soft', + (0x7ff, 0x601): 'tail hard', + (0x700, 0x700): 'gstate', + (0x7ff, 0x7ff): 'gstate move', + (0x700, 0x500): 'crc', +} + +def typeof(type): + for prefix in range(12): + mask = 0x7ff & ~((1 << prefix)-1) + if (mask, type & mask) in TYPES: + return TYPES[mask, type & mask] + ( + ' %0*x' % (prefix/4, type & ((1 << prefix)-1)) + if prefix else '') + else: + return '%02x' % type + +def main(*blocks): + # find most recent block + file = None + rev = None + crc = None + versions = [] + + for block in blocks: + try: + nfile = open(block, 'rb') + ndata = nfile.read(4) + ncrc = binascii.crc32(ndata) + nrev, = struct.unpack('<I', ndata) + + assert rev != nrev + if not file or ((rev - nrev) & 0x80000000): + file = nfile + rev = nrev + crc = ncrc + + versions.append((nrev, '%s (rev %d)' % (block, nrev))) + except (IOError, struct.error): + pass + + if not file: + print 'Bad metadata pair {%s}' % ', '.join(blocks) + return 1 + + print "--- %s ---" % ', '.join(v for _,v in sorted(versions, reverse=True)) + + # go through each tag, print useful information + print "%-4s %-8s %-14s %3s %4s %s" % ( + 'off', 'tag', 'type', 'id', 'len', 'dump') + + tag = 0xffffffff + off = 4 + while True: + try: + data = file.read(4) + crc = binascii.crc32(data, crc) + ntag, = struct.unpack('>I', data) + except struct.error: + break + + tag ^= ntag + off += 4 + + type = (tag & 0x7ff00000) >> 20 + id = (tag & 0x000ffc00) >> 10 + size = (tag & 0x000003ff) >> 0 + iscrc = (type & 0x700) == 0x500 + + data = file.read(size if size != 0x3ff else 0) + if iscrc: + crc = binascii.crc32(data[:4], crc) + else: + crc = binascii.crc32(data, crc) + + print '%04x: %08x %-15s %3s %4s %-23s %-8s' % ( + off, tag, + typeof(type) + (' bad!' if iscrc and ~crc else ''), + id if id != 0x3ff else '.', + size if size != 0x3ff else 'x', + ' '.join('%02x' % ord(c) for c in data[:8]), + ''.join(c if c >= ' ' and c <= '~' else '.' for c in data[:8])) + + off += size if size != 0x3ff else 0 + if iscrc: + crc = 0 + tag ^= (type & 1) << 31 + + return 0 + +if __name__ == "__main__": + import sys + sys.exit(main(*sys.argv[1:])) |