Skip to content

Commit 93b1b36

Browse files
committed
scripts/qemu-gdb: Split MtreeCommand into its own module
As we add more commands to our Python gdb debugging support, it's going to get unwieldy to have everything in a single file. Split the implementation of the 'mtree' command from qemu-gdb.py into its own module. Signed-off-by: Peter Maydell <[email protected]> Reviewed-by: Stefan Hajnoczi <[email protected]> Message-id: [email protected]
1 parent ba9cef7 commit 93b1b36

File tree

3 files changed

+118
-62
lines changed

3 files changed

+118
-62
lines changed

Diff for: scripts/qemu-gdb.py

+8-62
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@
1616

1717
import gdb
1818

19-
def isnull(ptr):
20-
return ptr == gdb.Value(0).cast(ptr.type)
19+
import os, sys
2120

22-
def int128(p):
23-
return long(p['lo']) + (long(p['hi']) << 64)
21+
# Annoyingly, gdb doesn't put the directory of scripts onto the
22+
# module search path. Do it manually.
23+
24+
sys.path.append(os.path.dirname(__file__))
25+
26+
from qemugdb import mtree
2427

2528
def get_fs_base():
2629
'''Fetch %fs base value using arch_prctl(ARCH_GET_FS)'''
@@ -102,63 +105,6 @@ def invoke(self, arg, from_tty):
102105
coroutine_pointer = gdb.parse_and_eval(argv[0]).cast(gdb.lookup_type('CoroutineUContext').pointer())
103106
bt_jmpbuf(coroutine_pointer['env']['__jmpbuf'])
104107

105-
class MtreeCommand(gdb.Command):
106-
'''Display the memory tree hierarchy'''
107-
def __init__(self):
108-
gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA,
109-
gdb.COMPLETE_NONE)
110-
self.queue = []
111-
def invoke(self, arg, from_tty):
112-
self.seen = set()
113-
self.queue_root('address_space_memory')
114-
self.queue_root('address_space_io')
115-
self.process_queue()
116-
def queue_root(self, varname):
117-
ptr = gdb.parse_and_eval(varname)['root']
118-
self.queue.append(ptr)
119-
def process_queue(self):
120-
while self.queue:
121-
ptr = self.queue.pop(0)
122-
if long(ptr) in self.seen:
123-
continue
124-
self.print_item(ptr)
125-
def print_item(self, ptr, offset = gdb.Value(0), level = 0):
126-
self.seen.add(long(ptr))
127-
addr = ptr['addr']
128-
addr += offset
129-
size = int128(ptr['size'])
130-
alias = ptr['alias']
131-
klass = ''
132-
if not isnull(alias):
133-
klass = ' (alias)'
134-
elif not isnull(ptr['ops']):
135-
klass = ' (I/O)'
136-
elif bool(ptr['ram']):
137-
klass = ' (RAM)'
138-
gdb.write('%s%016x-%016x %s%s (@ %s)\n'
139-
% (' ' * level,
140-
long(addr),
141-
long(addr + (size - 1)),
142-
ptr['name'].string(),
143-
klass,
144-
ptr,
145-
),
146-
gdb.STDOUT)
147-
if not isnull(alias):
148-
gdb.write('%s alias: %s@%016x (@ %s)\n' %
149-
(' ' * level,
150-
alias['name'].string(),
151-
ptr['alias_offset'],
152-
alias,
153-
),
154-
gdb.STDOUT)
155-
self.queue.append(alias)
156-
subregion = ptr['subregions']['tqh_first']
157-
level += 1
158-
while not isnull(subregion):
159-
self.print_item(subregion, addr, level)
160-
subregion = subregion['subregions_link']['tqe_next']
161-
162108
QemuCommand()
163109
CoroutineCommand()
164-
MtreeCommand()
110+
mtree.MtreeCommand()

Diff for: scripts/qemugdb/__init__.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/python
2+
3+
# GDB debugging support
4+
#
5+
# Copyright (c) 2015 Linaro Ltd
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License
9+
# as published by the Free Software Foundation; either version 2
10+
# of the License, or (at your option) any later version.
11+
#
12+
# This program is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU General Public License
18+
# along with this program; if not, see
19+
# <http://www.gnu.org/licenses/gpl-2.0.html>
20+
#
21+
22+
# We don't need to do anything in our init file currently.
23+
24+
"""
25+
Support routines for debugging QEMU under GDB
26+
"""
27+
28+
__license__ = "GPL version 2 or (at your option) any later version"

Diff for: scripts/qemugdb/mtree.py

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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+
# 'qemu mtree' -- display the memory hierarchy
17+
18+
import gdb
19+
20+
def isnull(ptr):
21+
return ptr == gdb.Value(0).cast(ptr.type)
22+
23+
def int128(p):
24+
return long(p['lo']) + (long(p['hi']) << 64)
25+
26+
class MtreeCommand(gdb.Command):
27+
'''Display the memory tree hierarchy'''
28+
def __init__(self):
29+
gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA,
30+
gdb.COMPLETE_NONE)
31+
self.queue = []
32+
def invoke(self, arg, from_tty):
33+
self.seen = set()
34+
self.queue_root('address_space_memory')
35+
self.queue_root('address_space_io')
36+
self.process_queue()
37+
def queue_root(self, varname):
38+
ptr = gdb.parse_and_eval(varname)['root']
39+
self.queue.append(ptr)
40+
def process_queue(self):
41+
while self.queue:
42+
ptr = self.queue.pop(0)
43+
if long(ptr) in self.seen:
44+
continue
45+
self.print_item(ptr)
46+
def print_item(self, ptr, offset = gdb.Value(0), level = 0):
47+
self.seen.add(long(ptr))
48+
addr = ptr['addr']
49+
addr += offset
50+
size = int128(ptr['size'])
51+
alias = ptr['alias']
52+
klass = ''
53+
if not isnull(alias):
54+
klass = ' (alias)'
55+
elif not isnull(ptr['ops']):
56+
klass = ' (I/O)'
57+
elif bool(ptr['ram']):
58+
klass = ' (RAM)'
59+
gdb.write('%s%016x-%016x %s%s (@ %s)\n'
60+
% (' ' * level,
61+
long(addr),
62+
long(addr + (size - 1)),
63+
ptr['name'].string(),
64+
klass,
65+
ptr,
66+
),
67+
gdb.STDOUT)
68+
if not isnull(alias):
69+
gdb.write('%s alias: %s@%016x (@ %s)\n' %
70+
(' ' * level,
71+
alias['name'].string(),
72+
ptr['alias_offset'],
73+
alias,
74+
),
75+
gdb.STDOUT)
76+
self.queue.append(alias)
77+
subregion = ptr['subregions']['tqh_first']
78+
level += 1
79+
while not isnull(subregion):
80+
self.print_item(subregion, addr, level)
81+
subregion = subregion['subregions_link']['tqe_next']
82+

0 commit comments

Comments
 (0)