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