|
|
1.1 ! root 1: #!/usr/bin/python ! 2: ! 3: # GDB debugging support ! 4: # ! 5: # Copyright 2012 Red Hat, Inc. and/or its affiliates ! 6: # ! 7: # Authors: ! 8: # Avi Kivity <[email protected]> ! 9: # ! 10: # This work is licensed under the terms of the GNU GPL, version 2. See ! 11: # the COPYING file in the top-level directory. ! 12: # ! 13: # Contributions after 2012-01-13 are licensed under the terms of the ! 14: # GNU GPL, version 2 or (at your option) any later version. ! 15: ! 16: ! 17: import gdb ! 18: ! 19: def isnull(ptr): ! 20: return ptr == gdb.Value(0).cast(ptr.type) ! 21: ! 22: def int128(p): ! 23: return long(p['lo']) + (long(p['hi']) << 64) ! 24: ! 25: class QemuCommand(gdb.Command): ! 26: '''Prefix for QEMU debug support commands''' ! 27: def __init__(self): ! 28: gdb.Command.__init__(self, 'qemu', gdb.COMMAND_DATA, ! 29: gdb.COMPLETE_NONE, True) ! 30: ! 31: class MtreeCommand(gdb.Command): ! 32: '''Display the memory tree hierarchy''' ! 33: def __init__(self): ! 34: gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA, ! 35: gdb.COMPLETE_NONE) ! 36: self.queue = [] ! 37: def invoke(self, arg, from_tty): ! 38: self.seen = set() ! 39: self.queue_root('address_space_memory') ! 40: self.queue_root('address_space_io') ! 41: self.process_queue() ! 42: def queue_root(self, varname): ! 43: ptr = gdb.parse_and_eval(varname)['root'] ! 44: self.queue.append(ptr) ! 45: def process_queue(self): ! 46: while self.queue: ! 47: ptr = self.queue.pop(0) ! 48: if long(ptr) in self.seen: ! 49: continue ! 50: self.print_item(ptr) ! 51: def print_item(self, ptr, offset = gdb.Value(0), level = 0): ! 52: self.seen.add(long(ptr)) ! 53: addr = ptr['addr'] ! 54: addr += offset ! 55: size = int128(ptr['size']) ! 56: alias = ptr['alias'] ! 57: klass = '' ! 58: if not isnull(alias): ! 59: klass = ' (alias)' ! 60: elif not isnull(ptr['ops']): ! 61: klass = ' (I/O)' ! 62: elif bool(ptr['ram']): ! 63: klass = ' (RAM)' ! 64: gdb.write('%s%016x-%016x %s%s (@ %s)\n' ! 65: % (' ' * level, ! 66: long(addr), ! 67: long(addr + (size - 1)), ! 68: ptr['name'].string(), ! 69: klass, ! 70: ptr, ! 71: ), ! 72: gdb.STDOUT) ! 73: if not isnull(alias): ! 74: gdb.write('%s alias: %s@%016x (@ %s)\n' % ! 75: (' ' * level, ! 76: alias['name'].string(), ! 77: ptr['alias_offset'], ! 78: alias, ! 79: ), ! 80: gdb.STDOUT) ! 81: self.queue.append(alias) ! 82: subregion = ptr['subregions']['tqh_first'] ! 83: level += 1 ! 84: while not isnull(subregion): ! 85: self.print_item(subregion, addr, level) ! 86: subregion = subregion['subregions_link']['tqe_next'] ! 87: ! 88: QemuCommand() ! 89: MtreeCommand()
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.