Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <peter.maydell@linaro.org> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Message-id: 1439574392-4403-2-git-send-email-peter.maydell@linaro.org
- Loading branch information
Showing
3 changed files
with
118 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/usr/bin/python | ||
|
||
# GDB debugging support | ||
# | ||
# Copyright (c) 2015 Linaro Ltd | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License | ||
# as published by the Free Software Foundation; either version 2 | ||
# of the License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program; if not, see | ||
# <http://www.gnu.org/licenses/gpl-2.0.html> | ||
# | ||
|
||
# We don't need to do anything in our init file currently. | ||
|
||
""" | ||
Support routines for debugging QEMU under GDB | ||
""" | ||
|
||
__license__ = "GPL version 2 or (at your option) any later version" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#!/usr/bin/python | ||
|
||
# GDB debugging support | ||
# | ||
# Copyright 2012 Red Hat, Inc. and/or its affiliates | ||
# | ||
# Authors: | ||
# Avi Kivity <avi@redhat.com> | ||
# | ||
# This work is licensed under the terms of the GNU GPL, version 2. See | ||
# the COPYING file in the top-level directory. | ||
# | ||
# Contributions after 2012-01-13 are licensed under the terms of the | ||
# GNU GPL, version 2 or (at your option) any later version. | ||
|
||
# 'qemu mtree' -- display the memory hierarchy | ||
|
||
import gdb | ||
|
||
def isnull(ptr): | ||
return ptr == gdb.Value(0).cast(ptr.type) | ||
|
||
def int128(p): | ||
return long(p['lo']) + (long(p['hi']) << 64) | ||
|
||
class MtreeCommand(gdb.Command): | ||
'''Display the memory tree hierarchy''' | ||
def __init__(self): | ||
gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA, | ||
gdb.COMPLETE_NONE) | ||
self.queue = [] | ||
def invoke(self, arg, from_tty): | ||
self.seen = set() | ||
self.queue_root('address_space_memory') | ||
self.queue_root('address_space_io') | ||
self.process_queue() | ||
def queue_root(self, varname): | ||
ptr = gdb.parse_and_eval(varname)['root'] | ||
self.queue.append(ptr) | ||
def process_queue(self): | ||
while self.queue: | ||
ptr = self.queue.pop(0) | ||
if long(ptr) in self.seen: | ||
continue | ||
self.print_item(ptr) | ||
def print_item(self, ptr, offset = gdb.Value(0), level = 0): | ||
self.seen.add(long(ptr)) | ||
addr = ptr['addr'] | ||
addr += offset | ||
size = int128(ptr['size']) | ||
alias = ptr['alias'] | ||
klass = '' | ||
if not isnull(alias): | ||
klass = ' (alias)' | ||
elif not isnull(ptr['ops']): | ||
klass = ' (I/O)' | ||
elif bool(ptr['ram']): | ||
klass = ' (RAM)' | ||
gdb.write('%s%016x-%016x %s%s (@ %s)\n' | ||
% (' ' * level, | ||
long(addr), | ||
long(addr + (size - 1)), | ||
ptr['name'].string(), | ||
klass, | ||
ptr, | ||
), | ||
gdb.STDOUT) | ||
if not isnull(alias): | ||
gdb.write('%s alias: %s@%016x (@ %s)\n' % | ||
(' ' * level, | ||
alias['name'].string(), | ||
ptr['alias_offset'], | ||
alias, | ||
), | ||
gdb.STDOUT) | ||
self.queue.append(alias) | ||
subregion = ptr['subregions']['tqh_first'] | ||
level += 1 | ||
while not isnull(subregion): | ||
self.print_item(subregion, addr, level) | ||
subregion = subregion['subregions_link']['tqe_next'] | ||
|