mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
1 Commits
gdb-15.2-r
...
users/sima
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c45c0c0fa |
@@ -39,7 +39,7 @@ to those that gdb produces.
|
||||
Finally, check that all strings are canonicalized identically.
|
||||
"""
|
||||
|
||||
__author__ = 'saugustine@google.com (Sterling Augustine)'
|
||||
__author__ = "saugustine@google.com (Sterling Augustine)"
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
@@ -49,159 +49,176 @@ OBJCOPY = None
|
||||
READELF = None
|
||||
GDB = None
|
||||
|
||||
|
||||
def get_pub_info(filename, readelf_option):
|
||||
"""Parse and return all the pubnames or pubtypes produced by readelf with the
|
||||
given option.
|
||||
"""
|
||||
readelf = subprocess.Popen([READELF, '--debug-dump=' + readelf_option,
|
||||
filename], stdout=subprocess.PIPE)
|
||||
pubnames = []
|
||||
"""Parse and return all the pubnames or pubtypes produced by readelf with the
|
||||
given option.
|
||||
"""
|
||||
readelf = subprocess.Popen(
|
||||
[READELF, "--debug-dump=" + readelf_option, filename], stdout=subprocess.PIPE
|
||||
)
|
||||
pubnames = []
|
||||
|
||||
in_list = False;
|
||||
for line in readelf.stdout:
|
||||
fields = line.split(None, 1)
|
||||
if (len(fields) == 2 and fields[0] == 'Offset'
|
||||
and fields[1].strip() == 'Name'):
|
||||
in_list = True
|
||||
# Either a blank-line or a new Length field terminates the current section.
|
||||
elif (len(fields) == 0 or fields[0] == 'Length:'):
|
||||
in_list = False;
|
||||
elif (in_list):
|
||||
pubnames.append(fields[1].strip())
|
||||
in_list = False
|
||||
for line in readelf.stdout:
|
||||
fields = line.split(None, 1)
|
||||
if len(fields) == 2 and fields[0] == "Offset" and fields[1].strip() == "Name":
|
||||
in_list = True
|
||||
# Either a blank-line or a new Length field terminates the current section.
|
||||
elif len(fields) == 0 or fields[0] == "Length:":
|
||||
in_list = False
|
||||
elif in_list:
|
||||
pubnames.append(fields[1].strip())
|
||||
|
||||
readelf.wait()
|
||||
return pubnames
|
||||
readelf.wait()
|
||||
return pubnames
|
||||
|
||||
|
||||
def get_gdb_index(filename):
|
||||
"""Use readelf to dump the gdb index and collect the types and names"""
|
||||
readelf = subprocess.Popen([READELF, '--debug-dump=gdb_index',
|
||||
filename], stdout=subprocess.PIPE)
|
||||
index_symbols = []
|
||||
symbol_table_started = False
|
||||
for line in readelf.stdout:
|
||||
if (line == 'Symbol table:\n'):
|
||||
symbol_table_started = True;
|
||||
elif (symbol_table_started):
|
||||
# Readelf prints gdb-index lines formatted like so:
|
||||
# [ 4] two::c2<double>::c2: 0
|
||||
# So take the string between the first close bracket and the last colon.
|
||||
index_symbols.append(line[line.find(']') + 2: line.rfind(':')])
|
||||
"""Use readelf to dump the gdb index and collect the types and names"""
|
||||
readelf = subprocess.Popen(
|
||||
[READELF, "--debug-dump=gdb_index", filename], stdout=subprocess.PIPE
|
||||
)
|
||||
index_symbols = []
|
||||
symbol_table_started = False
|
||||
for line in readelf.stdout:
|
||||
if line == "Symbol table:\n":
|
||||
symbol_table_started = True
|
||||
elif symbol_table_started:
|
||||
# Readelf prints gdb-index lines formatted like so:
|
||||
# [ 4] two::c2<double>::c2: 0
|
||||
# So take the string between the first close bracket and the last colon.
|
||||
index_symbols.append(line[line.find("]") + 2 : line.rfind(":")])
|
||||
|
||||
readelf.wait()
|
||||
return index_symbols
|
||||
readelf.wait()
|
||||
return index_symbols
|
||||
|
||||
|
||||
def CheckSets(list0, list1, name0, name1):
|
||||
"""Report any setwise differences between the two lists"""
|
||||
"""Report any setwise differences between the two lists"""
|
||||
|
||||
if len(list0) == 0 or len(list1) == 0:
|
||||
if len(list0) == 0 or len(list1) == 0:
|
||||
return False
|
||||
|
||||
difference0 = set(list0) - set(list1)
|
||||
if len(difference0) != 0:
|
||||
print "Elements in " + name0 + " but not " + name1 + ": (",
|
||||
print len(difference0),
|
||||
print ")"
|
||||
for element in difference0:
|
||||
print " " + element
|
||||
|
||||
difference1 = set(list1) - set(list0)
|
||||
if len(difference1) != 0:
|
||||
print "Elements in " + name1 + " but not " + name0 + ": (",
|
||||
print len(difference1),
|
||||
print ")"
|
||||
for element in difference1:
|
||||
print " " + element
|
||||
|
||||
if len(difference0) != 0 or len(difference1) != 0:
|
||||
return True
|
||||
|
||||
print name0 + " and " + name1 + " are identical."
|
||||
return False
|
||||
|
||||
difference0 = set(list0) - set(list1)
|
||||
if len(difference0) != 0:
|
||||
print "Elements in " + name0 + " but not " + name1 + ": (",
|
||||
print len(difference0),
|
||||
print ")"
|
||||
for element in difference0:
|
||||
print " " + element
|
||||
|
||||
difference1 = set(list1) - set(list0)
|
||||
if len(difference1) != 0:
|
||||
print "Elements in " + name1 + " but not " + name0 + ": (",
|
||||
print len(difference1),
|
||||
print ")"
|
||||
for element in difference1:
|
||||
print " " + element
|
||||
|
||||
if (len(difference0) != 0 or len(difference1) != 0):
|
||||
return True
|
||||
|
||||
print name0 + " and " + name1 + " are identical."
|
||||
return False
|
||||
|
||||
|
||||
def find_executables():
|
||||
"""Find the copies of readelf, objcopy and gdb to use."""
|
||||
# Executable finding logic follows cc-with-index.sh
|
||||
global READELF
|
||||
READELF = os.getenv('READELF')
|
||||
if READELF is None:
|
||||
READELF = 'readelf'
|
||||
global OBJCOPY
|
||||
OBJCOPY = os.getenv('OBJCOPY')
|
||||
if OBJCOPY is None:
|
||||
OBJCOPY = 'objcopy'
|
||||
"""Find the copies of readelf, objcopy and gdb to use."""
|
||||
# Executable finding logic follows cc-with-index.sh
|
||||
global READELF
|
||||
READELF = os.getenv("READELF")
|
||||
if READELF is None:
|
||||
READELF = "readelf"
|
||||
global OBJCOPY
|
||||
OBJCOPY = os.getenv("OBJCOPY")
|
||||
if OBJCOPY is None:
|
||||
OBJCOPY = "objcopy"
|
||||
|
||||
global GDB
|
||||
GDB = os.getenv('GDB')
|
||||
if (GDB is None):
|
||||
if os.path.isfile('./gdb') and os.access('./gdb', os.X_OK):
|
||||
GDB = './gdb'
|
||||
elif os.path.isfile('../gdb') and os.access('../gdb', os.X_OK):
|
||||
GDB = '../gdb'
|
||||
elif os.path.isfile('../../gdb') and os.access('../../gdb', os.X_OK):
|
||||
GDB = '../../gdb'
|
||||
else:
|
||||
# Punt and use the gdb in the path.
|
||||
GDB = 'gdb'
|
||||
global GDB
|
||||
GDB = os.getenv("GDB")
|
||||
if GDB is None:
|
||||
if os.path.isfile("./gdb") and os.access("./gdb", os.X_OK):
|
||||
GDB = "./gdb"
|
||||
elif os.path.isfile("../gdb") and os.access("../gdb", os.X_OK):
|
||||
GDB = "../gdb"
|
||||
elif os.path.isfile("../../gdb") and os.access("../../gdb", os.X_OK):
|
||||
GDB = "../../gdb"
|
||||
else:
|
||||
# Punt and use the gdb in the path.
|
||||
GDB = "gdb"
|
||||
|
||||
|
||||
def main(argv):
|
||||
"""The main subprogram."""
|
||||
if len(argv) != 2:
|
||||
print "Usage: test_pubnames_and_indexes.py <filename>"
|
||||
sys.exit(2)
|
||||
"""The main subprogram."""
|
||||
if len(argv) != 2:
|
||||
print "Usage: test_pubnames_and_indexes.py <filename>"
|
||||
sys.exit(2)
|
||||
|
||||
find_executables();
|
||||
find_executables()
|
||||
|
||||
# Get the index produced by Gold--It should have been built into the binary.
|
||||
gold_index = get_gdb_index(argv[1])
|
||||
# Get the index produced by Gold--It should have been built into the binary.
|
||||
gold_index = get_gdb_index(argv[1])
|
||||
|
||||
# Collect the pubnames and types list
|
||||
pubs_list = get_pub_info(argv[1], "pubnames")
|
||||
pubs_list = pubs_list + get_pub_info(argv[1], "pubtypes")
|
||||
# Collect the pubnames and types list
|
||||
pubs_list = get_pub_info(argv[1], "pubnames")
|
||||
pubs_list = pubs_list + get_pub_info(argv[1], "pubtypes")
|
||||
|
||||
# Generate a .gdb_index with gdb
|
||||
gdb_index_file = argv[1] + '.gdb-generated-index'
|
||||
subprocess.check_call([OBJCOPY, '--remove-section', '.gdb_index',
|
||||
argv[1], gdb_index_file])
|
||||
subprocess.check_call([GDB, '-batch', '-nx', gdb_index_file,
|
||||
'-ex', 'save gdb-index ' + os.path.dirname(argv[1]),
|
||||
'-ex', 'quit'])
|
||||
subprocess.check_call([OBJCOPY, '--add-section',
|
||||
'.gdb_index=' + gdb_index_file + '.gdb-index',
|
||||
gdb_index_file])
|
||||
gdb_index = get_gdb_index(gdb_index_file)
|
||||
os.remove(gdb_index_file)
|
||||
os.remove(gdb_index_file + '.gdb-index')
|
||||
# Generate a .gdb_index with gdb
|
||||
gdb_index_file = argv[1] + ".gdb-generated-index"
|
||||
subprocess.check_call(
|
||||
[OBJCOPY, "--remove-section", ".gdb_index", argv[1], gdb_index_file]
|
||||
)
|
||||
subprocess.check_call(
|
||||
[
|
||||
GDB,
|
||||
"-batch",
|
||||
"-nx",
|
||||
gdb_index_file,
|
||||
"-ex",
|
||||
"save gdb-index " + os.path.dirname(argv[1]),
|
||||
"-ex",
|
||||
"quit",
|
||||
]
|
||||
)
|
||||
subprocess.check_call(
|
||||
[
|
||||
OBJCOPY,
|
||||
"--add-section",
|
||||
".gdb_index=" + gdb_index_file + ".gdb-index",
|
||||
gdb_index_file,
|
||||
]
|
||||
)
|
||||
gdb_index = get_gdb_index(gdb_index_file)
|
||||
os.remove(gdb_index_file)
|
||||
os.remove(gdb_index_file + ".gdb-index")
|
||||
|
||||
failed = False
|
||||
gdb_index.sort()
|
||||
gold_index.sort()
|
||||
pubs_list.sort()
|
||||
failed = False
|
||||
gdb_index.sort()
|
||||
gold_index.sort()
|
||||
pubs_list.sort()
|
||||
|
||||
# Find the differences between the various indices.
|
||||
if len(gold_index) == 0:
|
||||
print "Gold index is empty"
|
||||
failed |= True
|
||||
# Find the differences between the various indices.
|
||||
if len(gold_index) == 0:
|
||||
print "Gold index is empty"
|
||||
failed |= True
|
||||
|
||||
if len(gdb_index) == 0:
|
||||
print "Gdb index is empty"
|
||||
failed |= True
|
||||
if len(gdb_index) == 0:
|
||||
print "Gdb index is empty"
|
||||
failed |= True
|
||||
|
||||
if len(pubs_list) == 0:
|
||||
print "Pubs list is empty"
|
||||
failed |= True
|
||||
if len(pubs_list) == 0:
|
||||
print "Pubs list is empty"
|
||||
failed |= True
|
||||
|
||||
failed |= CheckSets(gdb_index, gold_index, "gdb index", "gold index")
|
||||
failed |= CheckSets(pubs_list, gold_index, "pubs list", "gold index")
|
||||
failed |= CheckSets(pubs_list, gdb_index, "pubs list", "gdb index")
|
||||
failed |= CheckSets(gdb_index, gold_index, "gdb index", "gold index")
|
||||
failed |= CheckSets(pubs_list, gold_index, "pubs list", "gold index")
|
||||
failed |= CheckSets(pubs_list, gdb_index, "pubs list", "gdb index")
|
||||
|
||||
if failed:
|
||||
print "Test failed"
|
||||
sys.exit(1)
|
||||
if failed:
|
||||
print "Test failed"
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
|
||||
289
gdb/copyright.py
289
gdb/copyright.py
@@ -47,23 +47,32 @@ def get_update_list():
|
||||
"""
|
||||
result = []
|
||||
for gdb_dir in (
|
||||
'gdb', 'gdbserver', 'gdbsupport', 'gnulib', 'sim', 'include/gdb',
|
||||
"gdb",
|
||||
"gdbserver",
|
||||
"gdbsupport",
|
||||
"gnulib",
|
||||
"sim",
|
||||
"include/gdb",
|
||||
):
|
||||
for root, dirs, files in os.walk(gdb_dir, topdown=True):
|
||||
for dirname in dirs:
|
||||
reldirname = "%s/%s" % (root, dirname)
|
||||
if (dirname in EXCLUDE_ALL_LIST
|
||||
if (
|
||||
dirname in EXCLUDE_ALL_LIST
|
||||
or reldirname in EXCLUDE_LIST
|
||||
or reldirname in NOT_FSF_LIST
|
||||
or reldirname in BY_HAND):
|
||||
or reldirname in BY_HAND
|
||||
):
|
||||
# Prune this directory from our search list.
|
||||
dirs.remove(dirname)
|
||||
for filename in files:
|
||||
relpath = "%s/%s" % (root, filename)
|
||||
if (filename in EXCLUDE_ALL_LIST
|
||||
if (
|
||||
filename in EXCLUDE_ALL_LIST
|
||||
or relpath in EXCLUDE_LIST
|
||||
or relpath in NOT_FSF_LIST
|
||||
or relpath in BY_HAND):
|
||||
or relpath in BY_HAND
|
||||
):
|
||||
# Ignore this file.
|
||||
pass
|
||||
else:
|
||||
@@ -80,15 +89,18 @@ def update_files(update_list):
|
||||
# all years should be collapsed to one single year interval,
|
||||
# even if there are "holes" in the list of years found in the
|
||||
# original copyright notice (OK'ed by the FSF, case [gnu.org #719834]).
|
||||
os.environ['UPDATE_COPYRIGHT_USE_INTERVALS'] = '2'
|
||||
os.environ["UPDATE_COPYRIGHT_USE_INTERVALS"] = "2"
|
||||
|
||||
# Perform the update, and save the output in a string.
|
||||
update_cmd = ['bash', 'gnulib/import/extra/update-copyright']
|
||||
update_cmd = ["bash", "gnulib/import/extra/update-copyright"]
|
||||
update_cmd += update_list
|
||||
|
||||
p = subprocess.Popen(update_cmd, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
encoding=locale.getpreferredencoding())
|
||||
p = subprocess.Popen(
|
||||
update_cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
encoding=locale.getpreferredencoding(),
|
||||
)
|
||||
update_out = p.communicate()[0]
|
||||
|
||||
# Process the output. Typically, a lot of files do not have
|
||||
@@ -100,7 +112,7 @@ def update_files(update_list):
|
||||
# short of looking at each file and seeing which notice is appropriate.
|
||||
# Too much work! (~4,000 files listed as of 2012-01-03).
|
||||
update_out = update_out.splitlines(keepends=False)
|
||||
warning_string = ': warning: copyright statement not found'
|
||||
warning_string = ": warning: copyright statement not found"
|
||||
warning_len = len(warning_string)
|
||||
|
||||
for line in update_out:
|
||||
@@ -134,11 +146,11 @@ def may_have_copyright_notice(filename):
|
||||
# so just open the file as a byte stream. We only need to search
|
||||
# for a pattern that should be the same regardless of encoding,
|
||||
# so that should be good enough.
|
||||
fd = open(filename, 'rb')
|
||||
fd = open(filename, "rb")
|
||||
|
||||
lineno = 1
|
||||
for line in fd:
|
||||
if b'Copyright' in line:
|
||||
if b"Copyright" in line:
|
||||
return True
|
||||
lineno += 1
|
||||
if lineno > 50:
|
||||
@@ -146,36 +158,41 @@ def may_have_copyright_notice(filename):
|
||||
return False
|
||||
|
||||
|
||||
def main ():
|
||||
def main():
|
||||
"""The main subprogram."""
|
||||
root_dir = os.path.dirname(os.getcwd())
|
||||
os.chdir(root_dir)
|
||||
|
||||
if not (os.path.isdir('gdb') and
|
||||
os.path.isfile("gnulib/import/extra/update-copyright")):
|
||||
if not (
|
||||
os.path.isdir("gdb") and os.path.isfile("gnulib/import/extra/update-copyright")
|
||||
):
|
||||
print("Error: This script must be called from the gdb directory.")
|
||||
sys.exit(1)
|
||||
|
||||
update_list = get_update_list()
|
||||
update_files (update_list)
|
||||
update_files(update_list)
|
||||
|
||||
# Remind the user that some files need to be updated by HAND...
|
||||
|
||||
if MULTIPLE_COPYRIGHT_HEADERS:
|
||||
print()
|
||||
print("\033[31m"
|
||||
"REMINDER: Multiple copyright headers must be updated by hand:"
|
||||
"\033[0m")
|
||||
print(
|
||||
"\033[31m"
|
||||
"REMINDER: Multiple copyright headers must be updated by hand:"
|
||||
"\033[0m"
|
||||
)
|
||||
for filename in MULTIPLE_COPYRIGHT_HEADERS:
|
||||
print(" ", filename)
|
||||
|
||||
if BY_HAND:
|
||||
print()
|
||||
print("\033[31mREMINDER: The following files must be updated by hand." \
|
||||
"\033[0m")
|
||||
print(
|
||||
"\033[31mREMINDER: The following files must be updated by hand." "\033[0m"
|
||||
)
|
||||
for filename in BY_HAND:
|
||||
print(" ", filename)
|
||||
|
||||
|
||||
############################################################################
|
||||
#
|
||||
# Some constants, placed at the end because they take up a lot of room.
|
||||
@@ -190,11 +207,11 @@ def main ():
|
||||
#
|
||||
# Filenames are relative to the root directory.
|
||||
EXCLUDE_LIST = (
|
||||
'gdb/nat/glibc_thread_db.h',
|
||||
'gdb/CONTRIBUTE',
|
||||
'gnulib/import',
|
||||
'gnulib/config.in',
|
||||
'gnulib/Makefile.in',
|
||||
"gdb/nat/glibc_thread_db.h",
|
||||
"gdb/CONTRIBUTE",
|
||||
"gnulib/import",
|
||||
"gnulib/config.in",
|
||||
"gnulib/Makefile.in",
|
||||
)
|
||||
|
||||
# Files which should not be modified, either because they are
|
||||
@@ -206,8 +223,14 @@ EXCLUDE_LIST = (
|
||||
# Eg: We want all files named COPYING to be left untouched.
|
||||
|
||||
EXCLUDE_ALL_LIST = (
|
||||
"COPYING", "COPYING.LIB", "CVS", "configure", "copying.c",
|
||||
"fdl.texi", "gpl.texi", "aclocal.m4",
|
||||
"COPYING",
|
||||
"COPYING.LIB",
|
||||
"CVS",
|
||||
"configure",
|
||||
"copying.c",
|
||||
"fdl.texi",
|
||||
"gpl.texi",
|
||||
"aclocal.m4",
|
||||
)
|
||||
|
||||
# The list of files to update by hand.
|
||||
@@ -230,66 +253,166 @@ NOT_FSF_LIST = (
|
||||
"gdb/exc_request.defs",
|
||||
"gdb/gdbtk",
|
||||
"gdb/testsuite/gdb.gdbtk/",
|
||||
"sim/arm/armemu.h", "sim/arm/armos.c", "sim/arm/gdbhost.c",
|
||||
"sim/arm/dbg_hif.h", "sim/arm/dbg_conf.h", "sim/arm/communicate.h",
|
||||
"sim/arm/armos.h", "sim/arm/armcopro.c", "sim/arm/armemu.c",
|
||||
"sim/arm/kid.c", "sim/arm/thumbemu.c", "sim/arm/armdefs.h",
|
||||
"sim/arm/armopts.h", "sim/arm/dbg_cp.h", "sim/arm/dbg_rdi.h",
|
||||
"sim/arm/parent.c", "sim/arm/armsupp.c", "sim/arm/armrdi.c",
|
||||
"sim/arm/bag.c", "sim/arm/armvirt.c", "sim/arm/main.c", "sim/arm/bag.h",
|
||||
"sim/arm/communicate.c", "sim/arm/gdbhost.h", "sim/arm/armfpe.h",
|
||||
"sim/arm/armemu.h",
|
||||
"sim/arm/armos.c",
|
||||
"sim/arm/gdbhost.c",
|
||||
"sim/arm/dbg_hif.h",
|
||||
"sim/arm/dbg_conf.h",
|
||||
"sim/arm/communicate.h",
|
||||
"sim/arm/armos.h",
|
||||
"sim/arm/armcopro.c",
|
||||
"sim/arm/armemu.c",
|
||||
"sim/arm/kid.c",
|
||||
"sim/arm/thumbemu.c",
|
||||
"sim/arm/armdefs.h",
|
||||
"sim/arm/armopts.h",
|
||||
"sim/arm/dbg_cp.h",
|
||||
"sim/arm/dbg_rdi.h",
|
||||
"sim/arm/parent.c",
|
||||
"sim/arm/armsupp.c",
|
||||
"sim/arm/armrdi.c",
|
||||
"sim/arm/bag.c",
|
||||
"sim/arm/armvirt.c",
|
||||
"sim/arm/main.c",
|
||||
"sim/arm/bag.h",
|
||||
"sim/arm/communicate.c",
|
||||
"sim/arm/gdbhost.h",
|
||||
"sim/arm/armfpe.h",
|
||||
"sim/arm/arminit.c",
|
||||
"sim/common/cgen-fpu.c", "sim/common/cgen-fpu.h",
|
||||
"sim/common/cgen-fpu.c",
|
||||
"sim/common/cgen-fpu.h",
|
||||
"sim/common/cgen-accfp.c",
|
||||
"sim/mips/m16run.c", "sim/mips/sim-main.c",
|
||||
"sim/mips/m16run.c",
|
||||
"sim/mips/sim-main.c",
|
||||
"sim/moxie/moxie-gdb.dts",
|
||||
# Not a single file in sim/ppc/ appears to be copyright FSF :-(.
|
||||
"sim/ppc/filter.h", "sim/ppc/gen-support.h", "sim/ppc/ld-insn.h",
|
||||
"sim/ppc/hw_sem.c", "sim/ppc/hw_disk.c", "sim/ppc/idecode_branch.h",
|
||||
"sim/ppc/sim-endian.h", "sim/ppc/table.c", "sim/ppc/hw_core.c",
|
||||
"sim/ppc/gen-support.c", "sim/ppc/gen-semantics.h", "sim/ppc/cpu.h",
|
||||
"sim/ppc/sim_callbacks.h", "sim/ppc/RUN", "sim/ppc/Makefile.in",
|
||||
"sim/ppc/emul_chirp.c", "sim/ppc/hw_nvram.c", "sim/ppc/dc-test.01",
|
||||
"sim/ppc/hw_phb.c", "sim/ppc/hw_eeprom.c", "sim/ppc/bits.h",
|
||||
"sim/ppc/hw_vm.c", "sim/ppc/cap.h", "sim/ppc/os_emul.h",
|
||||
"sim/ppc/options.h", "sim/ppc/gen-idecode.c", "sim/ppc/filter.c",
|
||||
"sim/ppc/corefile-n.h", "sim/ppc/std-config.h", "sim/ppc/ld-decode.h",
|
||||
"sim/ppc/filter_filename.h", "sim/ppc/hw_shm.c",
|
||||
"sim/ppc/pk_disklabel.c", "sim/ppc/dc-simple", "sim/ppc/misc.h",
|
||||
"sim/ppc/device_table.h", "sim/ppc/ld-insn.c", "sim/ppc/inline.c",
|
||||
"sim/ppc/emul_bugapi.h", "sim/ppc/hw_cpu.h", "sim/ppc/debug.h",
|
||||
"sim/ppc/hw_ide.c", "sim/ppc/debug.c", "sim/ppc/gen-itable.h",
|
||||
"sim/ppc/interrupts.c", "sim/ppc/hw_glue.c", "sim/ppc/emul_unix.c",
|
||||
"sim/ppc/sim_calls.c", "sim/ppc/dc-complex", "sim/ppc/ld-cache.c",
|
||||
"sim/ppc/registers.h", "sim/ppc/dc-test.02", "sim/ppc/options.c",
|
||||
"sim/ppc/igen.h", "sim/ppc/registers.c", "sim/ppc/device.h",
|
||||
"sim/ppc/emul_chirp.h", "sim/ppc/hw_register.c", "sim/ppc/hw_init.c",
|
||||
"sim/ppc/sim-endian-n.h", "sim/ppc/filter_filename.c",
|
||||
"sim/ppc/bits.c", "sim/ppc/idecode_fields.h", "sim/ppc/hw_memory.c",
|
||||
"sim/ppc/misc.c", "sim/ppc/double.c", "sim/ppc/psim.h",
|
||||
"sim/ppc/hw_trace.c", "sim/ppc/emul_netbsd.h", "sim/ppc/psim.c",
|
||||
"sim/ppc/ppc-instructions", "sim/ppc/tree.h", "sim/ppc/README",
|
||||
"sim/ppc/gen-icache.h", "sim/ppc/gen-model.h", "sim/ppc/ld-cache.h",
|
||||
"sim/ppc/mon.c", "sim/ppc/corefile.h", "sim/ppc/vm.c",
|
||||
"sim/ppc/INSTALL", "sim/ppc/gen-model.c", "sim/ppc/hw_cpu.c",
|
||||
"sim/ppc/corefile.c", "sim/ppc/hw_opic.c", "sim/ppc/gen-icache.c",
|
||||
"sim/ppc/events.h", "sim/ppc/os_emul.c", "sim/ppc/emul_generic.c",
|
||||
"sim/ppc/main.c", "sim/ppc/hw_com.c", "sim/ppc/gen-semantics.c",
|
||||
"sim/ppc/emul_bugapi.c", "sim/ppc/device.c", "sim/ppc/emul_generic.h",
|
||||
"sim/ppc/tree.c", "sim/ppc/mon.h", "sim/ppc/interrupts.h",
|
||||
"sim/ppc/cap.c", "sim/ppc/cpu.c", "sim/ppc/hw_phb.h",
|
||||
"sim/ppc/device_table.c", "sim/ppc/lf.c", "sim/ppc/lf.c",
|
||||
"sim/ppc/dc-stupid", "sim/ppc/hw_pal.c", "sim/ppc/ppc-spr-table",
|
||||
"sim/ppc/emul_unix.h", "sim/ppc/words.h", "sim/ppc/basics.h",
|
||||
"sim/ppc/hw_htab.c", "sim/ppc/lf.h", "sim/ppc/ld-decode.c",
|
||||
"sim/ppc/sim-endian.c", "sim/ppc/gen-itable.c",
|
||||
"sim/ppc/idecode_expression.h", "sim/ppc/table.h", "sim/ppc/dgen.c",
|
||||
"sim/ppc/events.c", "sim/ppc/gen-idecode.h", "sim/ppc/emul_netbsd.c",
|
||||
"sim/ppc/igen.c", "sim/ppc/vm_n.h", "sim/ppc/vm.h",
|
||||
"sim/ppc/hw_iobus.c", "sim/ppc/inline.h",
|
||||
"sim/ppc/filter.h",
|
||||
"sim/ppc/gen-support.h",
|
||||
"sim/ppc/ld-insn.h",
|
||||
"sim/ppc/hw_sem.c",
|
||||
"sim/ppc/hw_disk.c",
|
||||
"sim/ppc/idecode_branch.h",
|
||||
"sim/ppc/sim-endian.h",
|
||||
"sim/ppc/table.c",
|
||||
"sim/ppc/hw_core.c",
|
||||
"sim/ppc/gen-support.c",
|
||||
"sim/ppc/gen-semantics.h",
|
||||
"sim/ppc/cpu.h",
|
||||
"sim/ppc/sim_callbacks.h",
|
||||
"sim/ppc/RUN",
|
||||
"sim/ppc/Makefile.in",
|
||||
"sim/ppc/emul_chirp.c",
|
||||
"sim/ppc/hw_nvram.c",
|
||||
"sim/ppc/dc-test.01",
|
||||
"sim/ppc/hw_phb.c",
|
||||
"sim/ppc/hw_eeprom.c",
|
||||
"sim/ppc/bits.h",
|
||||
"sim/ppc/hw_vm.c",
|
||||
"sim/ppc/cap.h",
|
||||
"sim/ppc/os_emul.h",
|
||||
"sim/ppc/options.h",
|
||||
"sim/ppc/gen-idecode.c",
|
||||
"sim/ppc/filter.c",
|
||||
"sim/ppc/corefile-n.h",
|
||||
"sim/ppc/std-config.h",
|
||||
"sim/ppc/ld-decode.h",
|
||||
"sim/ppc/filter_filename.h",
|
||||
"sim/ppc/hw_shm.c",
|
||||
"sim/ppc/pk_disklabel.c",
|
||||
"sim/ppc/dc-simple",
|
||||
"sim/ppc/misc.h",
|
||||
"sim/ppc/device_table.h",
|
||||
"sim/ppc/ld-insn.c",
|
||||
"sim/ppc/inline.c",
|
||||
"sim/ppc/emul_bugapi.h",
|
||||
"sim/ppc/hw_cpu.h",
|
||||
"sim/ppc/debug.h",
|
||||
"sim/ppc/hw_ide.c",
|
||||
"sim/ppc/debug.c",
|
||||
"sim/ppc/gen-itable.h",
|
||||
"sim/ppc/interrupts.c",
|
||||
"sim/ppc/hw_glue.c",
|
||||
"sim/ppc/emul_unix.c",
|
||||
"sim/ppc/sim_calls.c",
|
||||
"sim/ppc/dc-complex",
|
||||
"sim/ppc/ld-cache.c",
|
||||
"sim/ppc/registers.h",
|
||||
"sim/ppc/dc-test.02",
|
||||
"sim/ppc/options.c",
|
||||
"sim/ppc/igen.h",
|
||||
"sim/ppc/registers.c",
|
||||
"sim/ppc/device.h",
|
||||
"sim/ppc/emul_chirp.h",
|
||||
"sim/ppc/hw_register.c",
|
||||
"sim/ppc/hw_init.c",
|
||||
"sim/ppc/sim-endian-n.h",
|
||||
"sim/ppc/filter_filename.c",
|
||||
"sim/ppc/bits.c",
|
||||
"sim/ppc/idecode_fields.h",
|
||||
"sim/ppc/hw_memory.c",
|
||||
"sim/ppc/misc.c",
|
||||
"sim/ppc/double.c",
|
||||
"sim/ppc/psim.h",
|
||||
"sim/ppc/hw_trace.c",
|
||||
"sim/ppc/emul_netbsd.h",
|
||||
"sim/ppc/psim.c",
|
||||
"sim/ppc/ppc-instructions",
|
||||
"sim/ppc/tree.h",
|
||||
"sim/ppc/README",
|
||||
"sim/ppc/gen-icache.h",
|
||||
"sim/ppc/gen-model.h",
|
||||
"sim/ppc/ld-cache.h",
|
||||
"sim/ppc/mon.c",
|
||||
"sim/ppc/corefile.h",
|
||||
"sim/ppc/vm.c",
|
||||
"sim/ppc/INSTALL",
|
||||
"sim/ppc/gen-model.c",
|
||||
"sim/ppc/hw_cpu.c",
|
||||
"sim/ppc/corefile.c",
|
||||
"sim/ppc/hw_opic.c",
|
||||
"sim/ppc/gen-icache.c",
|
||||
"sim/ppc/events.h",
|
||||
"sim/ppc/os_emul.c",
|
||||
"sim/ppc/emul_generic.c",
|
||||
"sim/ppc/main.c",
|
||||
"sim/ppc/hw_com.c",
|
||||
"sim/ppc/gen-semantics.c",
|
||||
"sim/ppc/emul_bugapi.c",
|
||||
"sim/ppc/device.c",
|
||||
"sim/ppc/emul_generic.h",
|
||||
"sim/ppc/tree.c",
|
||||
"sim/ppc/mon.h",
|
||||
"sim/ppc/interrupts.h",
|
||||
"sim/ppc/cap.c",
|
||||
"sim/ppc/cpu.c",
|
||||
"sim/ppc/hw_phb.h",
|
||||
"sim/ppc/device_table.c",
|
||||
"sim/ppc/lf.c",
|
||||
"sim/ppc/lf.c",
|
||||
"sim/ppc/dc-stupid",
|
||||
"sim/ppc/hw_pal.c",
|
||||
"sim/ppc/ppc-spr-table",
|
||||
"sim/ppc/emul_unix.h",
|
||||
"sim/ppc/words.h",
|
||||
"sim/ppc/basics.h",
|
||||
"sim/ppc/hw_htab.c",
|
||||
"sim/ppc/lf.h",
|
||||
"sim/ppc/ld-decode.c",
|
||||
"sim/ppc/sim-endian.c",
|
||||
"sim/ppc/gen-itable.c",
|
||||
"sim/ppc/idecode_expression.h",
|
||||
"sim/ppc/table.h",
|
||||
"sim/ppc/dgen.c",
|
||||
"sim/ppc/events.c",
|
||||
"sim/ppc/gen-idecode.h",
|
||||
"sim/ppc/emul_netbsd.c",
|
||||
"sim/ppc/igen.c",
|
||||
"sim/ppc/vm_n.h",
|
||||
"sim/ppc/vm.h",
|
||||
"sim/ppc/hw_iobus.c",
|
||||
"sim/ppc/inline.h",
|
||||
"sim/testsuite/sim/mips/mips32-dsp2.s",
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ try:
|
||||
except NameError:
|
||||
basestring = str
|
||||
|
||||
|
||||
class FrameDecorator(object):
|
||||
"""Basic implementation of a Frame Decorator"""
|
||||
|
||||
@@ -66,9 +67,12 @@ class FrameDecorator(object):
|
||||
limited."""
|
||||
sal = frame.find_sal()
|
||||
|
||||
if (not sal.symtab or not sal.symtab.filename
|
||||
if (
|
||||
not sal.symtab
|
||||
or not sal.symtab.filename
|
||||
or frame.type() == gdb.DUMMY_FRAME
|
||||
or frame.type() == gdb.SIGTRAMP_FRAME):
|
||||
or frame.type() == gdb.SIGTRAMP_FRAME
|
||||
):
|
||||
|
||||
return True
|
||||
|
||||
@@ -83,7 +87,7 @@ class FrameDecorator(object):
|
||||
return None
|
||||
|
||||
def function(self):
|
||||
""" Return the name of the frame's function or an address of
|
||||
"""Return the name of the frame's function or an address of
|
||||
the function of the frame. First determine if this is a
|
||||
special frame. If not, try to determine filename from GDB's
|
||||
frame internal function API. Finally, if a name cannot be
|
||||
@@ -120,7 +124,7 @@ class FrameDecorator(object):
|
||||
return str(func)
|
||||
|
||||
def address(self):
|
||||
""" Return the address of the frame's pc"""
|
||||
"""Return the address of the frame's pc"""
|
||||
|
||||
if hasattr(self._base, "address"):
|
||||
return self._base.address()
|
||||
@@ -129,7 +133,7 @@ class FrameDecorator(object):
|
||||
return frame.pc()
|
||||
|
||||
def filename(self):
|
||||
""" Return the filename associated with this frame, detecting
|
||||
"""Return the filename associated with this frame, detecting
|
||||
and returning the appropriate library name is this is a shared
|
||||
library."""
|
||||
|
||||
@@ -145,7 +149,7 @@ class FrameDecorator(object):
|
||||
return sal.symtab.filename
|
||||
|
||||
def frame_args(self):
|
||||
""" Return an iterable of frame arguments for this frame, if
|
||||
"""Return an iterable of frame arguments for this frame, if
|
||||
any. The iterable object contains objects conforming with the
|
||||
Symbol/Value interface. If there are no frame arguments, or
|
||||
if this frame is deemed to be a special case, return None."""
|
||||
@@ -161,7 +165,7 @@ class FrameDecorator(object):
|
||||
return args.fetch_frame_args()
|
||||
|
||||
def frame_locals(self):
|
||||
""" Return an iterable of local variables for this frame, if
|
||||
"""Return an iterable of local variables for this frame, if
|
||||
any. The iterable object contains objects conforming with the
|
||||
Symbol/Value interface. If there are no frame locals, or if
|
||||
this frame is deemed to be a special case, return None."""
|
||||
@@ -177,7 +181,7 @@ class FrameDecorator(object):
|
||||
return args.fetch_frame_locals()
|
||||
|
||||
def line(self):
|
||||
""" Return line number information associated with the frame's
|
||||
"""Return line number information associated with the frame's
|
||||
pc. If symbol table/line information does not exist, or if
|
||||
this frame is deemed to be a special case, return None"""
|
||||
|
||||
@@ -189,13 +193,13 @@ class FrameDecorator(object):
|
||||
return None
|
||||
|
||||
sal = frame.find_sal()
|
||||
if (sal):
|
||||
if sal:
|
||||
return sal.line
|
||||
else:
|
||||
return None
|
||||
|
||||
def inferior_frame(self):
|
||||
""" Return the gdb.Frame underpinning this frame decorator."""
|
||||
"""Return the gdb.Frame underpinning this frame decorator."""
|
||||
|
||||
# If 'base' is a frame decorator, we want to call its inferior
|
||||
# frame method. If '_base' is a gdb.Frame, just return that.
|
||||
@@ -203,22 +207,25 @@ class FrameDecorator(object):
|
||||
return self._base.inferior_frame()
|
||||
return self._base
|
||||
|
||||
|
||||
class SymValueWrapper(object):
|
||||
"""A container class conforming to the Symbol/Value interface
|
||||
which holds frame locals or frame arguments."""
|
||||
|
||||
def __init__(self, symbol, value):
|
||||
self.sym = symbol
|
||||
self.val = value
|
||||
|
||||
def value(self):
|
||||
""" Return the value associated with this symbol, or None"""
|
||||
"""Return the value associated with this symbol, or None"""
|
||||
return self.val
|
||||
|
||||
def symbol(self):
|
||||
""" Return the symbol, or Python text, associated with this
|
||||
"""Return the symbol, or Python text, associated with this
|
||||
symbol, or None"""
|
||||
return self.sym
|
||||
|
||||
|
||||
class FrameVars(object):
|
||||
|
||||
"""Utility class to fetch and store frame local variables, or
|
||||
@@ -232,12 +239,12 @@ class FrameVars(object):
|
||||
gdb.SYMBOL_LOC_ARG: True,
|
||||
gdb.SYMBOL_LOC_REF_ARG: True,
|
||||
gdb.SYMBOL_LOC_LOCAL: True,
|
||||
gdb.SYMBOL_LOC_REGPARM_ADDR: True,
|
||||
gdb.SYMBOL_LOC_COMPUTED: True
|
||||
}
|
||||
gdb.SYMBOL_LOC_REGPARM_ADDR: True,
|
||||
gdb.SYMBOL_LOC_COMPUTED: True,
|
||||
}
|
||||
|
||||
def fetch_b(self, sym):
|
||||
""" Local utility method to determine if according to Symbol
|
||||
"""Local utility method to determine if according to Symbol
|
||||
type whether it should be included in the iterator. Not all
|
||||
symbols are fetched, and only symbols that return
|
||||
True from this method should be fetched."""
|
||||
@@ -268,7 +275,7 @@ class FrameVars(object):
|
||||
break
|
||||
for sym in block:
|
||||
if sym.is_argument:
|
||||
continue;
|
||||
continue
|
||||
if self.fetch_b(sym):
|
||||
lvars.append(SymValueWrapper(sym, None))
|
||||
|
||||
@@ -296,7 +303,7 @@ class FrameVars(object):
|
||||
if block != None:
|
||||
for sym in block:
|
||||
if not sym.is_argument:
|
||||
continue;
|
||||
continue
|
||||
args.append(SymValueWrapper(sym, None))
|
||||
|
||||
return args
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import gdb
|
||||
import itertools
|
||||
|
||||
|
||||
class FrameIterator(object):
|
||||
"""A gdb.Frame iterator. Iterates over gdb.Frames or objects that
|
||||
conform to that interface."""
|
||||
|
||||
@@ -26,7 +26,8 @@ elif sys.version_info[0] > 2:
|
||||
|
||||
from _gdb import *
|
||||
|
||||
class _GdbFile (object):
|
||||
|
||||
class _GdbFile(object):
|
||||
# These two are needed in Python 3
|
||||
encoding = "UTF-8"
|
||||
errors = "strict"
|
||||
@@ -45,16 +46,20 @@ class _GdbFile (object):
|
||||
def flush(self):
|
||||
flush()
|
||||
|
||||
class _GdbOutputFile (_GdbFile):
|
||||
|
||||
class _GdbOutputFile(_GdbFile):
|
||||
def write(self, s):
|
||||
write(s, stream=STDOUT)
|
||||
|
||||
|
||||
sys.stdout = _GdbOutputFile()
|
||||
|
||||
class _GdbOutputErrorFile (_GdbFile):
|
||||
|
||||
class _GdbOutputErrorFile(_GdbFile):
|
||||
def write(self, s):
|
||||
write(s, stream=STDERR)
|
||||
|
||||
|
||||
sys.stderr = _GdbOutputErrorFile()
|
||||
|
||||
# Default prompt hook does nothing.
|
||||
@@ -62,7 +67,7 @@ prompt_hook = None
|
||||
|
||||
# Ensure that sys.argv is set to something.
|
||||
# We do not use PySys_SetArgvEx because it did not appear until 2.6.6.
|
||||
sys.argv = ['']
|
||||
sys.argv = [""]
|
||||
|
||||
# Initial pretty printers.
|
||||
pretty_printers = []
|
||||
@@ -76,6 +81,7 @@ frame_filters = {}
|
||||
# Initial frame unwinders.
|
||||
frame_unwinders = []
|
||||
|
||||
|
||||
def _execute_unwinders(pending_frame):
|
||||
"""Internal function called from GDB to execute all unwinders.
|
||||
|
||||
@@ -108,6 +114,7 @@ def _execute_unwinders(pending_frame):
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _execute_file(filepath):
|
||||
"""This function is used to replace Python 2's PyRun_SimpleFile.
|
||||
|
||||
@@ -117,22 +124,22 @@ def _execute_file(filepath):
|
||||
"Furthermore, any functions and classes defined by the executed code are
|
||||
not guaranteed to work correctly after a runpy function has returned."
|
||||
"""
|
||||
globals = sys.modules['__main__'].__dict__
|
||||
globals = sys.modules["__main__"].__dict__
|
||||
set_file = False
|
||||
# Set file (if not set) so that the imported file can use it (e.g. to
|
||||
# access file-relative paths). This matches what PyRun_SimpleFile does.
|
||||
if not hasattr(globals, '__file__'):
|
||||
globals['__file__'] = filepath
|
||||
if not hasattr(globals, "__file__"):
|
||||
globals["__file__"] = filepath
|
||||
set_file = True
|
||||
try:
|
||||
with open(filepath, 'rb') as file:
|
||||
with open(filepath, "rb") as file:
|
||||
# We pass globals also as locals to match what Python does
|
||||
# in PyRun_SimpleFile.
|
||||
compiled = compile(file.read(), filepath, 'exec')
|
||||
compiled = compile(file.read(), filepath, "exec")
|
||||
exec(compiled, globals, globals)
|
||||
finally:
|
||||
if set_file:
|
||||
del globals['__file__']
|
||||
del globals["__file__"]
|
||||
|
||||
|
||||
# Convenience variable to GDB's python directory
|
||||
@@ -142,27 +149,24 @@ PYTHONDIR = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
# Packages to auto-load.
|
||||
|
||||
packages = [
|
||||
'function',
|
||||
'command',
|
||||
'printer'
|
||||
]
|
||||
packages = ["function", "command", "printer"]
|
||||
|
||||
# pkgutil.iter_modules is not available prior to Python 2.6. Instead,
|
||||
# manually iterate the list, collating the Python files in each module
|
||||
# path. Construct the module name, and import.
|
||||
|
||||
|
||||
def _auto_load_packages():
|
||||
for package in packages:
|
||||
location = os.path.join(os.path.dirname(__file__), package)
|
||||
if os.path.exists(location):
|
||||
py_files = filter(lambda x: x.endswith('.py')
|
||||
and x != '__init__.py',
|
||||
os.listdir(location))
|
||||
py_files = filter(
|
||||
lambda x: x.endswith(".py") and x != "__init__.py", os.listdir(location)
|
||||
)
|
||||
|
||||
for py_file in py_files:
|
||||
# Construct from foo.py, gdb.module.foo
|
||||
modname = "%s.%s.%s" % ( __name__, package, py_file[:-3] )
|
||||
modname = "%s.%s.%s" % (__name__, package, py_file[:-3])
|
||||
try:
|
||||
if modname in sys.modules:
|
||||
# reload modules with duplicate names
|
||||
@@ -170,10 +174,12 @@ def _auto_load_packages():
|
||||
else:
|
||||
__import__(modname)
|
||||
except:
|
||||
sys.stderr.write (traceback.format_exc() + "\n")
|
||||
sys.stderr.write(traceback.format_exc() + "\n")
|
||||
|
||||
|
||||
_auto_load_packages()
|
||||
|
||||
|
||||
def GdbSetPythonDirectory(dir):
|
||||
"""Update sys.path, reload gdb and auto-load packages."""
|
||||
global PYTHONDIR
|
||||
@@ -191,30 +197,37 @@ def GdbSetPythonDirectory(dir):
|
||||
reload(__import__(__name__))
|
||||
_auto_load_packages()
|
||||
|
||||
|
||||
def current_progspace():
|
||||
"Return the current Progspace."
|
||||
return selected_inferior().progspace
|
||||
|
||||
|
||||
def objfiles():
|
||||
"Return a sequence of the current program space's objfiles."
|
||||
return current_progspace().objfiles()
|
||||
|
||||
def solib_name (addr):
|
||||
|
||||
def solib_name(addr):
|
||||
"""solib_name (Long) -> String.\n\
|
||||
Return the name of the shared library holding a given address, or None."""
|
||||
return current_progspace().solib_name(addr)
|
||||
|
||||
|
||||
def block_for_pc(pc):
|
||||
"Return the block containing the given pc value, or None."
|
||||
return current_progspace().block_for_pc(pc)
|
||||
|
||||
|
||||
def find_pc_line(pc):
|
||||
"""find_pc_line (pc) -> Symtab_and_line.
|
||||
Return the gdb.Symtab_and_line object corresponding to the pc value."""
|
||||
Return the gdb.Symtab_and_line object corresponding to the pc value."""
|
||||
return current_progspace().find_pc_line(pc)
|
||||
|
||||
|
||||
try:
|
||||
from pygments import formatters, lexers, highlight
|
||||
|
||||
def colorize(filename, contents):
|
||||
# Don't want any errors.
|
||||
try:
|
||||
@@ -223,6 +236,9 @@ try:
|
||||
return highlight(contents, lexer, formatter)
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
except:
|
||||
|
||||
def colorize(filename, contents):
|
||||
return None
|
||||
|
||||
@@ -12,5 +12,3 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
@@ -22,12 +22,13 @@ import sys
|
||||
if sys.version_info[0] > 2:
|
||||
# Python 3 renamed raw_input to input
|
||||
raw_input = input
|
||||
|
||||
|
||||
|
||||
class Explorer(object):
|
||||
"""Internal class which invokes other explorers."""
|
||||
|
||||
# This map is filled by the Explorer.init_env() function
|
||||
type_code_to_explorer_map = { }
|
||||
type_code_to_explorer_map = {}
|
||||
|
||||
_SCALAR_TYPE_LIST = (
|
||||
gdb.TYPE_CODE_CHAR,
|
||||
@@ -43,14 +44,18 @@ class Explorer(object):
|
||||
length = len(expr)
|
||||
guard = False
|
||||
|
||||
if expr[0] == '(' and expr[length-1] == ')':
|
||||
if expr[0] == "(" and expr[length - 1] == ")":
|
||||
pass
|
||||
else:
|
||||
i = 0
|
||||
while i < length:
|
||||
c = expr[i]
|
||||
if (c == '_' or ('a' <= c and c <= 'z') or
|
||||
('A' <= c and c <= 'Z') or ('0' <= c and c <= '9')):
|
||||
if (
|
||||
c == "_"
|
||||
or ("a" <= c and c <= "z")
|
||||
or ("A" <= c and c <= "Z")
|
||||
or ("0" <= c and c <= "9")
|
||||
):
|
||||
pass
|
||||
else:
|
||||
guard = True
|
||||
@@ -85,8 +90,7 @@ class Explorer(object):
|
||||
while explorer_class.explore_expr(expr, value, is_child):
|
||||
pass
|
||||
else:
|
||||
print ("Explorer for type '%s' not yet available.\n" %
|
||||
str(value.type))
|
||||
print("Explorer for type '%s' not yet available.\n" % str(value.type))
|
||||
|
||||
@staticmethod
|
||||
def explore_type(name, datatype, is_child):
|
||||
@@ -111,8 +115,7 @@ class Explorer(object):
|
||||
while explorer_class.explore_type(name, datatype, is_child):
|
||||
pass
|
||||
else:
|
||||
print ("Explorer for type '%s' not yet available.\n" %
|
||||
str(datatype))
|
||||
print("Explorer for type '%s' not yet available.\n" % str(datatype))
|
||||
|
||||
@staticmethod
|
||||
def init_env():
|
||||
@@ -122,19 +125,19 @@ class Explorer(object):
|
||||
explorations.
|
||||
"""
|
||||
Explorer.type_code_to_explorer_map = {
|
||||
gdb.TYPE_CODE_CHAR : ScalarExplorer,
|
||||
gdb.TYPE_CODE_INT : ScalarExplorer,
|
||||
gdb.TYPE_CODE_BOOL : ScalarExplorer,
|
||||
gdb.TYPE_CODE_FLT : ScalarExplorer,
|
||||
gdb.TYPE_CODE_VOID : ScalarExplorer,
|
||||
gdb.TYPE_CODE_ENUM : ScalarExplorer,
|
||||
gdb.TYPE_CODE_STRUCT : CompoundExplorer,
|
||||
gdb.TYPE_CODE_UNION : CompoundExplorer,
|
||||
gdb.TYPE_CODE_PTR : PointerExplorer,
|
||||
gdb.TYPE_CODE_REF : ReferenceExplorer,
|
||||
gdb.TYPE_CODE_RVALUE_REF : ReferenceExplorer,
|
||||
gdb.TYPE_CODE_TYPEDEF : TypedefExplorer,
|
||||
gdb.TYPE_CODE_ARRAY : ArrayExplorer
|
||||
gdb.TYPE_CODE_CHAR: ScalarExplorer,
|
||||
gdb.TYPE_CODE_INT: ScalarExplorer,
|
||||
gdb.TYPE_CODE_BOOL: ScalarExplorer,
|
||||
gdb.TYPE_CODE_FLT: ScalarExplorer,
|
||||
gdb.TYPE_CODE_VOID: ScalarExplorer,
|
||||
gdb.TYPE_CODE_ENUM: ScalarExplorer,
|
||||
gdb.TYPE_CODE_STRUCT: CompoundExplorer,
|
||||
gdb.TYPE_CODE_UNION: CompoundExplorer,
|
||||
gdb.TYPE_CODE_PTR: PointerExplorer,
|
||||
gdb.TYPE_CODE_REF: ReferenceExplorer,
|
||||
gdb.TYPE_CODE_RVALUE_REF: ReferenceExplorer,
|
||||
gdb.TYPE_CODE_TYPEDEF: TypedefExplorer,
|
||||
gdb.TYPE_CODE_ARRAY: ArrayExplorer,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
@@ -161,8 +164,8 @@ class Explorer(object):
|
||||
"""A utility function which prints that the current exploration session
|
||||
is returning to the parent value. Useful when exploring values.
|
||||
"""
|
||||
print ("\nReturning to parent value...\n")
|
||||
|
||||
print("\nReturning to parent value...\n")
|
||||
|
||||
@staticmethod
|
||||
def return_to_parent_value_prompt():
|
||||
"""A utility function which prompts the user to press the 'enter' key
|
||||
@@ -170,14 +173,14 @@ class Explorer(object):
|
||||
Useful when exploring values.
|
||||
"""
|
||||
raw_input("\nPress enter to return to parent value: ")
|
||||
|
||||
|
||||
@staticmethod
|
||||
def return_to_enclosing_type():
|
||||
"""A utility function which prints that the current exploration session
|
||||
is returning to the enclosing type. Useful when exploring types.
|
||||
"""
|
||||
print ("\nReturning to enclosing type...\n")
|
||||
|
||||
print("\nReturning to enclosing type...\n")
|
||||
|
||||
@staticmethod
|
||||
def return_to_enclosing_type_prompt():
|
||||
"""A utility function which prompts the user to press the 'enter' key
|
||||
@@ -196,9 +199,8 @@ class ScalarExplorer(object):
|
||||
See Explorer.explore_expr and Explorer.is_scalar_type for more
|
||||
information.
|
||||
"""
|
||||
print ("'%s' is a scalar value of type '%s'." %
|
||||
(expr, value.type))
|
||||
print ("%s = %s" % (expr, str(value)))
|
||||
print("'%s' is a scalar value of type '%s'." % (expr, value.type))
|
||||
print("%s = %s" % (expr, str(value)))
|
||||
|
||||
if is_child:
|
||||
Explorer.return_to_parent_value_prompt()
|
||||
@@ -214,16 +216,14 @@ class ScalarExplorer(object):
|
||||
"""
|
||||
if datatype.code == gdb.TYPE_CODE_ENUM:
|
||||
if is_child:
|
||||
print ("%s is of an enumerated type '%s'." %
|
||||
(name, str(datatype)))
|
||||
print("%s is of an enumerated type '%s'." % (name, str(datatype)))
|
||||
else:
|
||||
print ("'%s' is an enumerated type." % name)
|
||||
print("'%s' is an enumerated type." % name)
|
||||
else:
|
||||
if is_child:
|
||||
print ("%s is of a scalar type '%s'." %
|
||||
(name, str(datatype)))
|
||||
print("%s is of a scalar type '%s'." % (name, str(datatype)))
|
||||
else:
|
||||
print ("'%s' is a scalar type." % name)
|
||||
print("'%s' is a scalar type." % name)
|
||||
|
||||
if is_child:
|
||||
Explorer.return_to_enclosing_type_prompt()
|
||||
@@ -240,33 +240,41 @@ class PointerExplorer(object):
|
||||
"""Function to explore pointer values.
|
||||
See Explorer.explore_expr for more information.
|
||||
"""
|
||||
print ("'%s' is a pointer to a value of type '%s'" %
|
||||
(expr, str(value.type.target())))
|
||||
option = raw_input("Continue exploring it as a pointer to a single "
|
||||
"value [y/n]: ")
|
||||
print(
|
||||
"'%s' is a pointer to a value of type '%s'"
|
||||
% (expr, str(value.type.target()))
|
||||
)
|
||||
option = raw_input(
|
||||
"Continue exploring it as a pointer to a single " "value [y/n]: "
|
||||
)
|
||||
if option == "y":
|
||||
deref_value = None
|
||||
try:
|
||||
deref_value = value.dereference()
|
||||
str(deref_value)
|
||||
except gdb.MemoryError:
|
||||
print ("'%s' a pointer pointing to an invalid memory "
|
||||
"location." % expr)
|
||||
print(
|
||||
"'%s' a pointer pointing to an invalid memory " "location." % expr
|
||||
)
|
||||
if is_child:
|
||||
Explorer.return_to_parent_value_prompt()
|
||||
return False
|
||||
Explorer.explore_expr("*%s" % Explorer.guard_expr(expr),
|
||||
deref_value, is_child)
|
||||
Explorer.explore_expr(
|
||||
"*%s" % Explorer.guard_expr(expr), deref_value, is_child
|
||||
)
|
||||
return False
|
||||
|
||||
option = raw_input("Continue exploring it as a pointer to an "
|
||||
"array [y/n]: ")
|
||||
|
||||
option = raw_input("Continue exploring it as a pointer to an " "array [y/n]: ")
|
||||
if option == "y":
|
||||
while True:
|
||||
index = 0
|
||||
try:
|
||||
index = int(raw_input("Enter the index of the element you "
|
||||
"want to explore in '%s': " % expr))
|
||||
index = int(
|
||||
raw_input(
|
||||
"Enter the index of the element you "
|
||||
"want to explore in '%s': " % expr
|
||||
)
|
||||
)
|
||||
except ValueError:
|
||||
break
|
||||
element_expr = "%s[%d]" % (Explorer.guard_expr(expr), index)
|
||||
@@ -274,7 +282,7 @@ class PointerExplorer(object):
|
||||
try:
|
||||
str(element)
|
||||
except gdb.MemoryError:
|
||||
print ("Cannot read value at index %d." % index)
|
||||
print("Cannot read value at index %d." % index)
|
||||
continue
|
||||
Explorer.explore_expr(element_expr, element, True)
|
||||
return False
|
||||
@@ -289,12 +297,9 @@ class PointerExplorer(object):
|
||||
See Explorer.explore_type for more information.
|
||||
"""
|
||||
target_type = datatype.target()
|
||||
print ("\n%s is a pointer to a value of type '%s'." %
|
||||
(name, str(target_type)))
|
||||
print("\n%s is a pointer to a value of type '%s'." % (name, str(target_type)))
|
||||
|
||||
Explorer.explore_type("the pointee type of %s" % name,
|
||||
target_type,
|
||||
is_child)
|
||||
Explorer.explore_type("the pointee type of %s" % name, target_type, is_child)
|
||||
return False
|
||||
|
||||
|
||||
@@ -319,6 +324,7 @@ class ReferenceExplorer(object):
|
||||
Explorer.explore_type(name, target_type, is_child)
|
||||
return False
|
||||
|
||||
|
||||
class ArrayExplorer(object):
|
||||
"""Internal class used to explore arrays."""
|
||||
|
||||
@@ -328,11 +334,15 @@ class ArrayExplorer(object):
|
||||
See Explorer.explore_expr for more information.
|
||||
"""
|
||||
target_type = value.type.target()
|
||||
print ("'%s' is an array of '%s'." % (expr, str(target_type)))
|
||||
print("'%s' is an array of '%s'." % (expr, str(target_type)))
|
||||
index = 0
|
||||
try:
|
||||
index = int(raw_input("Enter the index of the element you want to "
|
||||
"explore in '%s': " % expr))
|
||||
index = int(
|
||||
raw_input(
|
||||
"Enter the index of the element you want to "
|
||||
"explore in '%s': " % expr
|
||||
)
|
||||
)
|
||||
except ValueError:
|
||||
if is_child:
|
||||
Explorer.return_to_parent_value()
|
||||
@@ -343,12 +353,13 @@ class ArrayExplorer(object):
|
||||
element = value[index]
|
||||
str(element)
|
||||
except gdb.MemoryError:
|
||||
print ("Cannot read value at index %d." % index)
|
||||
print("Cannot read value at index %d." % index)
|
||||
raw_input("Press enter to continue... ")
|
||||
return True
|
||||
|
||||
Explorer.explore_expr("%s[%d]" % (Explorer.guard_expr(expr), index),
|
||||
element, True)
|
||||
|
||||
Explorer.explore_expr(
|
||||
"%s[%d]" % (Explorer.guard_expr(expr), index), element, True
|
||||
)
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
@@ -357,10 +368,9 @@ class ArrayExplorer(object):
|
||||
See Explorer.explore_type for more information.
|
||||
"""
|
||||
target_type = datatype.target()
|
||||
print ("%s is an array of '%s'." % (name, str(target_type)))
|
||||
print("%s is an array of '%s'." % (name, str(target_type)))
|
||||
|
||||
Explorer.explore_type("the array element of %s" % name, target_type,
|
||||
is_child)
|
||||
Explorer.explore_type("the array element of %s" % name, target_type, is_child)
|
||||
return False
|
||||
|
||||
|
||||
@@ -369,19 +379,18 @@ class CompoundExplorer(object):
|
||||
|
||||
@staticmethod
|
||||
def _print_fields(print_list):
|
||||
"""Internal function which prints the fields of a struct/class/union.
|
||||
"""
|
||||
"""Internal function which prints the fields of a struct/class/union."""
|
||||
max_field_name_length = 0
|
||||
for pair in print_list:
|
||||
if max_field_name_length < len(pair[0]):
|
||||
max_field_name_length = len(pair[0])
|
||||
|
||||
for pair in print_list:
|
||||
print (" %*s = %s" % (max_field_name_length, pair[0], pair[1]))
|
||||
print(" %*s = %s" % (max_field_name_length, pair[0], pair[1]))
|
||||
|
||||
@staticmethod
|
||||
def _get_real_field_count(fields):
|
||||
real_field_count = 0;
|
||||
real_field_count = 0
|
||||
for field in fields:
|
||||
if not field.artificial:
|
||||
real_field_count = real_field_count + 1
|
||||
@@ -403,19 +412,23 @@ class CompoundExplorer(object):
|
||||
type_desc = "union"
|
||||
|
||||
if CompoundExplorer._get_real_field_count(fields) == 0:
|
||||
print ("The value of '%s' is a %s of type '%s' with no fields." %
|
||||
(expr, type_desc, str(value.type)))
|
||||
print(
|
||||
"The value of '%s' is a %s of type '%s' with no fields."
|
||||
% (expr, type_desc, str(value.type))
|
||||
)
|
||||
if is_child:
|
||||
Explorer.return_to_parent_value_prompt()
|
||||
return False
|
||||
|
||||
print ("The value of '%s' is a %s of type '%s' with the following "
|
||||
"fields:\n" % (expr, type_desc, str(value.type)))
|
||||
print(
|
||||
"The value of '%s' is a %s of type '%s' with the following "
|
||||
"fields:\n" % (expr, type_desc, str(value.type))
|
||||
)
|
||||
|
||||
has_explorable_fields = False
|
||||
choice_to_compound_field_map = { }
|
||||
choice_to_compound_field_map = {}
|
||||
current_choice = 0
|
||||
print_list = [ ]
|
||||
print_list = []
|
||||
for field in fields:
|
||||
if field.artificial:
|
||||
continue
|
||||
@@ -426,39 +439,48 @@ class CompoundExplorer(object):
|
||||
field_value = value[field.name]
|
||||
literal_value = ""
|
||||
if type_code == gdb.TYPE_CODE_UNION:
|
||||
literal_value = ("<Enter %d to explore this field of type "
|
||||
"'%s'>" % (current_choice, str(field.type)))
|
||||
literal_value = "<Enter %d to explore this field of type " "'%s'>" % (
|
||||
current_choice,
|
||||
str(field.type),
|
||||
)
|
||||
has_explorable_fields = True
|
||||
else:
|
||||
if Explorer.is_scalar_type(field.type):
|
||||
literal_value = ("%s .. (Value of type '%s')" %
|
||||
(str(field_value), str(field.type)))
|
||||
literal_value = "%s .. (Value of type '%s')" % (
|
||||
str(field_value),
|
||||
str(field.type),
|
||||
)
|
||||
else:
|
||||
if field.is_base_class:
|
||||
field_desc = "base class"
|
||||
else:
|
||||
field_desc = "field"
|
||||
literal_value = ("<Enter %d to explore this %s of type "
|
||||
"'%s'>" %
|
||||
(current_choice, field_desc,
|
||||
str(field.type)))
|
||||
literal_value = "<Enter %d to explore this %s of type " "'%s'>" % (
|
||||
current_choice,
|
||||
field_desc,
|
||||
str(field.type),
|
||||
)
|
||||
has_explorable_fields = True
|
||||
|
||||
choice_to_compound_field_map[str(current_choice)] = (
|
||||
field_full_name, field_value)
|
||||
field_full_name,
|
||||
field_value,
|
||||
)
|
||||
current_choice = current_choice + 1
|
||||
|
||||
print_list.append((field.name, literal_value))
|
||||
|
||||
CompoundExplorer._print_fields(print_list)
|
||||
print ("")
|
||||
print("")
|
||||
|
||||
if has_explorable_fields:
|
||||
choice = raw_input("Enter the field number of choice: ")
|
||||
if choice in choice_to_compound_field_map:
|
||||
Explorer.explore_expr(choice_to_compound_field_map[choice][0],
|
||||
choice_to_compound_field_map[choice][1],
|
||||
True)
|
||||
Explorer.explore_expr(
|
||||
choice_to_compound_field_map[choice][0],
|
||||
choice_to_compound_field_map[choice][1],
|
||||
True,
|
||||
)
|
||||
return True
|
||||
else:
|
||||
if is_child:
|
||||
@@ -484,26 +506,27 @@ class CompoundExplorer(object):
|
||||
fields = datatype.fields()
|
||||
if CompoundExplorer._get_real_field_count(fields) == 0:
|
||||
if is_child:
|
||||
print ("%s is a %s of type '%s' with no fields." %
|
||||
(name, type_desc, str(datatype)))
|
||||
print(
|
||||
"%s is a %s of type '%s' with no fields."
|
||||
% (name, type_desc, str(datatype))
|
||||
)
|
||||
Explorer.return_to_enclosing_type_prompt()
|
||||
else:
|
||||
print ("'%s' is a %s with no fields." % (name, type_desc))
|
||||
print("'%s' is a %s with no fields." % (name, type_desc))
|
||||
return False
|
||||
|
||||
if is_child:
|
||||
print ("%s is a %s of type '%s' "
|
||||
"with the following fields:\n" %
|
||||
(name, type_desc, str(datatype)))
|
||||
print(
|
||||
"%s is a %s of type '%s' "
|
||||
"with the following fields:\n" % (name, type_desc, str(datatype))
|
||||
)
|
||||
else:
|
||||
print ("'%s' is a %s with the following "
|
||||
"fields:\n" %
|
||||
(name, type_desc))
|
||||
print("'%s' is a %s with the following " "fields:\n" % (name, type_desc))
|
||||
|
||||
has_explorable_fields = False
|
||||
current_choice = 0
|
||||
choice_to_compound_field_map = { }
|
||||
print_list = [ ]
|
||||
choice_to_compound_field_map = {}
|
||||
print_list = []
|
||||
for field in fields:
|
||||
if field.artificial:
|
||||
continue
|
||||
@@ -511,31 +534,40 @@ class CompoundExplorer(object):
|
||||
field_desc = "base class"
|
||||
else:
|
||||
field_desc = "field"
|
||||
rhs = ("<Enter %d to explore this %s of type '%s'>" %
|
||||
(current_choice, field_desc, str(field.type)))
|
||||
rhs = "<Enter %d to explore this %s of type '%s'>" % (
|
||||
current_choice,
|
||||
field_desc,
|
||||
str(field.type),
|
||||
)
|
||||
print_list.append((field.name, rhs))
|
||||
choice_to_compound_field_map[str(current_choice)] = (
|
||||
field.name, field.type, field_desc)
|
||||
field.name,
|
||||
field.type,
|
||||
field_desc,
|
||||
)
|
||||
current_choice = current_choice + 1
|
||||
|
||||
CompoundExplorer._print_fields(print_list)
|
||||
print ("")
|
||||
print("")
|
||||
|
||||
if len(choice_to_compound_field_map) > 0:
|
||||
choice = raw_input("Enter the field number of choice: ")
|
||||
if choice in choice_to_compound_field_map:
|
||||
if is_child:
|
||||
new_name = ("%s '%s' of %s" %
|
||||
(choice_to_compound_field_map[choice][2],
|
||||
choice_to_compound_field_map[choice][0],
|
||||
name))
|
||||
new_name = "%s '%s' of %s" % (
|
||||
choice_to_compound_field_map[choice][2],
|
||||
choice_to_compound_field_map[choice][0],
|
||||
name,
|
||||
)
|
||||
else:
|
||||
new_name = ("%s '%s' of '%s'" %
|
||||
(choice_to_compound_field_map[choice][2],
|
||||
choice_to_compound_field_map[choice][0],
|
||||
name))
|
||||
Explorer.explore_type(new_name,
|
||||
choice_to_compound_field_map[choice][1], True)
|
||||
new_name = "%s '%s' of '%s'" % (
|
||||
choice_to_compound_field_map[choice][2],
|
||||
choice_to_compound_field_map[choice][0],
|
||||
name,
|
||||
)
|
||||
Explorer.explore_type(
|
||||
new_name, choice_to_compound_field_map[choice][1], True
|
||||
)
|
||||
return True
|
||||
else:
|
||||
if is_child:
|
||||
@@ -545,7 +577,7 @@ class CompoundExplorer(object):
|
||||
Explorer.return_to_enclosing_type_prompt()
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
||||
class TypedefExplorer(object):
|
||||
"""Internal class used to explore values whose type is a typedef."""
|
||||
@@ -556,9 +588,11 @@ class TypedefExplorer(object):
|
||||
See Explorer.explore_expr for more information.
|
||||
"""
|
||||
actual_type = value.type.strip_typedefs()
|
||||
print ("The value of '%s' is of type '%s' "
|
||||
"which is a typedef of type '%s'" %
|
||||
(expr, str(value.type), str(actual_type)))
|
||||
print(
|
||||
"The value of '%s' is of type '%s' "
|
||||
"which is a typedef of type '%s'"
|
||||
% (expr, str(value.type), str(actual_type))
|
||||
)
|
||||
|
||||
Explorer.explore_expr(expr, value.cast(actual_type), is_child)
|
||||
return False
|
||||
@@ -570,11 +604,11 @@ class TypedefExplorer(object):
|
||||
"""
|
||||
actual_type = datatype.strip_typedefs()
|
||||
if is_child:
|
||||
print ("The type of %s is a typedef of type '%s'." %
|
||||
(name, str(actual_type)))
|
||||
print(
|
||||
"The type of %s is a typedef of type '%s'." % (name, str(actual_type))
|
||||
)
|
||||
else:
|
||||
print ("The type '%s' is a typedef of type '%s'." %
|
||||
(name, str(actual_type)))
|
||||
print("The type '%s' is a typedef of type '%s'." % (name, str(actual_type)))
|
||||
|
||||
Explorer.explore_type(name, actual_type, is_child)
|
||||
return False
|
||||
@@ -599,8 +633,7 @@ class ExploreUtils(object):
|
||||
gdb.GdbError if adequate arguments are not passed.
|
||||
"""
|
||||
if len(arg_str) < 1:
|
||||
raise gdb.GdbError("ERROR: '%s' requires an argument."
|
||||
% name)
|
||||
raise gdb.GdbError("ERROR: '%s' requires an argument." % name)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
@@ -649,16 +682,16 @@ class ExploreUtils(object):
|
||||
class ExploreCommand(gdb.Command):
|
||||
"""Explore a value or a type valid in the current context.
|
||||
|
||||
Usage: explore ARG
|
||||
Usage: explore ARG
|
||||
|
||||
- ARG is either a valid expression or a type name.
|
||||
- At any stage of exploration, hit the return key (instead of a
|
||||
choice, if any) to return to the enclosing type or value."""
|
||||
- ARG is either a valid expression or a type name.
|
||||
- At any stage of exploration, hit the return key (instead of a
|
||||
choice, if any) to return to the enclosing type or value."""
|
||||
|
||||
def __init__(self):
|
||||
super(ExploreCommand, self).__init__(name = "explore",
|
||||
command_class = gdb.COMMAND_DATA,
|
||||
prefix = True)
|
||||
super(ExploreCommand, self).__init__(
|
||||
name="explore", command_class=gdb.COMMAND_DATA, prefix=True
|
||||
)
|
||||
|
||||
def invoke(self, arg_str, from_tty):
|
||||
if ExploreUtils.check_args("explore", arg_str) == False:
|
||||
@@ -678,23 +711,26 @@ choice, if any) to return to the enclosing type or value."""
|
||||
|
||||
# If it is neither a value nor a type, raise an error.
|
||||
raise gdb.GdbError(
|
||||
("'%s' neither evaluates to a value nor is a type "
|
||||
"in the current context." %
|
||||
arg_str))
|
||||
(
|
||||
"'%s' neither evaluates to a value nor is a type "
|
||||
"in the current context." % arg_str
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class ExploreValueCommand(gdb.Command):
|
||||
"""Explore value of an expression valid in the current context.
|
||||
|
||||
Usage: explore value ARG
|
||||
Usage: explore value ARG
|
||||
|
||||
- ARG is a valid expression.
|
||||
- At any stage of exploration, hit the return key (instead of a
|
||||
choice, if any) to return to the enclosing value."""
|
||||
|
||||
- ARG is a valid expression.
|
||||
- At any stage of exploration, hit the return key (instead of a
|
||||
choice, if any) to return to the enclosing value."""
|
||||
|
||||
def __init__(self):
|
||||
super(ExploreValueCommand, self).__init__(
|
||||
name = "explore value", command_class = gdb.COMMAND_DATA)
|
||||
name="explore value", command_class=gdb.COMMAND_DATA
|
||||
)
|
||||
|
||||
def invoke(self, arg_str, from_tty):
|
||||
if ExploreUtils.check_args("explore value", arg_str) == False:
|
||||
@@ -703,26 +739,29 @@ choice, if any) to return to the enclosing value."""
|
||||
value = ExploreUtils.get_value_from_str(arg_str)
|
||||
if value is None:
|
||||
raise gdb.GdbError(
|
||||
(" '%s' does not evaluate to a value in the current "
|
||||
"context." %
|
||||
arg_str))
|
||||
(
|
||||
" '%s' does not evaluate to a value in the current "
|
||||
"context." % arg_str
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
Explorer.explore_expr(arg_str, value, False)
|
||||
|
||||
|
||||
class ExploreTypeCommand(gdb.Command):
|
||||
class ExploreTypeCommand(gdb.Command):
|
||||
"""Explore a type or the type of an expression.
|
||||
|
||||
Usage: explore type ARG
|
||||
Usage: explore type ARG
|
||||
|
||||
- ARG is a valid expression or a type name.
|
||||
- At any stage of exploration, hit the return key (instead of a
|
||||
choice, if any) to return to the enclosing type."""
|
||||
- ARG is a valid expression or a type name.
|
||||
- At any stage of exploration, hit the return key (instead of a
|
||||
choice, if any) to return to the enclosing type."""
|
||||
|
||||
def __init__(self):
|
||||
super(ExploreTypeCommand, self).__init__(
|
||||
name = "explore type", command_class = gdb.COMMAND_DATA)
|
||||
name="explore type", command_class=gdb.COMMAND_DATA
|
||||
)
|
||||
|
||||
def invoke(self, arg_str, from_tty):
|
||||
if ExploreUtils.check_args("explore type", arg_str) == False:
|
||||
@@ -735,12 +774,13 @@ choice, if any) to return to the enclosing type."""
|
||||
|
||||
value = ExploreUtils.get_value_from_str(arg_str)
|
||||
if value is not None:
|
||||
print ("'%s' is of type '%s'." % (arg_str, str(value.type)))
|
||||
print("'%s' is of type '%s'." % (arg_str, str(value.type)))
|
||||
Explorer.explore_type(str(value.type), value.type, False)
|
||||
return
|
||||
|
||||
raise gdb.GdbError(("'%s' is not a type or value in the current "
|
||||
"context." % arg_str))
|
||||
raise gdb.GdbError(
|
||||
("'%s' is not a type or value in the current " "context." % arg_str)
|
||||
)
|
||||
|
||||
|
||||
Explorer.init_env()
|
||||
|
||||
@@ -29,24 +29,28 @@ class SetFilterPrefixCmd(gdb.Command):
|
||||
"""Prefix command for 'set' frame-filter related operations."""
|
||||
|
||||
def __init__(self):
|
||||
super(SetFilterPrefixCmd, self).__init__("set frame-filter",
|
||||
gdb.COMMAND_OBSCURE,
|
||||
gdb.COMPLETE_NONE, True)
|
||||
super(SetFilterPrefixCmd, self).__init__(
|
||||
"set frame-filter", gdb.COMMAND_OBSCURE, gdb.COMPLETE_NONE, True
|
||||
)
|
||||
|
||||
|
||||
class ShowFilterPrefixCmd(gdb.Command):
|
||||
"""Prefix command for 'show' frame-filter related operations."""
|
||||
|
||||
def __init__(self):
|
||||
super(ShowFilterPrefixCmd, self).__init__("show frame-filter",
|
||||
gdb.COMMAND_OBSCURE,
|
||||
gdb.COMPLETE_NONE, True)
|
||||
super(ShowFilterPrefixCmd, self).__init__(
|
||||
"show frame-filter", gdb.COMMAND_OBSCURE, gdb.COMPLETE_NONE, True
|
||||
)
|
||||
|
||||
|
||||
class InfoFrameFilter(gdb.Command):
|
||||
"""List all registered Python frame-filters.
|
||||
|
||||
Usage: info frame-filters"""
|
||||
Usage: info frame-filters"""
|
||||
|
||||
def __init__(self):
|
||||
super(InfoFrameFilter, self).__init__("info frame-filter",
|
||||
gdb.COMMAND_DATA)
|
||||
super(InfoFrameFilter, self).__init__("info frame-filter", gdb.COMMAND_DATA)
|
||||
|
||||
@staticmethod
|
||||
def enabled_string(state):
|
||||
"""Return "Yes" if filter is enabled, otherwise "No"."""
|
||||
@@ -56,9 +60,11 @@ Usage: info frame-filters"""
|
||||
return "No"
|
||||
|
||||
def print_list(self, title, frame_filters, blank_line):
|
||||
sorted_frame_filters = sorted(frame_filters.items(),
|
||||
key=lambda i: gdb.frames.get_priority(i[1]),
|
||||
reverse=True)
|
||||
sorted_frame_filters = sorted(
|
||||
frame_filters.items(),
|
||||
key=lambda i: gdb.frames.get_priority(i[1]),
|
||||
reverse=True,
|
||||
)
|
||||
|
||||
if len(sorted_frame_filters) == 0:
|
||||
return 0
|
||||
@@ -68,14 +74,14 @@ Usage: info frame-filters"""
|
||||
for frame_filter in sorted_frame_filters:
|
||||
name = frame_filter[0]
|
||||
try:
|
||||
priority = '{:<8}'.format(
|
||||
str(gdb.frames.get_priority(frame_filter[1])))
|
||||
enabled = '{:<7}'.format(
|
||||
self.enabled_string(gdb.frames.get_enabled(frame_filter[1])))
|
||||
priority = "{:<8}".format(str(gdb.frames.get_priority(frame_filter[1])))
|
||||
enabled = "{:<7}".format(
|
||||
self.enabled_string(gdb.frames.get_enabled(frame_filter[1]))
|
||||
)
|
||||
print(" %s %s %s" % (priority, enabled, name))
|
||||
except Exception:
|
||||
e = sys.exc_info()[1]
|
||||
print(" Error printing filter '"+name+"': "+str(e))
|
||||
print(" Error printing filter '" + name + "': " + str(e))
|
||||
if blank_line:
|
||||
print("")
|
||||
return 1
|
||||
@@ -84,20 +90,26 @@ Usage: info frame-filters"""
|
||||
any_printed = self.print_list("global frame-filters:", gdb.frame_filters, True)
|
||||
|
||||
cp = gdb.current_progspace()
|
||||
any_printed += self.print_list("progspace %s frame-filters:" % cp.filename,
|
||||
cp.frame_filters, True)
|
||||
any_printed += self.print_list(
|
||||
"progspace %s frame-filters:" % cp.filename, cp.frame_filters, True
|
||||
)
|
||||
|
||||
for objfile in gdb.objfiles():
|
||||
any_printed += self.print_list("objfile %s frame-filters:" % objfile.filename,
|
||||
objfile.frame_filters, False)
|
||||
any_printed += self.print_list(
|
||||
"objfile %s frame-filters:" % objfile.filename,
|
||||
objfile.frame_filters,
|
||||
False,
|
||||
)
|
||||
|
||||
if any_printed == 0:
|
||||
print ("No frame filters.")
|
||||
print("No frame filters.")
|
||||
|
||||
|
||||
# Internal enable/disable functions.
|
||||
|
||||
|
||||
def _enable_parse_arg(cmd_name, arg):
|
||||
""" Internal worker function to take an argument from
|
||||
"""Internal worker function to take an argument from
|
||||
enable/disable and return a tuple of arguments.
|
||||
|
||||
Arguments:
|
||||
@@ -109,19 +121,21 @@ def _enable_parse_arg(cmd_name, arg):
|
||||
the dictionary in the case of "all".
|
||||
"""
|
||||
|
||||
argv = gdb.string_to_argv(arg);
|
||||
argv = gdb.string_to_argv(arg)
|
||||
argc = len(argv)
|
||||
if argc == 0:
|
||||
raise gdb.GdbError(cmd_name + " requires an argument")
|
||||
if argv[0] == "all":
|
||||
if argc > 1:
|
||||
raise gdb.GdbError(cmd_name + ": with 'all' " \
|
||||
"you may not specify a filter.")
|
||||
raise gdb.GdbError(
|
||||
cmd_name + ": with 'all' " "you may not specify a filter."
|
||||
)
|
||||
elif argc != 2:
|
||||
raise gdb.GdbError(cmd_name + " takes exactly two arguments.")
|
||||
raise gdb.GdbError(cmd_name + " takes exactly two arguments.")
|
||||
|
||||
return argv
|
||||
|
||||
|
||||
def _do_enable_frame_filter(command_tuple, flag):
|
||||
"""Worker for enabling/disabling frame_filters.
|
||||
|
||||
@@ -148,6 +162,7 @@ def _do_enable_frame_filter(command_tuple, flag):
|
||||
|
||||
gdb.frames.set_enabled(ff, flag)
|
||||
|
||||
|
||||
def _complete_frame_filter_list(text, word, all_flag):
|
||||
"""Worker for frame filter dictionary name completion.
|
||||
|
||||
@@ -160,7 +175,7 @@ def _complete_frame_filter_list(text, word, all_flag):
|
||||
A list of suggested frame filter dictionary name completions
|
||||
from text/word analysis. This list can be empty when there
|
||||
are no suggestions for completion.
|
||||
"""
|
||||
"""
|
||||
if all_flag == True:
|
||||
filter_locations = ["all", "global", "progspace"]
|
||||
else:
|
||||
@@ -171,20 +186,21 @@ def _complete_frame_filter_list(text, word, all_flag):
|
||||
# If the user just asked for completions with no completion
|
||||
# hints, just return all the frame filter dictionaries we know
|
||||
# about.
|
||||
if (text == ""):
|
||||
if text == "":
|
||||
return filter_locations
|
||||
|
||||
# Otherwise filter on what we know.
|
||||
flist = filter(lambda x,y=text:x.startswith(y), filter_locations)
|
||||
flist = filter(lambda x, y=text: x.startswith(y), filter_locations)
|
||||
|
||||
# If we only have one completion, complete it and return it.
|
||||
if len(flist) == 1:
|
||||
flist[0] = flist[0][len(text)-len(word):]
|
||||
flist[0] = flist[0][len(text) - len(word) :]
|
||||
|
||||
# Otherwise, return an empty list, or a list of frame filter
|
||||
# dictionaries that the previous filter operation returned.
|
||||
return flist
|
||||
|
||||
|
||||
def _complete_frame_filter_name(word, printer_dict):
|
||||
"""Worker for frame filter name completion.
|
||||
|
||||
@@ -201,29 +217,31 @@ def _complete_frame_filter_name(word, printer_dict):
|
||||
"""
|
||||
|
||||
printer_keys = printer_dict.keys()
|
||||
if (word == ""):
|
||||
if word == "":
|
||||
return printer_keys
|
||||
|
||||
flist = filter(lambda x,y=word:x.startswith(y), printer_keys)
|
||||
flist = filter(lambda x, y=word: x.startswith(y), printer_keys)
|
||||
return flist
|
||||
|
||||
|
||||
class EnableFrameFilter(gdb.Command):
|
||||
"""GDB command to enable the specified frame-filter.
|
||||
|
||||
Usage: enable frame-filter DICTIONARY [NAME]
|
||||
Usage: enable frame-filter DICTIONARY [NAME]
|
||||
|
||||
DICTIONARY is the name of the frame filter dictionary on which to
|
||||
operate. If dictionary is set to "all", perform operations on all
|
||||
dictionaries. Named dictionaries are: "global" for the global
|
||||
frame filter dictionary, "progspace" for the program space's frame
|
||||
filter dictionary. If either all, or the two named dictionaries
|
||||
are not specified, the dictionary name is assumed to be the name
|
||||
of an "objfile" -- a shared library or an executable.
|
||||
DICTIONARY is the name of the frame filter dictionary on which to
|
||||
operate. If dictionary is set to "all", perform operations on all
|
||||
dictionaries. Named dictionaries are: "global" for the global
|
||||
frame filter dictionary, "progspace" for the program space's frame
|
||||
filter dictionary. If either all, or the two named dictionaries
|
||||
are not specified, the dictionary name is assumed to be the name
|
||||
of an "objfile" -- a shared library or an executable.
|
||||
|
||||
NAME matches the name of the frame-filter to operate on."""
|
||||
|
||||
NAME matches the name of the frame-filter to operate on."""
|
||||
def __init__(self):
|
||||
super(EnableFrameFilter, self).__init__("enable frame-filter",
|
||||
gdb.COMMAND_DATA)
|
||||
super(EnableFrameFilter, self).__init__("enable frame-filter", gdb.COMMAND_DATA)
|
||||
|
||||
def complete(self, text, word):
|
||||
"""Completion function for both frame filter dictionary, and
|
||||
frame filter name."""
|
||||
@@ -241,20 +259,22 @@ NAME matches the name of the frame-filter to operate on."""
|
||||
class DisableFrameFilter(gdb.Command):
|
||||
"""GDB command to disable the specified frame-filter.
|
||||
|
||||
Usage: disable frame-filter DICTIONARY [NAME]
|
||||
Usage: disable frame-filter DICTIONARY [NAME]
|
||||
|
||||
DICTIONARY is the name of the frame filter dictionary on which to
|
||||
operate. If dictionary is set to "all", perform operations on all
|
||||
dictionaries. Named dictionaries are: "global" for the global
|
||||
frame filter dictionary, "progspace" for the program space's frame
|
||||
filter dictionary. If either all, or the two named dictionaries
|
||||
are not specified, the dictionary name is assumed to be the name
|
||||
of an "objfile" -- a shared library or an executable.
|
||||
DICTIONARY is the name of the frame filter dictionary on which to
|
||||
operate. If dictionary is set to "all", perform operations on all
|
||||
dictionaries. Named dictionaries are: "global" for the global
|
||||
frame filter dictionary, "progspace" for the program space's frame
|
||||
filter dictionary. If either all, or the two named dictionaries
|
||||
are not specified, the dictionary name is assumed to be the name
|
||||
of an "objfile" -- a shared library or an executable.
|
||||
|
||||
NAME matches the name of the frame-filter to operate on."""
|
||||
|
||||
NAME matches the name of the frame-filter to operate on."""
|
||||
def __init__(self):
|
||||
super(DisableFrameFilter, self).__init__("disable frame-filter",
|
||||
gdb.COMMAND_DATA)
|
||||
super(DisableFrameFilter, self).__init__(
|
||||
"disable frame-filter", gdb.COMMAND_DATA
|
||||
)
|
||||
|
||||
def complete(self, text, word):
|
||||
"""Completion function for both frame filter dictionary, and
|
||||
@@ -269,27 +289,28 @@ NAME matches the name of the frame-filter to operate on."""
|
||||
command_tuple = _enable_parse_arg("disable frame-filter", arg)
|
||||
_do_enable_frame_filter(command_tuple, False)
|
||||
|
||||
|
||||
class SetFrameFilterPriority(gdb.Command):
|
||||
"""GDB command to set the priority of the specified frame-filter.
|
||||
|
||||
Usage: set frame-filter priority DICTIONARY NAME PRIORITY
|
||||
Usage: set frame-filter priority DICTIONARY NAME PRIORITY
|
||||
|
||||
DICTIONARY is the name of the frame filter dictionary on which to
|
||||
operate. Named dictionaries are: "global" for the global frame
|
||||
filter dictionary, "progspace" for the program space's framefilter
|
||||
dictionary. If either of these two are not specified, the
|
||||
dictionary name is assumed to be the name of an "objfile" -- a
|
||||
shared library or an executable.
|
||||
DICTIONARY is the name of the frame filter dictionary on which to
|
||||
operate. Named dictionaries are: "global" for the global frame
|
||||
filter dictionary, "progspace" for the program space's framefilter
|
||||
dictionary. If either of these two are not specified, the
|
||||
dictionary name is assumed to be the name of an "objfile" -- a
|
||||
shared library or an executable.
|
||||
|
||||
NAME matches the name of the frame filter to operate on.
|
||||
NAME matches the name of the frame filter to operate on.
|
||||
|
||||
PRIORITY is the an integer to assign the new priority to the frame
|
||||
filter."""
|
||||
PRIORITY is the an integer to assign the new priority to the frame
|
||||
filter."""
|
||||
|
||||
def __init__(self):
|
||||
super(SetFrameFilterPriority, self).__init__("set frame-filter " \
|
||||
"priority",
|
||||
gdb.COMMAND_DATA)
|
||||
super(SetFrameFilterPriority, self).__init__(
|
||||
"set frame-filter " "priority", gdb.COMMAND_DATA
|
||||
)
|
||||
|
||||
def _parse_pri_arg(self, arg):
|
||||
"""Internal worker to parse a priority from a tuple.
|
||||
@@ -305,11 +326,10 @@ filter."""
|
||||
gdb.GdbError: An error parsing the arguments.
|
||||
"""
|
||||
|
||||
argv = gdb.string_to_argv(arg);
|
||||
argv = gdb.string_to_argv(arg)
|
||||
argc = len(argv)
|
||||
if argc != 3:
|
||||
print("set frame-filter priority " \
|
||||
"takes exactly three arguments.")
|
||||
print("set frame-filter priority " "takes exactly three arguments.")
|
||||
return None
|
||||
|
||||
return argv
|
||||
@@ -355,24 +375,25 @@ filter."""
|
||||
if command_tuple != None:
|
||||
self._set_filter_priority(command_tuple)
|
||||
|
||||
|
||||
class ShowFrameFilterPriority(gdb.Command):
|
||||
"""GDB command to show the priority of the specified frame-filter.
|
||||
|
||||
Usage: show frame-filter priority DICTIONARY NAME
|
||||
Usage: show frame-filter priority DICTIONARY NAME
|
||||
|
||||
DICTIONARY is the name of the frame filter dictionary on which to
|
||||
operate. Named dictionaries are: "global" for the global frame
|
||||
filter dictionary, "progspace" for the program space's framefilter
|
||||
dictionary. If either of these two are not specified, the
|
||||
dictionary name is assumed to be the name of an "objfile" -- a
|
||||
shared library or an executable.
|
||||
DICTIONARY is the name of the frame filter dictionary on which to
|
||||
operate. Named dictionaries are: "global" for the global frame
|
||||
filter dictionary, "progspace" for the program space's framefilter
|
||||
dictionary. If either of these two are not specified, the
|
||||
dictionary name is assumed to be the name of an "objfile" -- a
|
||||
shared library or an executable.
|
||||
|
||||
NAME matches the name of the frame-filter to operate on."""
|
||||
NAME matches the name of the frame-filter to operate on."""
|
||||
|
||||
def __init__(self):
|
||||
super(ShowFrameFilterPriority, self).__init__("show frame-filter " \
|
||||
"priority",
|
||||
gdb.COMMAND_DATA)
|
||||
super(ShowFrameFilterPriority, self).__init__(
|
||||
"show frame-filter " "priority", gdb.COMMAND_DATA
|
||||
)
|
||||
|
||||
def _parse_pri_arg(self, arg):
|
||||
"""Internal worker to parse a dictionary and name from a
|
||||
@@ -388,11 +409,10 @@ NAME matches the name of the frame-filter to operate on."""
|
||||
gdb.GdbError: An error parsing the arguments.
|
||||
"""
|
||||
|
||||
argv = gdb.string_to_argv(arg);
|
||||
argv = gdb.string_to_argv(arg)
|
||||
argc = len(argv)
|
||||
if argc != 2:
|
||||
print("show frame-filter priority " \
|
||||
"takes exactly two arguments.")
|
||||
print("show frame-filter priority " "takes exactly two arguments.")
|
||||
return None
|
||||
|
||||
return argv
|
||||
@@ -438,13 +458,20 @@ NAME matches the name of the frame-filter to operate on."""
|
||||
filter_name = command_tuple[1]
|
||||
list_name = command_tuple[0]
|
||||
try:
|
||||
priority = self.get_filter_priority(list_name, filter_name);
|
||||
priority = self.get_filter_priority(list_name, filter_name)
|
||||
except Exception:
|
||||
e = sys.exc_info()[1]
|
||||
print("Error printing filter priority for '"+name+"':"+str(e))
|
||||
print("Error printing filter priority for '" + name + "':" + str(e))
|
||||
else:
|
||||
print("Priority of filter '" + filter_name + "' in list '" \
|
||||
+ list_name + "' is: " + str(priority))
|
||||
print(
|
||||
"Priority of filter '"
|
||||
+ filter_name
|
||||
+ "' in list '"
|
||||
+ list_name
|
||||
+ "' is: "
|
||||
+ str(priority)
|
||||
)
|
||||
|
||||
|
||||
# Register commands
|
||||
SetFilterPrefixCmd()
|
||||
|
||||
@@ -38,7 +38,7 @@ def parse_printer_regexps(arg):
|
||||
SyntaxError: an error processing ARG
|
||||
"""
|
||||
|
||||
argv = gdb.string_to_argv(arg);
|
||||
argv = gdb.string_to_argv(arg)
|
||||
argc = len(argv)
|
||||
object_regexp = "" # match everything
|
||||
name_regexp = "" # match everything
|
||||
@@ -60,7 +60,7 @@ def parse_printer_regexps(arg):
|
||||
except SyntaxError:
|
||||
raise SyntaxError("invalid object regexp: %s" % object_regexp)
|
||||
try:
|
||||
name_re = re.compile (name_regexp)
|
||||
name_re = re.compile(name_regexp)
|
||||
except SyntaxError:
|
||||
raise SyntaxError("invalid name regexp: %s" % name_regexp)
|
||||
if subname_regexp is not None:
|
||||
@@ -70,7 +70,7 @@ def parse_printer_regexps(arg):
|
||||
raise SyntaxError("invalid subname regexp: %s" % subname_regexp)
|
||||
else:
|
||||
subname_re = None
|
||||
return(object_re, name_re, subname_re)
|
||||
return (object_re, name_re, subname_re)
|
||||
|
||||
|
||||
def printer_enabled_p(printer):
|
||||
@@ -84,19 +84,18 @@ def printer_enabled_p(printer):
|
||||
class InfoPrettyPrinter(gdb.Command):
|
||||
"""GDB command to list all registered pretty-printers.
|
||||
|
||||
Usage: info pretty-printer [OBJECT-REGEXP [NAME-REGEXP]]
|
||||
Usage: info pretty-printer [OBJECT-REGEXP [NAME-REGEXP]]
|
||||
|
||||
OBJECT-REGEXP is a regular expression matching the objects to list.
|
||||
Objects are "global", the program space's file, and the objfiles within
|
||||
that program space.
|
||||
OBJECT-REGEXP is a regular expression matching the objects to list.
|
||||
Objects are "global", the program space's file, and the objfiles within
|
||||
that program space.
|
||||
|
||||
NAME-REGEXP matches the name of the pretty-printer.
|
||||
Individual printers in a collection are named as
|
||||
printer-name;subprinter-name."""
|
||||
NAME-REGEXP matches the name of the pretty-printer.
|
||||
Individual printers in a collection are named as
|
||||
printer-name;subprinter-name."""
|
||||
|
||||
def __init__ (self):
|
||||
super(InfoPrettyPrinter, self).__init__("info pretty-printer",
|
||||
gdb.COMMAND_DATA)
|
||||
def __init__(self):
|
||||
super(InfoPrettyPrinter, self).__init__("info pretty-printer", gdb.COMMAND_DATA)
|
||||
|
||||
@staticmethod
|
||||
def enabled_string(printer):
|
||||
@@ -123,44 +122,62 @@ printer-name;subprinter-name."""
|
||||
"""Print a list of pretty-printers."""
|
||||
# A potential enhancement is to provide an option to list printers in
|
||||
# "lookup order" (i.e. unsorted).
|
||||
sorted_pretty_printers = sorted (copy.copy(pretty_printers),
|
||||
key = self.printer_name)
|
||||
sorted_pretty_printers = sorted(
|
||||
copy.copy(pretty_printers), key=self.printer_name
|
||||
)
|
||||
for printer in sorted_pretty_printers:
|
||||
name = self.printer_name(printer)
|
||||
enabled = self.enabled_string(printer)
|
||||
if name_re.match(name):
|
||||
print (" %s%s" % (name, enabled))
|
||||
if (hasattr(printer, "subprinters") and
|
||||
printer.subprinters is not None):
|
||||
sorted_subprinters = sorted (copy.copy(printer.subprinters),
|
||||
key = self.printer_name)
|
||||
print(" %s%s" % (name, enabled))
|
||||
if hasattr(printer, "subprinters") and printer.subprinters is not None:
|
||||
sorted_subprinters = sorted(
|
||||
copy.copy(printer.subprinters), key=self.printer_name
|
||||
)
|
||||
for subprinter in sorted_subprinters:
|
||||
if (not subname_re or
|
||||
subname_re.match(subprinter.name)):
|
||||
print (" %s%s" %
|
||||
(subprinter.name,
|
||||
self.enabled_string(subprinter)))
|
||||
if not subname_re or subname_re.match(subprinter.name):
|
||||
print(
|
||||
" %s%s"
|
||||
% (subprinter.name, self.enabled_string(subprinter))
|
||||
)
|
||||
|
||||
def invoke1(self, title, printer_list,
|
||||
obj_name_to_match, object_re, name_re, subname_re):
|
||||
def invoke1(
|
||||
self, title, printer_list, obj_name_to_match, object_re, name_re, subname_re
|
||||
):
|
||||
"""Subroutine of invoke to simplify it."""
|
||||
if printer_list and object_re.match(obj_name_to_match):
|
||||
print (title)
|
||||
print(title)
|
||||
self.list_pretty_printers(printer_list, name_re, subname_re)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
"""GDB calls this to perform the command."""
|
||||
(object_re, name_re, subname_re) = parse_printer_regexps(arg)
|
||||
self.invoke1("global pretty-printers:", gdb.pretty_printers,
|
||||
"global", object_re, name_re, subname_re)
|
||||
self.invoke1(
|
||||
"global pretty-printers:",
|
||||
gdb.pretty_printers,
|
||||
"global",
|
||||
object_re,
|
||||
name_re,
|
||||
subname_re,
|
||||
)
|
||||
cp = gdb.current_progspace()
|
||||
self.invoke1("progspace %s pretty-printers:" % cp.filename,
|
||||
cp.pretty_printers, "progspace",
|
||||
object_re, name_re, subname_re)
|
||||
self.invoke1(
|
||||
"progspace %s pretty-printers:" % cp.filename,
|
||||
cp.pretty_printers,
|
||||
"progspace",
|
||||
object_re,
|
||||
name_re,
|
||||
subname_re,
|
||||
)
|
||||
for objfile in gdb.objfiles():
|
||||
self.invoke1("objfile %s pretty-printers:" % objfile.filename,
|
||||
objfile.pretty_printers, objfile.filename,
|
||||
object_re, name_re, subname_re)
|
||||
self.invoke1(
|
||||
"objfile %s pretty-printers:" % objfile.filename,
|
||||
objfile.pretty_printers,
|
||||
objfile.filename,
|
||||
object_re,
|
||||
name_re,
|
||||
subname_re,
|
||||
)
|
||||
|
||||
|
||||
def count_enabled_printers(pretty_printers):
|
||||
@@ -168,8 +185,7 @@ def count_enabled_printers(pretty_printers):
|
||||
enabled = 0
|
||||
total = 0
|
||||
for printer in pretty_printers:
|
||||
if (hasattr(printer, "subprinters")
|
||||
and printer.subprinters is not None):
|
||||
if hasattr(printer, "subprinters") and printer.subprinters is not None:
|
||||
if printer_enabled_p(printer):
|
||||
for subprinter in printer.subprinters:
|
||||
if printer_enabled_p(subprinter):
|
||||
@@ -191,7 +207,9 @@ def count_all_enabled_printers():
|
||||
(t_enabled, t_total) = count_enabled_printers(gdb.pretty_printers)
|
||||
enabled_count += t_enabled
|
||||
total_count += t_total
|
||||
(t_enabled, t_total) = count_enabled_printers(gdb.current_progspace().pretty_printers)
|
||||
(t_enabled, t_total) = count_enabled_printers(
|
||||
gdb.current_progspace().pretty_printers
|
||||
)
|
||||
enabled_count += t_enabled
|
||||
total_count += t_total
|
||||
for objfile in gdb.objfiles():
|
||||
@@ -214,10 +232,10 @@ def show_pretty_printer_enabled_summary():
|
||||
We count subprinters individually.
|
||||
"""
|
||||
(enabled_count, total_count) = count_all_enabled_printers()
|
||||
print ("%d of %d printers enabled" % (enabled_count, total_count))
|
||||
print("%d of %d printers enabled" % (enabled_count, total_count))
|
||||
|
||||
|
||||
def do_enable_pretty_printer_1 (pretty_printers, name_re, subname_re, flag):
|
||||
def do_enable_pretty_printer_1(pretty_printers, name_re, subname_re, flag):
|
||||
"""Worker for enabling/disabling pretty-printers.
|
||||
|
||||
Arguments:
|
||||
@@ -233,10 +251,13 @@ def do_enable_pretty_printer_1 (pretty_printers, name_re, subname_re, flag):
|
||||
"""
|
||||
total = 0
|
||||
for printer in pretty_printers:
|
||||
if (hasattr(printer, "name") and name_re.match(printer.name) or
|
||||
hasattr(printer, "__name__") and name_re.match(printer.__name__)):
|
||||
if (hasattr(printer, "subprinters") and
|
||||
printer.subprinters is not None):
|
||||
if (
|
||||
hasattr(printer, "name")
|
||||
and name_re.match(printer.name)
|
||||
or hasattr(printer, "__name__")
|
||||
and name_re.match(printer.__name__)
|
||||
):
|
||||
if hasattr(printer, "subprinters") and printer.subprinters is not None:
|
||||
if not subname_re:
|
||||
# Only record printers that change state.
|
||||
if printer_enabled_p(printer) != flag:
|
||||
@@ -252,10 +273,12 @@ def do_enable_pretty_printer_1 (pretty_printers, name_re, subname_re, flag):
|
||||
for subprinter in printer.subprinters:
|
||||
if subname_re.match(subprinter.name):
|
||||
# Only record printers that change state.
|
||||
if (printer_enabled_p(printer) and
|
||||
printer_enabled_p(subprinter) != flag):
|
||||
total += 1
|
||||
subprinter.enabled = flag
|
||||
if (
|
||||
printer_enabled_p(printer)
|
||||
and printer_enabled_p(subprinter) != flag
|
||||
):
|
||||
total += 1
|
||||
subprinter.enabled = flag
|
||||
else:
|
||||
# This printer has no subprinters.
|
||||
# If the user does "disable pretty-printer .* .* foo"
|
||||
@@ -275,28 +298,31 @@ def do_enable_pretty_printer_1 (pretty_printers, name_re, subname_re, flag):
|
||||
return total
|
||||
|
||||
|
||||
def do_enable_pretty_printer (arg, flag):
|
||||
def do_enable_pretty_printer(arg, flag):
|
||||
"""Internal worker for enabling/disabling pretty-printers."""
|
||||
(object_re, name_re, subname_re) = parse_printer_regexps(arg)
|
||||
|
||||
total = 0
|
||||
if object_re.match("global"):
|
||||
total += do_enable_pretty_printer_1(gdb.pretty_printers,
|
||||
name_re, subname_re, flag)
|
||||
total += do_enable_pretty_printer_1(
|
||||
gdb.pretty_printers, name_re, subname_re, flag
|
||||
)
|
||||
cp = gdb.current_progspace()
|
||||
if object_re.match("progspace"):
|
||||
total += do_enable_pretty_printer_1(cp.pretty_printers,
|
||||
name_re, subname_re, flag)
|
||||
total += do_enable_pretty_printer_1(
|
||||
cp.pretty_printers, name_re, subname_re, flag
|
||||
)
|
||||
for objfile in gdb.objfiles():
|
||||
if object_re.match(objfile.filename):
|
||||
total += do_enable_pretty_printer_1(objfile.pretty_printers,
|
||||
name_re, subname_re, flag)
|
||||
total += do_enable_pretty_printer_1(
|
||||
objfile.pretty_printers, name_re, subname_re, flag
|
||||
)
|
||||
|
||||
if flag:
|
||||
state = "enabled"
|
||||
else:
|
||||
state = "disabled"
|
||||
print ("%d %s %s" % (total, pluralize("printer", total), state))
|
||||
print("%d %s %s" % (total, pluralize("printer", total), state))
|
||||
|
||||
# Print the total list of printers currently enabled/disabled.
|
||||
# This is to further assist the user in determining whether the result
|
||||
@@ -312,44 +338,47 @@ def do_enable_pretty_printer (arg, flag):
|
||||
#
|
||||
# A useful addition would be -v (verbose) to show each printer affected.
|
||||
|
||||
class EnablePrettyPrinter (gdb.Command):
|
||||
|
||||
class EnablePrettyPrinter(gdb.Command):
|
||||
"""GDB command to enable the specified pretty-printer.
|
||||
|
||||
Usage: enable pretty-printer [OBJECT-REGEXP [NAME-REGEXP]]
|
||||
Usage: enable pretty-printer [OBJECT-REGEXP [NAME-REGEXP]]
|
||||
|
||||
OBJECT-REGEXP is a regular expression matching the objects to examine.
|
||||
Objects are "global", the program space's file, and the objfiles within
|
||||
that program space.
|
||||
OBJECT-REGEXP is a regular expression matching the objects to examine.
|
||||
Objects are "global", the program space's file, and the objfiles within
|
||||
that program space.
|
||||
|
||||
NAME-REGEXP matches the name of the pretty-printer.
|
||||
Individual printers in a collection are named as
|
||||
printer-name;subprinter-name."""
|
||||
NAME-REGEXP matches the name of the pretty-printer.
|
||||
Individual printers in a collection are named as
|
||||
printer-name;subprinter-name."""
|
||||
|
||||
def __init__(self):
|
||||
super(EnablePrettyPrinter, self).__init__("enable pretty-printer",
|
||||
gdb.COMMAND_DATA)
|
||||
super(EnablePrettyPrinter, self).__init__(
|
||||
"enable pretty-printer", gdb.COMMAND_DATA
|
||||
)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
"""GDB calls this to perform the command."""
|
||||
do_enable_pretty_printer(arg, True)
|
||||
|
||||
|
||||
class DisablePrettyPrinter (gdb.Command):
|
||||
class DisablePrettyPrinter(gdb.Command):
|
||||
"""GDB command to disable the specified pretty-printer.
|
||||
|
||||
Usage: disable pretty-printer [OBJECT-REGEXP [NAME-REGEXP]]
|
||||
Usage: disable pretty-printer [OBJECT-REGEXP [NAME-REGEXP]]
|
||||
|
||||
OBJECT-REGEXP is a regular expression matching the objects to examine.
|
||||
Objects are "global", the program space's file, and the objfiles within
|
||||
that program space.
|
||||
OBJECT-REGEXP is a regular expression matching the objects to examine.
|
||||
Objects are "global", the program space's file, and the objfiles within
|
||||
that program space.
|
||||
|
||||
NAME-REGEXP matches the name of the pretty-printer.
|
||||
Individual printers in a collection are named as
|
||||
printer-name;subprinter-name."""
|
||||
NAME-REGEXP matches the name of the pretty-printer.
|
||||
Individual printers in a collection are named as
|
||||
printer-name;subprinter-name."""
|
||||
|
||||
def __init__(self):
|
||||
super(DisablePrettyPrinter, self).__init__("disable pretty-printer",
|
||||
gdb.COMMAND_DATA)
|
||||
super(DisablePrettyPrinter, self).__init__(
|
||||
"disable pretty-printer", gdb.COMMAND_DATA
|
||||
)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
"""GDB calls this to perform the command."""
|
||||
@@ -362,4 +391,5 @@ def register_pretty_printer_commands():
|
||||
EnablePrettyPrinter()
|
||||
DisablePrettyPrinter()
|
||||
|
||||
|
||||
register_pretty_printer_commands()
|
||||
|
||||
@@ -19,17 +19,18 @@
|
||||
import gdb
|
||||
import gdb.prompt
|
||||
|
||||
|
||||
class _ExtendedPrompt(gdb.Parameter):
|
||||
|
||||
"""Set the extended prompt.
|
||||
|
||||
Usage: set extended-prompt VALUE
|
||||
Usage: set extended-prompt VALUE
|
||||
|
||||
Substitutions are applied to VALUE to compute the real prompt.
|
||||
Substitutions are applied to VALUE to compute the real prompt.
|
||||
|
||||
The currently defined substitutions are:
|
||||
The currently defined substitutions are:
|
||||
"""
|
||||
|
||||
"""
|
||||
# Add the prompt library's dynamically generated help to the
|
||||
# __doc__ string.
|
||||
__doc__ = __doc__ + gdb.prompt.prompt_help()
|
||||
@@ -38,22 +39,22 @@ The currently defined substitutions are:
|
||||
show_doc = "Show the extended prompt."
|
||||
|
||||
def __init__(self):
|
||||
super(_ExtendedPrompt, self).__init__("extended-prompt",
|
||||
gdb.COMMAND_SUPPORT,
|
||||
gdb.PARAM_STRING_NOESCAPE)
|
||||
self.value = ''
|
||||
super(_ExtendedPrompt, self).__init__(
|
||||
"extended-prompt", gdb.COMMAND_SUPPORT, gdb.PARAM_STRING_NOESCAPE
|
||||
)
|
||||
self.value = ""
|
||||
self.hook_set = False
|
||||
|
||||
def get_show_string (self, pvalue):
|
||||
def get_show_string(self, pvalue):
|
||||
if self.value:
|
||||
return "The extended prompt is: " + self.value
|
||||
return "The extended prompt is: " + self.value
|
||||
else:
|
||||
return "The extended prompt is not set."
|
||||
return "The extended prompt is not set."
|
||||
|
||||
def get_set_string (self):
|
||||
def get_set_string(self):
|
||||
if self.hook_set == False:
|
||||
gdb.prompt_hook = self.before_prompt_hook
|
||||
self.hook_set = True
|
||||
gdb.prompt_hook = self.before_prompt_hook
|
||||
self.hook_set = True
|
||||
return ""
|
||||
|
||||
def before_prompt_hook(self, current):
|
||||
@@ -62,4 +63,5 @@ The currently defined substitutions are:
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
_ExtendedPrompt()
|
||||
|
||||
@@ -19,44 +19,44 @@ import gdb
|
||||
|
||||
"""GDB commands for working with type-printers."""
|
||||
|
||||
|
||||
class InfoTypePrinter(gdb.Command):
|
||||
"""GDB command to list all registered type-printers.
|
||||
|
||||
Usage: info type-printers"""
|
||||
Usage: info type-printers"""
|
||||
|
||||
def __init__ (self):
|
||||
super(InfoTypePrinter, self).__init__("info type-printers",
|
||||
gdb.COMMAND_DATA)
|
||||
def __init__(self):
|
||||
super(InfoTypePrinter, self).__init__("info type-printers", gdb.COMMAND_DATA)
|
||||
|
||||
def list_type_printers(self, type_printers):
|
||||
"""Print a list of type printers."""
|
||||
# A potential enhancement is to provide an option to list printers in
|
||||
# "lookup order" (i.e. unsorted).
|
||||
sorted_type_printers = sorted (copy.copy(type_printers),
|
||||
key = lambda x: x.name)
|
||||
sorted_type_printers = sorted(copy.copy(type_printers), key=lambda x: x.name)
|
||||
for printer in sorted_type_printers:
|
||||
if printer.enabled:
|
||||
enabled = ''
|
||||
enabled = ""
|
||||
else:
|
||||
enabled = " [disabled]"
|
||||
print (" %s%s" % (printer.name, enabled))
|
||||
print(" %s%s" % (printer.name, enabled))
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
"""GDB calls this to perform the command."""
|
||||
sep = ''
|
||||
sep = ""
|
||||
for objfile in gdb.objfiles():
|
||||
if objfile.type_printers:
|
||||
print ("%sType printers for %s:" % (sep, objfile.filename))
|
||||
print("%sType printers for %s:" % (sep, objfile.filename))
|
||||
self.list_type_printers(objfile.type_printers)
|
||||
sep = '\n'
|
||||
sep = "\n"
|
||||
if gdb.current_progspace().type_printers:
|
||||
print ("%sType printers for program space:" % sep)
|
||||
print("%sType printers for program space:" % sep)
|
||||
self.list_type_printers(gdb.current_progspace().type_printers)
|
||||
sep = '\n'
|
||||
sep = "\n"
|
||||
if gdb.type_printers:
|
||||
print ("%sGlobal type printers:" % sep)
|
||||
print("%sGlobal type printers:" % sep)
|
||||
self.list_type_printers(gdb.type_printers)
|
||||
|
||||
|
||||
class _EnableOrDisableCommand(gdb.Command):
|
||||
def __init__(self, setting, name):
|
||||
super(_EnableOrDisableCommand, self).__init__(name, gdb.COMMAND_DATA)
|
||||
@@ -82,7 +82,7 @@ class _EnableOrDisableCommand(gdb.Command):
|
||||
if self.set_some(name, gdb.type_printers):
|
||||
ok = True
|
||||
if not ok:
|
||||
print ("No type printer named '%s'" % name)
|
||||
print("No type printer named '%s'" % name)
|
||||
|
||||
def add_some(self, result, word, printers):
|
||||
for p in printers:
|
||||
@@ -97,26 +97,29 @@ class _EnableOrDisableCommand(gdb.Command):
|
||||
self.add_some(result, word, gdb.type_printers)
|
||||
return result
|
||||
|
||||
|
||||
class EnableTypePrinter(_EnableOrDisableCommand):
|
||||
"""GDB command to enable the specified type printer.
|
||||
|
||||
Usage: enable type-printer NAME
|
||||
Usage: enable type-printer NAME
|
||||
|
||||
NAME is the name of the type-printer."""
|
||||
NAME is the name of the type-printer."""
|
||||
|
||||
def __init__(self):
|
||||
super(EnableTypePrinter, self).__init__(True, "enable type-printer")
|
||||
|
||||
|
||||
class DisableTypePrinter(_EnableOrDisableCommand):
|
||||
"""GDB command to disable the specified type-printer.
|
||||
|
||||
Usage: disable type-printer NAME
|
||||
Usage: disable type-printer NAME
|
||||
|
||||
NAME is the name of the type-printer."""
|
||||
NAME is the name of the type-printer."""
|
||||
|
||||
def __init__(self):
|
||||
super(DisableTypePrinter, self).__init__(False, "disable type-printer")
|
||||
|
||||
|
||||
InfoTypePrinter()
|
||||
EnableTypePrinter()
|
||||
DisableTypePrinter()
|
||||
|
||||
@@ -49,28 +49,29 @@ def parse_unwinder_command_args(arg):
|
||||
locus_regexp = argv[0]
|
||||
if argc >= 2:
|
||||
name_regexp = argv[1]
|
||||
return (validate_regexp(locus_regexp, "locus"),
|
||||
validate_regexp(name_regexp, "unwinder"))
|
||||
return (
|
||||
validate_regexp(locus_regexp, "locus"),
|
||||
validate_regexp(name_regexp, "unwinder"),
|
||||
)
|
||||
|
||||
|
||||
class InfoUnwinder(gdb.Command):
|
||||
"""GDB command to list unwinders.
|
||||
|
||||
Usage: info unwinder [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
Usage: info unwinder [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
|
||||
LOCUS-REGEXP is a regular expression matching the location of the
|
||||
unwinder. If it is omitted, all registered unwinders from all
|
||||
loci are listed. A locus can be 'global', 'progspace' to list
|
||||
the unwinders from the current progspace, or a regular expression
|
||||
matching filenames of objfiles.
|
||||
LOCUS-REGEXP is a regular expression matching the location of the
|
||||
unwinder. If it is omitted, all registered unwinders from all
|
||||
loci are listed. A locus can be 'global', 'progspace' to list
|
||||
the unwinders from the current progspace, or a regular expression
|
||||
matching filenames of objfiles.
|
||||
|
||||
NAME-REGEXP is a regular expression to filter unwinder names. If
|
||||
this omitted for a specified locus, then all registered unwinders
|
||||
in the locus are listed."""
|
||||
NAME-REGEXP is a regular expression to filter unwinder names. If
|
||||
this omitted for a specified locus, then all registered unwinders
|
||||
in the locus are listed."""
|
||||
|
||||
def __init__(self):
|
||||
super(InfoUnwinder, self).__init__("info unwinder",
|
||||
gdb.COMMAND_STACK)
|
||||
super(InfoUnwinder, self).__init__("info unwinder", gdb.COMMAND_STACK)
|
||||
|
||||
def list_unwinders(self, title, unwinders, name_re):
|
||||
"""Lists the unwinders whose name matches regexp.
|
||||
@@ -85,22 +86,25 @@ in the locus are listed."""
|
||||
print(title)
|
||||
for unwinder in unwinders:
|
||||
if name_re.match(unwinder.name):
|
||||
print(" %s%s" % (unwinder.name,
|
||||
"" if unwinder.enabled else " [disabled]"))
|
||||
print(
|
||||
" %s%s"
|
||||
% (unwinder.name, "" if unwinder.enabled else " [disabled]")
|
||||
)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
locus_re, name_re = parse_unwinder_command_args(arg)
|
||||
if locus_re.match("global"):
|
||||
self.list_unwinders("Global:", gdb.frame_unwinders,
|
||||
name_re)
|
||||
self.list_unwinders("Global:", gdb.frame_unwinders, name_re)
|
||||
if locus_re.match("progspace"):
|
||||
cp = gdb.current_progspace()
|
||||
self.list_unwinders("Progspace %s:" % cp.filename,
|
||||
cp.frame_unwinders, name_re)
|
||||
self.list_unwinders(
|
||||
"Progspace %s:" % cp.filename, cp.frame_unwinders, name_re
|
||||
)
|
||||
for objfile in gdb.objfiles():
|
||||
if locus_re.match(objfile.filename):
|
||||
self.list_unwinders("Objfile %s:" % objfile.filename,
|
||||
objfile.frame_unwinders, name_re)
|
||||
self.list_unwinders(
|
||||
"Objfile %s:" % objfile.filename, objfile.frame_unwinders, name_re
|
||||
)
|
||||
|
||||
|
||||
def do_enable_unwinder1(unwinders, name_re, flag):
|
||||
@@ -129,34 +133,35 @@ def do_enable_unwinder(arg, flag):
|
||||
if locus_re.match("global"):
|
||||
total += do_enable_unwinder1(gdb.frame_unwinders, name_re, flag)
|
||||
if locus_re.match("progspace"):
|
||||
total += do_enable_unwinder1(gdb.current_progspace().frame_unwinders,
|
||||
name_re, flag)
|
||||
total += do_enable_unwinder1(
|
||||
gdb.current_progspace().frame_unwinders, name_re, flag
|
||||
)
|
||||
for objfile in gdb.objfiles():
|
||||
if locus_re.match(objfile.filename):
|
||||
total += do_enable_unwinder1(objfile.frame_unwinders, name_re,
|
||||
flag)
|
||||
total += do_enable_unwinder1(objfile.frame_unwinders, name_re, flag)
|
||||
if total > 0:
|
||||
gdb.invalidate_cached_frames()
|
||||
print("%d unwinder%s %s" % (total, "" if total == 1 else "s",
|
||||
"enabled" if flag else "disabled"))
|
||||
print(
|
||||
"%d unwinder%s %s"
|
||||
% (total, "" if total == 1 else "s", "enabled" if flag else "disabled")
|
||||
)
|
||||
|
||||
|
||||
class EnableUnwinder(gdb.Command):
|
||||
"""GDB command to enable unwinders.
|
||||
|
||||
Usage: enable unwinder [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
Usage: enable unwinder [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
|
||||
LOCUS-REGEXP is a regular expression specifying the unwinders to
|
||||
enable. It can 'global', 'progspace', or the name of an objfile
|
||||
within that progspace.
|
||||
LOCUS-REGEXP is a regular expression specifying the unwinders to
|
||||
enable. It can 'global', 'progspace', or the name of an objfile
|
||||
within that progspace.
|
||||
|
||||
NAME_REGEXP is a regular expression to filter unwinder names. If
|
||||
this omitted for a specified locus, then all registered unwinders
|
||||
in the locus are affected."""
|
||||
NAME_REGEXP is a regular expression to filter unwinder names. If
|
||||
this omitted for a specified locus, then all registered unwinders
|
||||
in the locus are affected."""
|
||||
|
||||
def __init__(self):
|
||||
super(EnableUnwinder, self).__init__("enable unwinder",
|
||||
gdb.COMMAND_STACK)
|
||||
super(EnableUnwinder, self).__init__("enable unwinder", gdb.COMMAND_STACK)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
"""GDB calls this to perform the command."""
|
||||
@@ -166,19 +171,18 @@ in the locus are affected."""
|
||||
class DisableUnwinder(gdb.Command):
|
||||
"""GDB command to disable the specified unwinder.
|
||||
|
||||
Usage: disable unwinder [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
Usage: disable unwinder [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
|
||||
LOCUS-REGEXP is a regular expression specifying the unwinders to
|
||||
disable. It can 'global', 'progspace', or the name of an objfile
|
||||
within that progspace.
|
||||
LOCUS-REGEXP is a regular expression specifying the unwinders to
|
||||
disable. It can 'global', 'progspace', or the name of an objfile
|
||||
within that progspace.
|
||||
|
||||
NAME_REGEXP is a regular expression to filter unwinder names. If
|
||||
this omitted for a specified locus, then all registered unwinders
|
||||
in the locus are affected."""
|
||||
NAME_REGEXP is a regular expression to filter unwinder names. If
|
||||
this omitted for a specified locus, then all registered unwinders
|
||||
in the locus are affected."""
|
||||
|
||||
def __init__(self):
|
||||
super(DisableUnwinder, self).__init__("disable unwinder",
|
||||
gdb.COMMAND_STACK)
|
||||
super(DisableUnwinder, self).__init__("disable unwinder", gdb.COMMAND_STACK)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
"""GDB calls this to perform the command."""
|
||||
|
||||
@@ -56,9 +56,11 @@ def parse_xm_command_args(arg):
|
||||
name_re = validate_xm_regexp("xmethod name", xm_name_regexp)
|
||||
else:
|
||||
name_re = None
|
||||
return (validate_xm_regexp("locus", locus_regexp),
|
||||
validate_xm_regexp("matcher name", matcher_name_regexp),
|
||||
name_re)
|
||||
return (
|
||||
validate_xm_regexp("locus", locus_regexp),
|
||||
validate_xm_regexp("matcher name", matcher_name_regexp),
|
||||
name_re,
|
||||
)
|
||||
|
||||
|
||||
def get_global_method_matchers(locus_re, matcher_re):
|
||||
@@ -75,10 +77,9 @@ def get_global_method_matchers(locus_re, matcher_re):
|
||||
key in the dict will be 'global'.
|
||||
"""
|
||||
locus_str = "global"
|
||||
xm_dict = { locus_str: [] }
|
||||
xm_dict = {locus_str: []}
|
||||
if locus_re.match("global"):
|
||||
xm_dict[locus_str].extend(
|
||||
[m for m in gdb.xmethods if matcher_re.match(m.name)])
|
||||
xm_dict[locus_str].extend([m for m in gdb.xmethods if matcher_re.match(m.name)])
|
||||
return xm_dict
|
||||
|
||||
|
||||
@@ -102,7 +103,7 @@ def get_method_matchers_in_loci(loci, locus_re, matcher_re):
|
||||
xm_dict = {}
|
||||
for locus in loci:
|
||||
if isinstance(locus, gdb.Progspace):
|
||||
if not locus_re.match('progspace'):
|
||||
if not locus_re.match("progspace"):
|
||||
continue
|
||||
locus_type = "progspace"
|
||||
else:
|
||||
@@ -110,32 +111,32 @@ def get_method_matchers_in_loci(loci, locus_re, matcher_re):
|
||||
continue
|
||||
locus_type = "objfile"
|
||||
locus_str = "%s %s" % (locus_type, locus.filename)
|
||||
xm_dict[locus_str] = [
|
||||
m for m in locus.xmethods if matcher_re.match(m.name)]
|
||||
xm_dict[locus_str] = [m for m in locus.xmethods if matcher_re.match(m.name)]
|
||||
return xm_dict
|
||||
|
||||
|
||||
def print_xm_info(xm_dict, name_re):
|
||||
"""Print a dictionary of xmethods."""
|
||||
|
||||
def get_status_string(m):
|
||||
if not m.enabled:
|
||||
return " [disabled]"
|
||||
else:
|
||||
return ""
|
||||
return ""
|
||||
|
||||
if not xm_dict:
|
||||
return
|
||||
for locus_str in xm_dict:
|
||||
if not xm_dict[locus_str]:
|
||||
continue
|
||||
print ("Xmethods in %s:" % locus_str)
|
||||
print("Xmethods in %s:" % locus_str)
|
||||
for matcher in xm_dict[locus_str]:
|
||||
print (" %s%s" % (matcher.name, get_status_string(matcher)))
|
||||
print(" %s%s" % (matcher.name, get_status_string(matcher)))
|
||||
if not matcher.methods:
|
||||
continue
|
||||
for m in matcher.methods:
|
||||
if name_re is None or name_re.match(m.name):
|
||||
print (" %s%s" % (m.name, get_status_string(m)))
|
||||
print(" %s%s" % (m.name, get_status_string(m)))
|
||||
|
||||
|
||||
def set_xm_status1(xm_dict, name_re, status):
|
||||
@@ -161,75 +162,74 @@ def set_xm_status(arg, status):
|
||||
argument string passed to the commands.
|
||||
"""
|
||||
locus_re, matcher_re, name_re = parse_xm_command_args(arg)
|
||||
set_xm_status1(get_global_method_matchers(locus_re, matcher_re), name_re,
|
||||
status)
|
||||
set_xm_status1(get_global_method_matchers(locus_re, matcher_re), name_re, status)
|
||||
set_xm_status1(
|
||||
get_method_matchers_in_loci(
|
||||
[gdb.current_progspace()], locus_re, matcher_re),
|
||||
get_method_matchers_in_loci([gdb.current_progspace()], locus_re, matcher_re),
|
||||
name_re,
|
||||
status)
|
||||
status,
|
||||
)
|
||||
set_xm_status1(
|
||||
get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re),
|
||||
name_re,
|
||||
status)
|
||||
status,
|
||||
)
|
||||
|
||||
|
||||
class InfoXMethod(gdb.Command):
|
||||
"""GDB command to list registered xmethod matchers.
|
||||
|
||||
Usage: info xmethod [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
Usage: info xmethod [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
|
||||
LOCUS-REGEXP is a regular expression matching the location of the
|
||||
xmethod matchers. If it is omitted, all registered xmethod matchers
|
||||
from all loci are listed. A locus could be 'global', a regular expression
|
||||
matching the current program space's filename, or a regular expression
|
||||
matching filenames of objfiles. Locus could be 'progspace' to specify that
|
||||
only xmethods from the current progspace should be listed.
|
||||
LOCUS-REGEXP is a regular expression matching the location of the
|
||||
xmethod matchers. If it is omitted, all registered xmethod matchers
|
||||
from all loci are listed. A locus could be 'global', a regular expression
|
||||
matching the current program space's filename, or a regular expression
|
||||
matching filenames of objfiles. Locus could be 'progspace' to specify that
|
||||
only xmethods from the current progspace should be listed.
|
||||
|
||||
NAME-REGEXP is a regular expression matching the names of xmethod
|
||||
matchers. If this omitted for a specified locus, then all registered
|
||||
xmethods in the locus are listed. To list only a certain xmethods
|
||||
managed by a single matcher, the name regexp can be specified as
|
||||
matcher-name-regexp;xmethod-name-regexp."""
|
||||
NAME-REGEXP is a regular expression matching the names of xmethod
|
||||
matchers. If this omitted for a specified locus, then all registered
|
||||
xmethods in the locus are listed. To list only a certain xmethods
|
||||
managed by a single matcher, the name regexp can be specified as
|
||||
matcher-name-regexp;xmethod-name-regexp."""
|
||||
|
||||
def __init__(self):
|
||||
super(InfoXMethod, self).__init__("info xmethod",
|
||||
gdb.COMMAND_DATA)
|
||||
super(InfoXMethod, self).__init__("info xmethod", gdb.COMMAND_DATA)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
locus_re, matcher_re, name_re = parse_xm_command_args(arg)
|
||||
print_xm_info(get_global_method_matchers(locus_re, matcher_re),
|
||||
name_re)
|
||||
print_xm_info(get_global_method_matchers(locus_re, matcher_re), name_re)
|
||||
print_xm_info(
|
||||
get_method_matchers_in_loci(
|
||||
[gdb.current_progspace()], locus_re, matcher_re),
|
||||
name_re)
|
||||
[gdb.current_progspace()], locus_re, matcher_re
|
||||
),
|
||||
name_re,
|
||||
)
|
||||
print_xm_info(
|
||||
get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re),
|
||||
name_re)
|
||||
get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re), name_re
|
||||
)
|
||||
|
||||
|
||||
class EnableXMethod(gdb.Command):
|
||||
"""GDB command to enable a specified (group of) xmethod(s).
|
||||
|
||||
Usage: enable xmethod [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
Usage: enable xmethod [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
|
||||
LOCUS-REGEXP is a regular expression matching the location of the
|
||||
xmethod matchers. If it is omitted, all registered xmethods matchers
|
||||
from all loci are enabled. A locus could be 'global', a regular expression
|
||||
matching the current program space's filename, or a regular expression
|
||||
matching filenames of objfiles. Locus could be 'progspace' to specify that
|
||||
only xmethods from the current progspace should be enabled.
|
||||
LOCUS-REGEXP is a regular expression matching the location of the
|
||||
xmethod matchers. If it is omitted, all registered xmethods matchers
|
||||
from all loci are enabled. A locus could be 'global', a regular expression
|
||||
matching the current program space's filename, or a regular expression
|
||||
matching filenames of objfiles. Locus could be 'progspace' to specify that
|
||||
only xmethods from the current progspace should be enabled.
|
||||
|
||||
NAME-REGEXP is a regular expression matching the names of xmethods
|
||||
within a given locus. If this omitted for a specified locus, then all
|
||||
registered xmethod matchers in the locus are enabled. To enable only
|
||||
a certain xmethods managed by a single matcher, the name regexp can be
|
||||
specified as matcher-name-regexp;xmethod-name-regexp."""
|
||||
NAME-REGEXP is a regular expression matching the names of xmethods
|
||||
within a given locus. If this omitted for a specified locus, then all
|
||||
registered xmethod matchers in the locus are enabled. To enable only
|
||||
a certain xmethods managed by a single matcher, the name regexp can be
|
||||
specified as matcher-name-regexp;xmethod-name-regexp."""
|
||||
|
||||
def __init__(self):
|
||||
super(EnableXMethod, self).__init__("enable xmethod",
|
||||
gdb.COMMAND_DATA)
|
||||
super(EnableXMethod, self).__init__("enable xmethod", gdb.COMMAND_DATA)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
set_xm_status(arg, True)
|
||||
@@ -238,24 +238,23 @@ specified as matcher-name-regexp;xmethod-name-regexp."""
|
||||
class DisableXMethod(gdb.Command):
|
||||
"""GDB command to disable a specified (group of) xmethod(s).
|
||||
|
||||
Usage: disable xmethod [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
Usage: disable xmethod [LOCUS-REGEXP [NAME-REGEXP]]
|
||||
|
||||
LOCUS-REGEXP is a regular expression matching the location of the
|
||||
xmethod matchers. If it is omitted, all registered xmethod matchers
|
||||
from all loci are disabled. A locus could be 'global', a regular
|
||||
expression matching the current program space's filename, or a regular
|
||||
expression filenames of objfiles. Locus could be 'progspace' to specify
|
||||
that only xmethods from the current progspace should be disabled.
|
||||
LOCUS-REGEXP is a regular expression matching the location of the
|
||||
xmethod matchers. If it is omitted, all registered xmethod matchers
|
||||
from all loci are disabled. A locus could be 'global', a regular
|
||||
expression matching the current program space's filename, or a regular
|
||||
expression filenames of objfiles. Locus could be 'progspace' to specify
|
||||
that only xmethods from the current progspace should be disabled.
|
||||
|
||||
NAME-REGEXP is a regular expression matching the names of xmethods
|
||||
within a given locus. If this omitted for a specified locus, then all
|
||||
registered xmethod matchers in the locus are disabled. To disable
|
||||
only a certain xmethods managed by a single matcher, the name regexp
|
||||
can be specified as matcher-name-regexp;xmethod-name-regexp."""
|
||||
NAME-REGEXP is a regular expression matching the names of xmethods
|
||||
within a given locus. If this omitted for a specified locus, then all
|
||||
registered xmethod matchers in the locus are disabled. To disable
|
||||
only a certain xmethods managed by a single matcher, the name regexp
|
||||
can be specified as matcher-name-regexp;xmethod-name-regexp."""
|
||||
|
||||
def __init__(self):
|
||||
super(DisableXMethod, self).__init__("disable xmethod",
|
||||
gdb.COMMAND_DATA)
|
||||
super(DisableXMethod, self).__init__("disable xmethod", gdb.COMMAND_DATA)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
set_xm_status(arg, False)
|
||||
|
||||
@@ -22,8 +22,9 @@ from gdb.FrameDecorator import FrameDecorator
|
||||
import itertools
|
||||
import collections
|
||||
|
||||
|
||||
def get_priority(filter_item):
|
||||
""" Internal worker function to return the frame-filter's priority
|
||||
"""Internal worker function to return the frame-filter's priority
|
||||
from a frame filter object. This is a fail free function as it is
|
||||
used in sorting and filtering. If a badly implemented frame
|
||||
filter does not implement the priority attribute, return zero
|
||||
@@ -42,8 +43,9 @@ def get_priority(filter_item):
|
||||
# (incorrectly) set a priority, set it to zero.
|
||||
return getattr(filter_item, "priority", 0)
|
||||
|
||||
|
||||
def set_priority(filter_item, priority):
|
||||
""" Internal worker function to set the frame-filter's priority.
|
||||
"""Internal worker function to set the frame-filter's priority.
|
||||
|
||||
Arguments:
|
||||
filter_item: An object conforming to the frame filter
|
||||
@@ -53,8 +55,9 @@ def set_priority(filter_item, priority):
|
||||
|
||||
filter_item.priority = priority
|
||||
|
||||
|
||||
def get_enabled(filter_item):
|
||||
""" Internal worker function to return a filter's enabled state
|
||||
"""Internal worker function to return a filter's enabled state
|
||||
from a frame filter object. This is a fail free function as it is
|
||||
used in sorting and filtering. If a badly implemented frame
|
||||
filter does not implement the enabled attribute, return False
|
||||
@@ -75,8 +78,9 @@ def get_enabled(filter_item):
|
||||
# enabled to False.
|
||||
return getattr(filter_item, "enabled", False)
|
||||
|
||||
|
||||
def set_enabled(filter_item, state):
|
||||
""" Internal Worker function to set the frame-filter's enabled
|
||||
"""Internal Worker function to set the frame-filter's enabled
|
||||
state.
|
||||
|
||||
Arguments:
|
||||
@@ -87,8 +91,9 @@ def set_enabled(filter_item, state):
|
||||
|
||||
filter_item.enabled = state
|
||||
|
||||
|
||||
def return_list(name):
|
||||
""" Internal Worker function to return the frame filter
|
||||
"""Internal Worker function to return the frame filter
|
||||
dictionary, depending on the name supplied as an argument. If the
|
||||
name is not "all", "global" or "progspace", it is assumed to name
|
||||
an object-file.
|
||||
@@ -132,8 +137,9 @@ def return_list(name):
|
||||
msg = "Cannot find frame-filter dictionary for '" + name + "'"
|
||||
raise gdb.GdbError(msg)
|
||||
|
||||
|
||||
def _sort_list():
|
||||
""" Internal Worker function to merge all known frame-filter
|
||||
"""Internal Worker function to merge all known frame-filter
|
||||
lists, prune any filters with the state set to "disabled", and
|
||||
sort the list on the frame-filter's "priority" attribute.
|
||||
|
||||
@@ -143,16 +149,15 @@ def _sort_list():
|
||||
"""
|
||||
|
||||
all_filters = return_list("all")
|
||||
sorted_frame_filters = sorted(all_filters, key = get_priority,
|
||||
reverse = True)
|
||||
sorted_frame_filters = sorted(all_filters, key=get_priority, reverse=True)
|
||||
|
||||
sorted_frame_filters = filter(get_enabled,
|
||||
sorted_frame_filters)
|
||||
sorted_frame_filters = filter(get_enabled, sorted_frame_filters)
|
||||
|
||||
return sorted_frame_filters
|
||||
|
||||
|
||||
def execute_frame_filters(frame, frame_low, frame_high):
|
||||
""" Internal function called from GDB that will execute the chain
|
||||
"""Internal function called from GDB that will execute the chain
|
||||
of frame filters. Each filter is executed in priority order.
|
||||
After the execution completes, slice the iterator to frame_low -
|
||||
frame_high range.
|
||||
@@ -187,7 +192,7 @@ def execute_frame_filters(frame, frame_low, frame_high):
|
||||
# Apply a basic frame decorator to all gdb.Frames. This unifies
|
||||
# the interface. Python 3.x moved the itertools.imap
|
||||
# functionality to map(), so check if it is available.
|
||||
if hasattr(itertools,"imap"):
|
||||
if hasattr(itertools, "imap"):
|
||||
frame_iterator = itertools.imap(FrameDecorator, frame_iterator)
|
||||
else:
|
||||
frame_iterator = map(FrameDecorator, frame_iterator)
|
||||
@@ -207,7 +212,7 @@ def execute_frame_filters(frame, frame_low, frame_high):
|
||||
|
||||
for frame_item in frame_iterator:
|
||||
if count >= slice_length:
|
||||
sliced.popleft();
|
||||
sliced.popleft()
|
||||
count = count + 1
|
||||
sliced.append(frame_item)
|
||||
|
||||
@@ -221,7 +226,7 @@ def execute_frame_filters(frame, frame_low, frame_high):
|
||||
else:
|
||||
# As frames start from 0, add one to frame_high so islice
|
||||
# correctly finds the end
|
||||
frame_high = frame_high + 1;
|
||||
frame_high = frame_high + 1
|
||||
|
||||
sliced = itertools.islice(frame_iterator, frame_low, frame_high)
|
||||
|
||||
|
||||
@@ -19,14 +19,14 @@ import gdb
|
||||
class _AsString(gdb.Function):
|
||||
"""Return the string representation of a value.
|
||||
|
||||
Usage: $_as_string (VALUE)
|
||||
Usage: $_as_string (VALUE)
|
||||
|
||||
Arguments:
|
||||
Arguments:
|
||||
|
||||
VALUE: any value
|
||||
VALUE: any value
|
||||
|
||||
Returns:
|
||||
The string representation of the value."""
|
||||
Returns:
|
||||
The string representation of the value."""
|
||||
|
||||
def __init__(self):
|
||||
super(_AsString, self).__init__("_as_string")
|
||||
@@ -34,4 +34,5 @@ Returns:
|
||||
def invoke(self, val):
|
||||
return str(val)
|
||||
|
||||
|
||||
_AsString()
|
||||
|
||||
@@ -17,27 +17,28 @@
|
||||
import gdb
|
||||
import re
|
||||
|
||||
|
||||
class CallerIs(gdb.Function):
|
||||
"""Check the calling function's name.
|
||||
|
||||
Usage: $_caller_is (NAME [, NUMBER-OF-FRAMES])
|
||||
Usage: $_caller_is (NAME [, NUMBER-OF-FRAMES])
|
||||
|
||||
Arguments:
|
||||
Arguments:
|
||||
|
||||
NAME: The name of the function to search for.
|
||||
NAME: The name of the function to search for.
|
||||
|
||||
NUMBER-OF-FRAMES: How many stack frames to traverse back from the currently
|
||||
selected frame to compare with. If the value is greater than the depth of
|
||||
the stack from that point then the result is False.
|
||||
The default is 1.
|
||||
NUMBER-OF-FRAMES: How many stack frames to traverse back from the currently
|
||||
selected frame to compare with. If the value is greater than the depth of
|
||||
the stack from that point then the result is False.
|
||||
The default is 1.
|
||||
|
||||
Returns:
|
||||
True if the function's name at the specified frame is equal to NAME."""
|
||||
Returns:
|
||||
True if the function's name at the specified frame is equal to NAME."""
|
||||
|
||||
def __init__(self):
|
||||
super(CallerIs, self).__init__("_caller_is")
|
||||
|
||||
def invoke(self, name, nframes = 1):
|
||||
def invoke(self, name, nframes=1):
|
||||
if nframes < 0:
|
||||
raise ValueError("nframes must be >= 0")
|
||||
frame = gdb.selected_frame()
|
||||
@@ -48,27 +49,28 @@ Returns:
|
||||
nframes = nframes - 1
|
||||
return frame.name() == name.string()
|
||||
|
||||
|
||||
class CallerMatches(gdb.Function):
|
||||
"""Compare the calling function's name with a regexp.
|
||||
|
||||
Usage: $_caller_matches (REGEX [, NUMBER-OF-FRAMES])
|
||||
Usage: $_caller_matches (REGEX [, NUMBER-OF-FRAMES])
|
||||
|
||||
Arguments:
|
||||
Arguments:
|
||||
|
||||
REGEX: The regular expression to compare the function's name with.
|
||||
REGEX: The regular expression to compare the function's name with.
|
||||
|
||||
NUMBER-OF-FRAMES: How many stack frames to traverse back from the currently
|
||||
selected frame to compare with. If the value is greater than the depth of
|
||||
the stack from that point then the result is False.
|
||||
The default is 1.
|
||||
NUMBER-OF-FRAMES: How many stack frames to traverse back from the currently
|
||||
selected frame to compare with. If the value is greater than the depth of
|
||||
the stack from that point then the result is False.
|
||||
The default is 1.
|
||||
|
||||
Returns:
|
||||
True if the function's name at the specified frame matches REGEX."""
|
||||
Returns:
|
||||
True if the function's name at the specified frame matches REGEX."""
|
||||
|
||||
def __init__(self):
|
||||
super(CallerMatches, self).__init__("_caller_matches")
|
||||
|
||||
def invoke(self, name, nframes = 1):
|
||||
def invoke(self, name, nframes=1):
|
||||
if nframes < 0:
|
||||
raise ValueError("nframes must be >= 0")
|
||||
frame = gdb.selected_frame()
|
||||
@@ -79,60 +81,62 @@ Returns:
|
||||
nframes = nframes - 1
|
||||
return re.match(name.string(), frame.name()) is not None
|
||||
|
||||
|
||||
class AnyCallerIs(gdb.Function):
|
||||
"""Check all calling function's names.
|
||||
|
||||
Usage: $_any_caller_is (NAME [, NUMBER-OF-FRAMES])
|
||||
Usage: $_any_caller_is (NAME [, NUMBER-OF-FRAMES])
|
||||
|
||||
Arguments:
|
||||
Arguments:
|
||||
|
||||
NAME: The name of the function to search for.
|
||||
NAME: The name of the function to search for.
|
||||
|
||||
NUMBER-OF-FRAMES: How many stack frames to traverse back from the currently
|
||||
selected frame to compare with. If the value is greater than the depth of
|
||||
the stack from that point then the result is False.
|
||||
The default is 1.
|
||||
NUMBER-OF-FRAMES: How many stack frames to traverse back from the currently
|
||||
selected frame to compare with. If the value is greater than the depth of
|
||||
the stack from that point then the result is False.
|
||||
The default is 1.
|
||||
|
||||
Returns:
|
||||
True if any function's name is equal to NAME."""
|
||||
Returns:
|
||||
True if any function's name is equal to NAME."""
|
||||
|
||||
def __init__(self):
|
||||
super(AnyCallerIs, self).__init__("_any_caller_is")
|
||||
|
||||
def invoke(self, name, nframes = 1):
|
||||
def invoke(self, name, nframes=1):
|
||||
if nframes < 0:
|
||||
raise ValueError("nframes must be >= 0")
|
||||
frame = gdb.selected_frame()
|
||||
while nframes >= 0:
|
||||
if frame.name() == name.string():
|
||||
return True
|
||||
return True
|
||||
frame = frame.older()
|
||||
if frame is None:
|
||||
return False
|
||||
nframes = nframes - 1
|
||||
return False
|
||||
|
||||
|
||||
class AnyCallerMatches(gdb.Function):
|
||||
"""Compare all calling function's names with a regexp.
|
||||
|
||||
Usage: $_any_caller_matches (REGEX [, NUMBER-OF-FRAMES])
|
||||
Usage: $_any_caller_matches (REGEX [, NUMBER-OF-FRAMES])
|
||||
|
||||
Arguments:
|
||||
Arguments:
|
||||
|
||||
REGEX: The regular expression to compare the function's name with.
|
||||
REGEX: The regular expression to compare the function's name with.
|
||||
|
||||
NUMBER-OF-FRAMES: How many stack frames to traverse back from the currently
|
||||
selected frame to compare with. If the value is greater than the depth of
|
||||
the stack from that point then the result is False.
|
||||
The default is 1.
|
||||
NUMBER-OF-FRAMES: How many stack frames to traverse back from the currently
|
||||
selected frame to compare with. If the value is greater than the depth of
|
||||
the stack from that point then the result is False.
|
||||
The default is 1.
|
||||
|
||||
Returns:
|
||||
True if any function's name matches REGEX."""
|
||||
Returns:
|
||||
True if any function's name matches REGEX."""
|
||||
|
||||
def __init__(self):
|
||||
super(AnyCallerMatches, self).__init__("_any_caller_matches")
|
||||
|
||||
def invoke(self, name, nframes = 1):
|
||||
def invoke(self, name, nframes=1):
|
||||
if nframes < 0:
|
||||
raise ValueError("nframes must be >= 0")
|
||||
frame = gdb.selected_frame()
|
||||
@@ -146,6 +150,7 @@ Returns:
|
||||
nframes = nframes - 1
|
||||
return False
|
||||
|
||||
|
||||
CallerIs()
|
||||
CallerMatches()
|
||||
AnyCallerIs()
|
||||
|
||||
@@ -21,76 +21,80 @@ import re
|
||||
|
||||
|
||||
class _MemEq(gdb.Function):
|
||||
"""$_memeq - compare bytes of memory.
|
||||
"""$_memeq - compare bytes of memory.
|
||||
|
||||
Usage: $_memeq (A, B, LEN)
|
||||
Usage: $_memeq (A, B, LEN)
|
||||
|
||||
Returns:
|
||||
True if LEN bytes at A and B compare equally."""
|
||||
def __init__(self):
|
||||
super(_MemEq, self).__init__("_memeq")
|
||||
Returns:
|
||||
True if LEN bytes at A and B compare equally."""
|
||||
|
||||
def invoke(self, a, b, length):
|
||||
if length < 0:
|
||||
raise ValueError("length must be non-negative")
|
||||
if length == 0:
|
||||
return True
|
||||
# The argument(s) to vector are [low_bound,]high_bound.
|
||||
byte_vector = gdb.lookup_type("char").vector(length - 1)
|
||||
ptr_byte_vector = byte_vector.pointer()
|
||||
a_ptr = a.reinterpret_cast(ptr_byte_vector)
|
||||
b_ptr = b.reinterpret_cast(ptr_byte_vector)
|
||||
return a_ptr.dereference() == b_ptr.dereference()
|
||||
def __init__(self):
|
||||
super(_MemEq, self).__init__("_memeq")
|
||||
|
||||
def invoke(self, a, b, length):
|
||||
if length < 0:
|
||||
raise ValueError("length must be non-negative")
|
||||
if length == 0:
|
||||
return True
|
||||
# The argument(s) to vector are [low_bound,]high_bound.
|
||||
byte_vector = gdb.lookup_type("char").vector(length - 1)
|
||||
ptr_byte_vector = byte_vector.pointer()
|
||||
a_ptr = a.reinterpret_cast(ptr_byte_vector)
|
||||
b_ptr = b.reinterpret_cast(ptr_byte_vector)
|
||||
return a_ptr.dereference() == b_ptr.dereference()
|
||||
|
||||
|
||||
class _StrLen(gdb.Function):
|
||||
"""$_strlen - compute string length.
|
||||
"""$_strlen - compute string length.
|
||||
|
||||
Usage: $_strlen (A)
|
||||
Usage: $_strlen (A)
|
||||
|
||||
Returns:
|
||||
Length of string A, assumed to be a string in the current language."""
|
||||
def __init__(self):
|
||||
super(_StrLen, self).__init__("_strlen")
|
||||
Returns:
|
||||
Length of string A, assumed to be a string in the current language."""
|
||||
|
||||
def invoke(self, a):
|
||||
s = a.string()
|
||||
return len(s)
|
||||
def __init__(self):
|
||||
super(_StrLen, self).__init__("_strlen")
|
||||
|
||||
def invoke(self, a):
|
||||
s = a.string()
|
||||
return len(s)
|
||||
|
||||
|
||||
class _StrEq(gdb.Function):
|
||||
"""$_streq - check string equality.
|
||||
"""$_streq - check string equality.
|
||||
|
||||
Usage: $_streq (A, B)
|
||||
Usage: $_streq (A, B)
|
||||
|
||||
Returns:
|
||||
True if A and B are identical strings in the current language.
|
||||
Returns:
|
||||
True if A and B are identical strings in the current language.
|
||||
|
||||
Example (amd64-linux):
|
||||
catch syscall open
|
||||
cond $bpnum $_streq((char*) $rdi, "foo")"""
|
||||
def __init__(self):
|
||||
super(_StrEq, self).__init__("_streq")
|
||||
Example (amd64-linux):
|
||||
catch syscall open
|
||||
cond $bpnum $_streq((char*) $rdi, "foo")"""
|
||||
|
||||
def invoke(self, a, b):
|
||||
return a.string() == b.string()
|
||||
def __init__(self):
|
||||
super(_StrEq, self).__init__("_streq")
|
||||
|
||||
def invoke(self, a, b):
|
||||
return a.string() == b.string()
|
||||
|
||||
|
||||
class _RegEx(gdb.Function):
|
||||
"""$_regex - check if a string matches a regular expression.
|
||||
"""$_regex - check if a string matches a regular expression.
|
||||
|
||||
Usage: $_regex (STRING, REGEX)
|
||||
Usage: $_regex (STRING, REGEX)
|
||||
|
||||
Returns:
|
||||
True if string STRING (in the current language) matches the
|
||||
regular expression REGEX."""
|
||||
def __init__(self):
|
||||
super(_RegEx, self).__init__("_regex")
|
||||
Returns:
|
||||
True if string STRING (in the current language) matches the
|
||||
regular expression REGEX."""
|
||||
|
||||
def invoke(self, string, regex):
|
||||
s = string.string()
|
||||
r = re.compile(regex.string())
|
||||
return bool(r.match(s))
|
||||
def __init__(self):
|
||||
super(_RegEx, self).__init__("_regex")
|
||||
|
||||
def invoke(self, string, regex):
|
||||
s = string.string()
|
||||
r = re.compile(regex.string())
|
||||
return bool(r.match(s))
|
||||
|
||||
|
||||
# GDB will import us automagically via gdb/__init__.py.
|
||||
|
||||
@@ -23,21 +23,23 @@ if sys.version_info[0] > 2:
|
||||
basestring = str
|
||||
long = int
|
||||
|
||||
|
||||
class MpxBound128Printer:
|
||||
"""Adds size field to a mpx __gdb_builtin_type_bound128 type."""
|
||||
|
||||
def __init__ (self, val):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string (self):
|
||||
def to_string(self):
|
||||
upper = self.val["ubound"]
|
||||
lower = self.val["lbound"]
|
||||
size = (long) ((upper) - (lower))
|
||||
size = (long)((upper) - (lower))
|
||||
if size > -1:
|
||||
size = size + 1
|
||||
result = '{lbound = %s, ubound = %s} : size %s' % (lower, upper, size)
|
||||
result = "{lbound = %s, ubound = %s} : size %s" % (lower, upper, size)
|
||||
return result
|
||||
|
||||
gdb.printing.add_builtin_pretty_printer ('mpx_bound128',
|
||||
'^builtin_type_bound128',
|
||||
MpxBound128Printer)
|
||||
|
||||
gdb.printing.add_builtin_pretty_printer(
|
||||
"mpx_bound128", "^builtin_type_bound128", MpxBound128Printer
|
||||
)
|
||||
|
||||
@@ -26,6 +26,7 @@ if sys.version_info[0] > 2:
|
||||
basestring = str
|
||||
long = int
|
||||
|
||||
|
||||
class PrettyPrinter(object):
|
||||
"""A basic pretty-printer.
|
||||
|
||||
@@ -110,22 +111,23 @@ def register_pretty_printer(obj, printer, replace=False):
|
||||
if not hasattr(printer, "__name__") and not hasattr(printer, "name"):
|
||||
raise TypeError("printer missing attribute: name")
|
||||
if hasattr(printer, "name") and not hasattr(printer, "enabled"):
|
||||
raise TypeError("printer missing attribute: enabled")
|
||||
raise TypeError("printer missing attribute: enabled")
|
||||
if not hasattr(printer, "__call__"):
|
||||
raise TypeError("printer missing attribute: __call__")
|
||||
|
||||
if hasattr(printer, "name"):
|
||||
name = printer.name
|
||||
name = printer.name
|
||||
else:
|
||||
name = printer.__name__
|
||||
name = printer.__name__
|
||||
if obj is None or obj is gdb:
|
||||
if gdb.parameter("verbose"):
|
||||
gdb.write("Registering global %s pretty-printer ...\n" % name)
|
||||
obj = gdb
|
||||
else:
|
||||
if gdb.parameter("verbose"):
|
||||
gdb.write("Registering %s pretty-printer for %s ...\n" % (
|
||||
name, obj.filename))
|
||||
gdb.write(
|
||||
"Registering %s pretty-printer for %s ...\n" % (name, obj.filename)
|
||||
)
|
||||
|
||||
# Printers implemented as functions are old-style. In order to not risk
|
||||
# breaking anything we do not check __name__ here.
|
||||
@@ -148,8 +150,9 @@ def register_pretty_printer(obj, printer, replace=False):
|
||||
del obj.pretty_printers[i]
|
||||
break
|
||||
else:
|
||||
raise RuntimeError("pretty-printer already registered: %s" %
|
||||
printer.name)
|
||||
raise RuntimeError(
|
||||
"pretty-printer already registered: %s" % printer.name
|
||||
)
|
||||
i = i + 1
|
||||
|
||||
obj.pretty_printers.insert(0, printer)
|
||||
@@ -197,8 +200,7 @@ class RegexpCollectionPrettyPrinter(PrettyPrinter):
|
||||
# cumbersome to make a regexp of a regexp). So now the name is a
|
||||
# separate parameter.
|
||||
|
||||
self.subprinters.append(self.RegexpSubprinter(name, regexp,
|
||||
gen_printer))
|
||||
self.subprinters.append(self.RegexpSubprinter(name, regexp, gen_printer))
|
||||
|
||||
def __call__(self, val):
|
||||
"""Lookup the pretty-printer for the provided value."""
|
||||
@@ -220,6 +222,7 @@ class RegexpCollectionPrettyPrinter(PrettyPrinter):
|
||||
# Cannot find a pretty printer. Return None.
|
||||
return None
|
||||
|
||||
|
||||
# A helper class for printing enum types. This class is instantiated
|
||||
# with a list of enumerators to print a particular Value.
|
||||
class _EnumInstance:
|
||||
@@ -238,9 +241,10 @@ class _EnumInstance:
|
||||
any_found = True
|
||||
if not any_found or v != 0:
|
||||
# Leftover value.
|
||||
flag_list.append('<unknown: 0x%x>' % v)
|
||||
flag_list.append("<unknown: 0x%x>" % v)
|
||||
return "0x%x [%s]" % (int(self.val), " | ".join(flag_list))
|
||||
|
||||
|
||||
class FlagEnumerationPrinter(PrettyPrinter):
|
||||
"""A pretty-printer which can be used to print a flag-style enumeration.
|
||||
A flag-style enumeration is one where the enumerators are or'd
|
||||
@@ -263,7 +267,7 @@ class FlagEnumerationPrinter(PrettyPrinter):
|
||||
self.enumerators.append((field.name, field.enumval))
|
||||
# Sorting the enumerators by value usually does the right
|
||||
# thing.
|
||||
self.enumerators.sort(key = lambda x: x[1])
|
||||
self.enumerators.sort(key=lambda x: x[1])
|
||||
|
||||
if self.enabled:
|
||||
return _EnumInstance(self.enumerators, val)
|
||||
@@ -281,5 +285,6 @@ register_pretty_printer(None, _builtin_pretty_printers)
|
||||
|
||||
# Add a builtin pretty-printer.
|
||||
|
||||
|
||||
def add_builtin_pretty_printer(name, regexp, printer):
|
||||
_builtin_pretty_printers.add_printer(name, regexp, printer)
|
||||
|
||||
@@ -19,10 +19,12 @@
|
||||
import gdb
|
||||
import os
|
||||
|
||||
|
||||
def _prompt_pwd(ignore):
|
||||
"The current working directory."
|
||||
return os.getcwd()
|
||||
|
||||
|
||||
def _prompt_object_attr(func, what, attr, nattr):
|
||||
"""Internal worker for fetching GDB attributes."""
|
||||
if attr is None:
|
||||
@@ -30,91 +32,104 @@ def _prompt_object_attr(func, what, attr, nattr):
|
||||
try:
|
||||
obj = func()
|
||||
except gdb.error:
|
||||
return '<no %s>' % what
|
||||
return "<no %s>" % what
|
||||
if hasattr(obj, attr):
|
||||
result = getattr(obj, attr)
|
||||
if callable(result):
|
||||
result = result()
|
||||
return result
|
||||
else:
|
||||
return '<no attribute %s on current %s>' % (attr, what)
|
||||
return "<no attribute %s on current %s>" % (attr, what)
|
||||
|
||||
|
||||
def _prompt_frame(attr):
|
||||
"The selected frame; an argument names a frame parameter."
|
||||
return _prompt_object_attr(gdb.selected_frame, 'frame', attr, 'name')
|
||||
return _prompt_object_attr(gdb.selected_frame, "frame", attr, "name")
|
||||
|
||||
|
||||
def _prompt_thread(attr):
|
||||
"The selected thread; an argument names a thread parameter."
|
||||
return _prompt_object_attr(gdb.selected_thread, 'thread', attr, 'num')
|
||||
return _prompt_object_attr(gdb.selected_thread, "thread", attr, "num")
|
||||
|
||||
|
||||
def _prompt_version(attr):
|
||||
"The version of GDB."
|
||||
return gdb.VERSION
|
||||
|
||||
|
||||
def _prompt_esc(attr):
|
||||
"The ESC character."
|
||||
return '\033'
|
||||
return "\033"
|
||||
|
||||
|
||||
def _prompt_bs(attr):
|
||||
"A backslash."
|
||||
return '\\'
|
||||
return "\\"
|
||||
|
||||
|
||||
def _prompt_n(attr):
|
||||
"A newline."
|
||||
return '\n'
|
||||
return "\n"
|
||||
|
||||
|
||||
def _prompt_r(attr):
|
||||
"A carriage return."
|
||||
return '\r'
|
||||
return "\r"
|
||||
|
||||
|
||||
def _prompt_param(attr):
|
||||
"A parameter's value; the argument names the parameter."
|
||||
return gdb.parameter(attr)
|
||||
|
||||
|
||||
def _prompt_noprint_begin(attr):
|
||||
"Begins a sequence of non-printing characters."
|
||||
return '\001'
|
||||
return "\001"
|
||||
|
||||
|
||||
def _prompt_noprint_end(attr):
|
||||
"Ends a sequence of non-printing characters."
|
||||
return '\002'
|
||||
"Ends a sequence of non-printing characters."
|
||||
return "\002"
|
||||
|
||||
|
||||
prompt_substitutions = {
|
||||
'e': _prompt_esc,
|
||||
'\\': _prompt_bs,
|
||||
'n': _prompt_n,
|
||||
'r': _prompt_r,
|
||||
'v': _prompt_version,
|
||||
'w': _prompt_pwd,
|
||||
'f': _prompt_frame,
|
||||
't': _prompt_thread,
|
||||
'p': _prompt_param,
|
||||
'[': _prompt_noprint_begin,
|
||||
']': _prompt_noprint_end
|
||||
"e": _prompt_esc,
|
||||
"\\": _prompt_bs,
|
||||
"n": _prompt_n,
|
||||
"r": _prompt_r,
|
||||
"v": _prompt_version,
|
||||
"w": _prompt_pwd,
|
||||
"f": _prompt_frame,
|
||||
"t": _prompt_thread,
|
||||
"p": _prompt_param,
|
||||
"[": _prompt_noprint_begin,
|
||||
"]": _prompt_noprint_end,
|
||||
}
|
||||
|
||||
|
||||
def prompt_help():
|
||||
"""Generate help dynamically from the __doc__ strings of attribute
|
||||
functions."""
|
||||
|
||||
result = ''
|
||||
keys = sorted (prompt_substitutions.keys())
|
||||
result = ""
|
||||
keys = sorted(prompt_substitutions.keys())
|
||||
for key in keys:
|
||||
result += ' \\%s\t%s\n' % (key, prompt_substitutions[key].__doc__)
|
||||
result += " \\%s\t%s\n" % (key, prompt_substitutions[key].__doc__)
|
||||
result += """
|
||||
A substitution can be used in a simple form, like "\\f".
|
||||
An argument can also be passed to it, like "\\f{name}".
|
||||
The meaning of the argument depends on the particular substitution."""
|
||||
return result
|
||||
|
||||
|
||||
def substitute_prompt(prompt):
|
||||
"Perform substitutions on PROMPT."
|
||||
|
||||
result = ''
|
||||
result = ""
|
||||
plen = len(prompt)
|
||||
i = 0
|
||||
while i < plen:
|
||||
if prompt[i] == '\\':
|
||||
if prompt[i] == "\\":
|
||||
i = i + 1
|
||||
if i >= plen:
|
||||
break
|
||||
@@ -123,12 +138,12 @@ def substitute_prompt(prompt):
|
||||
if cmdch in prompt_substitutions:
|
||||
cmd = prompt_substitutions[cmdch]
|
||||
|
||||
if i + 1 < plen and prompt[i + 1] == '{':
|
||||
if i + 1 < plen and prompt[i + 1] == "{":
|
||||
j = i + 1
|
||||
while j < plen and prompt[j] != '}':
|
||||
while j < plen and prompt[j] != "}":
|
||||
j = j + 1
|
||||
# Just ignore formatting errors.
|
||||
if j >= plen or prompt[j] != '}':
|
||||
if j >= plen or prompt[j] != "}":
|
||||
arg = None
|
||||
else:
|
||||
arg = prompt[i + 2 : j]
|
||||
|
||||
@@ -30,11 +30,12 @@ def get_basic_type(type_):
|
||||
and typedefs/references converted to the underlying type.
|
||||
"""
|
||||
|
||||
while (type_.code == gdb.TYPE_CODE_REF or
|
||||
type_.code == gdb.TYPE_CODE_RVALUE_REF or
|
||||
type_.code == gdb.TYPE_CODE_TYPEDEF):
|
||||
if (type_.code == gdb.TYPE_CODE_REF or
|
||||
type_.code == gdb.TYPE_CODE_RVALUE_REF):
|
||||
while (
|
||||
type_.code == gdb.TYPE_CODE_REF
|
||||
or type_.code == gdb.TYPE_CODE_RVALUE_REF
|
||||
or type_.code == gdb.TYPE_CODE_TYPEDEF
|
||||
):
|
||||
if type_.code == gdb.TYPE_CODE_REF or type_.code == gdb.TYPE_CODE_RVALUE_REF:
|
||||
type_ = type_.target()
|
||||
else:
|
||||
type_ = type_.strip_typedefs()
|
||||
@@ -57,8 +58,7 @@ def has_field(type_, field):
|
||||
"""
|
||||
|
||||
type_ = get_basic_type(type_)
|
||||
if (type_.code != gdb.TYPE_CODE_STRUCT and
|
||||
type_.code != gdb.TYPE_CODE_UNION):
|
||||
if type_.code != gdb.TYPE_CODE_STRUCT and type_.code != gdb.TYPE_CODE_UNION:
|
||||
raise TypeError("not a struct or union")
|
||||
for f in type_.fields():
|
||||
if f.is_base_class:
|
||||
@@ -93,7 +93,7 @@ def make_enum_dict(enum_type):
|
||||
return enum_dict
|
||||
|
||||
|
||||
def deep_items (type_):
|
||||
def deep_items(type_):
|
||||
"""Return an iterator that recursively traverses anonymous fields.
|
||||
|
||||
Arguments:
|
||||
@@ -105,13 +105,14 @@ def deep_items (type_):
|
||||
pairs of key, value, but for any anonymous struct or union
|
||||
field that field is traversed recursively, depth-first.
|
||||
"""
|
||||
for k, v in type_.iteritems ():
|
||||
for k, v in type_.iteritems():
|
||||
if k:
|
||||
yield k, v
|
||||
else:
|
||||
for i in deep_items (v.type):
|
||||
for i in deep_items(v.type):
|
||||
yield i
|
||||
|
||||
|
||||
class TypePrinter(object):
|
||||
"""The base class for type printers.
|
||||
|
||||
@@ -134,6 +135,7 @@ class TypePrinter(object):
|
||||
def instantiate(self):
|
||||
return None
|
||||
|
||||
|
||||
# Helper function for computing the list of type recognizers.
|
||||
def _get_some_type_recognizers(result, plist):
|
||||
for printer in plist:
|
||||
@@ -143,6 +145,7 @@ def _get_some_type_recognizers(result, plist):
|
||||
result.append(inst)
|
||||
return None
|
||||
|
||||
|
||||
def get_type_recognizers():
|
||||
"Return a list of the enabled type recognizers for the current context."
|
||||
result = []
|
||||
@@ -157,6 +160,7 @@ def get_type_recognizers():
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def apply_type_recognizers(recognizers, type_obj):
|
||||
"""Apply the given list of type recognizers to the type TYPE_OBJ.
|
||||
If any recognizer in the list recognizes TYPE_OBJ, returns the name
|
||||
@@ -167,6 +171,7 @@ def apply_type_recognizers(recognizers, type_obj):
|
||||
return result
|
||||
return None
|
||||
|
||||
|
||||
def register_type_printer(locus, printer):
|
||||
"""Register a type printer.
|
||||
PRINTER is the type printer instance.
|
||||
|
||||
@@ -77,8 +77,9 @@ def register_unwinder(locus, unwinder, replace=False):
|
||||
locus = gdb
|
||||
elif isinstance(locus, gdb.Objfile) or isinstance(locus, gdb.Progspace):
|
||||
if gdb.parameter("verbose"):
|
||||
gdb.write("Registering %s unwinder for %s ...\n" %
|
||||
(unwinder.name, locus.filename))
|
||||
gdb.write(
|
||||
"Registering %s unwinder for %s ...\n" % (unwinder.name, locus.filename)
|
||||
)
|
||||
else:
|
||||
raise TypeError("locus should be gdb.Objfile or gdb.Progspace or None")
|
||||
|
||||
@@ -88,8 +89,7 @@ def register_unwinder(locus, unwinder, replace=False):
|
||||
if replace:
|
||||
del locus.frame_unwinders[i]
|
||||
else:
|
||||
raise RuntimeError("Unwinder %s already exists." %
|
||||
unwinder.name)
|
||||
raise RuntimeError("Unwinder %s already exists." % unwinder.name)
|
||||
i += 1
|
||||
locus.frame_unwinders.insert(0, unwinder)
|
||||
gdb.invalidate_cached_frames()
|
||||
|
||||
@@ -172,9 +172,9 @@ class SimpleXMethodMatcher(XMethodMatcher):
|
||||
def __call__(self, *args):
|
||||
return self._method_function(*args)
|
||||
|
||||
|
||||
def __init__(self, name, class_matcher, method_matcher, method_function,
|
||||
*arg_types):
|
||||
def __init__(
|
||||
self, name, class_matcher, method_matcher, method_function, *arg_types
|
||||
):
|
||||
"""
|
||||
Args:
|
||||
name: Name of the xmethod matcher.
|
||||
@@ -195,7 +195,8 @@ class SimpleXMethodMatcher(XMethodMatcher):
|
||||
XMethodMatcher.__init__(self, name)
|
||||
assert callable(method_function), (
|
||||
"The 'method_function' argument to 'SimpleXMethodMatcher' "
|
||||
"__init__ method should be a callable.")
|
||||
"__init__ method should be a callable."
|
||||
)
|
||||
self._method_function = method_function
|
||||
self._class_matcher = class_matcher
|
||||
self._method_matcher = method_matcher
|
||||
@@ -206,13 +207,15 @@ class SimpleXMethodMatcher(XMethodMatcher):
|
||||
mm = re.match(self._method_matcher, method_name)
|
||||
if cm and mm:
|
||||
return SimpleXMethodMatcher.SimpleXMethodWorker(
|
||||
self._method_function, self._arg_types)
|
||||
self._method_function, self._arg_types
|
||||
)
|
||||
|
||||
|
||||
# A helper function for register_xmethod_matcher which returns an error
|
||||
# object if MATCHER is not having the requisite attributes in the proper
|
||||
# format.
|
||||
|
||||
|
||||
def _validate_xmethod_matcher(matcher):
|
||||
if not hasattr(matcher, "match"):
|
||||
return TypeError("Xmethod matcher is missing method: match")
|
||||
@@ -221,17 +224,17 @@ def _validate_xmethod_matcher(matcher):
|
||||
if not hasattr(matcher, "enabled"):
|
||||
return TypeError("Xmethod matcher is missing attribute: enabled")
|
||||
if not isinstance(matcher.name, basestring):
|
||||
return TypeError("Attribute 'name' of xmethod matcher is not a "
|
||||
"string")
|
||||
return TypeError("Attribute 'name' of xmethod matcher is not a " "string")
|
||||
if matcher.name.find(";") >= 0:
|
||||
return ValueError("Xmethod matcher name cannot contain ';' in it")
|
||||
|
||||
|
||||
# A helper function for register_xmethod_matcher which looks up an
|
||||
# A helper function for register_xmethod_matcher which looks up an
|
||||
# xmethod matcher with NAME in LOCUS. Returns the index of the xmethod
|
||||
# matcher in 'xmethods' sequence attribute of the LOCUS. If NAME is not
|
||||
# found in LOCUS, then -1 is returned.
|
||||
|
||||
|
||||
def _lookup_xmethod_matcher(locus, name):
|
||||
for i in range(0, len(locus.xmethods)):
|
||||
if locus.xmethods[i].name == name:
|
||||
@@ -268,8 +271,10 @@ def register_xmethod_matcher(locus, matcher, replace=False):
|
||||
if replace:
|
||||
del locus.xmethods[index]
|
||||
else:
|
||||
raise RuntimeError("Xmethod matcher already registered with "
|
||||
"%s: %s" % (locus_name, matcher.name))
|
||||
raise RuntimeError(
|
||||
"Xmethod matcher already registered with "
|
||||
"%s: %s" % (locus_name, matcher.name)
|
||||
)
|
||||
if gdb.parameter("verbose"):
|
||||
gdb.write("Registering xmethod matcher '%s' with %s' ...\n")
|
||||
locus.xmethods.insert(0, matcher)
|
||||
|
||||
@@ -6,31 +6,34 @@ import os
|
||||
import getopt
|
||||
from distutils import sysconfig
|
||||
|
||||
valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags',
|
||||
'ldflags', 'help']
|
||||
valid_opts = ["prefix", "exec-prefix", "includes", "libs", "cflags", "ldflags", "help"]
|
||||
|
||||
|
||||
def exit_with_usage(code=1):
|
||||
sys.stderr.write ("Usage: %s [%s]\n" % (sys.argv[0],
|
||||
'|'.join('--'+opt for opt in valid_opts)))
|
||||
sys.stderr.write(
|
||||
"Usage: %s [%s]\n" % (sys.argv[0], "|".join("--" + opt for opt in valid_opts))
|
||||
)
|
||||
sys.exit(code)
|
||||
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], '', valid_opts)
|
||||
opts, args = getopt.getopt(sys.argv[1:], "", valid_opts)
|
||||
except getopt.error:
|
||||
exit_with_usage()
|
||||
|
||||
if not opts:
|
||||
exit_with_usage()
|
||||
|
||||
pyver = sysconfig.get_config_var('VERSION')
|
||||
pyver = sysconfig.get_config_var("VERSION")
|
||||
getvar = sysconfig.get_config_var
|
||||
abiflags = getattr (sys, "abiflags", "")
|
||||
abiflags = getattr(sys, "abiflags", "")
|
||||
|
||||
opt_flags = [flag for (flag, val) in opts]
|
||||
|
||||
if '--help' in opt_flags:
|
||||
if "--help" in opt_flags:
|
||||
exit_with_usage(code=0)
|
||||
|
||||
|
||||
def to_unix_path(path):
|
||||
"""On Windows, returns the given path with all backslashes
|
||||
converted into forward slashes. This is to help prevent problems
|
||||
@@ -39,39 +42,41 @@ def to_unix_path(path):
|
||||
|
||||
On Unix systems, returns the path unchanged.
|
||||
"""
|
||||
if os.name == 'nt':
|
||||
path = path.replace('\\', '/')
|
||||
if os.name == "nt":
|
||||
path = path.replace("\\", "/")
|
||||
return path
|
||||
|
||||
|
||||
for opt in opt_flags:
|
||||
if opt == '--prefix':
|
||||
print (to_unix_path(sysconfig.PREFIX))
|
||||
if opt == "--prefix":
|
||||
print(to_unix_path(sysconfig.PREFIX))
|
||||
|
||||
elif opt == '--exec-prefix':
|
||||
print (to_unix_path(sysconfig.EXEC_PREFIX))
|
||||
elif opt == "--exec-prefix":
|
||||
print(to_unix_path(sysconfig.EXEC_PREFIX))
|
||||
|
||||
elif opt in ('--includes', '--cflags'):
|
||||
flags = ['-I' + sysconfig.get_python_inc(),
|
||||
'-I' + sysconfig.get_python_inc(plat_specific=True)]
|
||||
if opt == '--cflags':
|
||||
flags.extend(getvar('CFLAGS').split())
|
||||
print (to_unix_path(' '.join(flags)))
|
||||
elif opt in ("--includes", "--cflags"):
|
||||
flags = [
|
||||
"-I" + sysconfig.get_python_inc(),
|
||||
"-I" + sysconfig.get_python_inc(plat_specific=True),
|
||||
]
|
||||
if opt == "--cflags":
|
||||
flags.extend(getvar("CFLAGS").split())
|
||||
print(to_unix_path(" ".join(flags)))
|
||||
|
||||
elif opt in ('--libs', '--ldflags'):
|
||||
libs = ['-lpython' + pyver + abiflags]
|
||||
if getvar('LIBS') is not None:
|
||||
libs.extend(getvar('LIBS').split())
|
||||
if getvar('SYSLIBS') is not None:
|
||||
libs.extend(getvar('SYSLIBS').split())
|
||||
elif opt in ("--libs", "--ldflags"):
|
||||
libs = ["-lpython" + pyver + abiflags]
|
||||
if getvar("LIBS") is not None:
|
||||
libs.extend(getvar("LIBS").split())
|
||||
if getvar("SYSLIBS") is not None:
|
||||
libs.extend(getvar("SYSLIBS").split())
|
||||
# add the prefix/lib/pythonX.Y/config dir, but only if there is no
|
||||
# shared library in prefix/lib/.
|
||||
if opt == '--ldflags':
|
||||
if not getvar('Py_ENABLE_SHARED'):
|
||||
if getvar('LIBPL') is not None:
|
||||
libs.insert(0, '-L' + getvar('LIBPL'))
|
||||
elif os.name == 'nt':
|
||||
libs.insert(0, '-L' + sysconfig.PREFIX + '/libs')
|
||||
if getvar('LINKFORSHARED') is not None:
|
||||
libs.extend(getvar('LINKFORSHARED').split())
|
||||
print (to_unix_path(' '.join(libs)))
|
||||
|
||||
if opt == "--ldflags":
|
||||
if not getvar("Py_ENABLE_SHARED"):
|
||||
if getvar("LIBPL") is not None:
|
||||
libs.insert(0, "-L" + getvar("LIBPL"))
|
||||
elif os.name == "nt":
|
||||
libs.insert(0, "-L" + sysconfig.PREFIX + "/libs")
|
||||
if getvar("LINKFORSHARED") is not None:
|
||||
libs.extend(getvar("LINKFORSHARED").split())
|
||||
print(to_unix_path(" ".join(libs)))
|
||||
|
||||
@@ -12,7 +12,8 @@ import time
|
||||
infname = sys.argv[1]
|
||||
inf = file(infname)
|
||||
|
||||
print("""\
|
||||
print(
|
||||
"""\
|
||||
<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2009-%s Free Software Foundation, Inc.
|
||||
|
||||
@@ -30,31 +31,33 @@ print("""\
|
||||
The file mentioned above belongs to the Linux Kernel.
|
||||
Some small hand-edits were made. -->
|
||||
|
||||
<syscalls_info>""" % (time.strftime("%Y"), infname))
|
||||
<syscalls_info>"""
|
||||
% (time.strftime("%Y"), infname)
|
||||
)
|
||||
|
||||
|
||||
def record(name, number, comment=None):
|
||||
#nm = 'name="%s"' % name
|
||||
#s = ' <syscall %-30s number="%d"/>' % (nm, number)
|
||||
# nm = 'name="%s"' % name
|
||||
# s = ' <syscall %-30s number="%d"/>' % (nm, number)
|
||||
s = ' <syscall name="%s" number="%d"/>' % (name, number)
|
||||
if comment:
|
||||
s += ' <!-- %s -->' % comment
|
||||
s += " <!-- %s -->" % comment
|
||||
print(s)
|
||||
|
||||
|
||||
for line in inf:
|
||||
m = re.match(r'^#define __NR_(\w+)\s+\(__NR_SYSCALL_BASE\+\s*(\d+)\)',
|
||||
line)
|
||||
m = re.match(r"^#define __NR_(\w+)\s+\(__NR_SYSCALL_BASE\+\s*(\d+)\)", line)
|
||||
if m:
|
||||
record(m.group(1), int(m.group(2)))
|
||||
continue
|
||||
|
||||
m = re.match(r'^\s+/\* (\d+) was sys_(\w+) \*/$', line)
|
||||
m = re.match(r"^\s+/\* (\d+) was sys_(\w+) \*/$", line)
|
||||
if m:
|
||||
record(m.group(2), int(m.group(1)), 'removed')
|
||||
record(m.group(2), int(m.group(1)), "removed")
|
||||
|
||||
m = re.match(r'^#define __ARM_NR_(\w+)\s+\(__ARM_NR_BASE\+\s*(\d+)\)',
|
||||
line)
|
||||
m = re.match(r"^#define __ARM_NR_(\w+)\s+\(__ARM_NR_BASE\+\s*(\d+)\)", line)
|
||||
if m:
|
||||
record('ARM_'+m.group(1), 0x0f0000+int(m.group(2)))
|
||||
record("ARM_" + m.group(1), 0x0F0000 + int(m.group(2)))
|
||||
continue
|
||||
|
||||
print('</syscalls_info>')
|
||||
print("</syscalls_info>")
|
||||
|
||||
@@ -79,9 +79,8 @@ def elinos_init():
|
||||
if elinos_env["project"] is None:
|
||||
warn("Xenomai libraries may not be loaded")
|
||||
else:
|
||||
for dir in elinos_env['xenomai']:
|
||||
solib_dirs += ["%s/%s"
|
||||
% (dir, "xenomai-build/usr/realtime/lib")]
|
||||
for dir in elinos_env["xenomai"]:
|
||||
solib_dirs += ["%s/%s" % (dir, "xenomai-build/usr/realtime/lib")]
|
||||
|
||||
if len(solib_dirs) != 0:
|
||||
gdb.execute("set solib-search-path %s" % ":".join(solib_dirs))
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
import os
|
||||
|
||||
if 'ENV_PREFIX' in os.environ:
|
||||
gdb.execute('set sysroot %s' % os.environ['ENV_PREFIX'])
|
||||
if "ENV_PREFIX" in os.environ:
|
||||
gdb.execute("set sysroot %s" % os.environ["ENV_PREFIX"])
|
||||
|
||||
else:
|
||||
print "warning: ENV_PREFIX environment variable missing."
|
||||
|
||||
@@ -45,35 +45,36 @@ import re
|
||||
# }
|
||||
# }
|
||||
|
||||
files_and_tests = dict ()
|
||||
files_and_tests = dict()
|
||||
|
||||
# The relatioships between various states of the same tests that
|
||||
# should be ignored. For example, if the same test PASSes on a
|
||||
# testcase run but KFAILs on another, this test should be considered
|
||||
# racy because a known-failure is... known.
|
||||
|
||||
ignore_relations = { 'PASS' : 'KFAIL' }
|
||||
ignore_relations = {"PASS": "KFAIL"}
|
||||
|
||||
# We are interested in lines that start with '.?(PASS|FAIL)'. In
|
||||
# other words, we don't process errors (maybe we should).
|
||||
|
||||
sum_matcher = re.compile('^(.?(PASS|FAIL)): (.*)$')
|
||||
sum_matcher = re.compile("^(.?(PASS|FAIL)): (.*)$")
|
||||
|
||||
def parse_sum_line (line, dic):
|
||||
|
||||
def parse_sum_line(line, dic):
|
||||
"""Parse a single LINE from a sumfile, and store the results in the
|
||||
dictionary referenced by DIC."""
|
||||
dictionary referenced by DIC."""
|
||||
global sum_matcher
|
||||
|
||||
line = line.rstrip ()
|
||||
m = re.match (sum_matcher, line)
|
||||
line = line.rstrip()
|
||||
m = re.match(sum_matcher, line)
|
||||
if m:
|
||||
result = m.group (1)
|
||||
test_name = m.group (3)
|
||||
result = m.group(1)
|
||||
test_name = m.group(3)
|
||||
# Remove tail parentheses. These are likely to be '(timeout)'
|
||||
# and other extra information that will only confuse us.
|
||||
test_name = re.sub ('(\s+)?\(.*$', '', test_name)
|
||||
if result not in dic.keys ():
|
||||
dic[result] = set ()
|
||||
test_name = re.sub("(\s+)?\(.*$", "", test_name)
|
||||
if result not in dic.keys():
|
||||
dic[result] = set()
|
||||
if test_name in dic[result]:
|
||||
# If the line is already present in the dictionary, then
|
||||
# we include a unique identifier in the end of it, in the
|
||||
@@ -84,35 +85,37 @@ dictionary referenced by DIC."""
|
||||
# in order to identify the racy test.
|
||||
i = 2
|
||||
while True:
|
||||
nname = test_name + ' <<' + str (i) + '>>'
|
||||
nname = test_name + " <<" + str(i) + ">>"
|
||||
if nname not in dic[result]:
|
||||
break
|
||||
i += 1
|
||||
test_name = nname
|
||||
dic[result].add (test_name)
|
||||
dic[result].add(test_name)
|
||||
|
||||
def read_sum_files (files):
|
||||
|
||||
def read_sum_files(files):
|
||||
"""Read the sumfiles (passed as a list in the FILES variable), and
|
||||
process each one, filling the FILES_AND_TESTS global dictionary with
|
||||
information about them. """
|
||||
process each one, filling the FILES_AND_TESTS global dictionary with
|
||||
information about them."""
|
||||
global files_and_tests
|
||||
|
||||
for x in files:
|
||||
with open (x, 'r') as f:
|
||||
files_and_tests[x] = dict ()
|
||||
for line in f.readlines ():
|
||||
parse_sum_line (line, files_and_tests[x])
|
||||
with open(x, "r") as f:
|
||||
files_and_tests[x] = dict()
|
||||
for line in f.readlines():
|
||||
parse_sum_line(line, files_and_tests[x])
|
||||
|
||||
def identify_racy_tests ():
|
||||
|
||||
def identify_racy_tests():
|
||||
"""Identify and print the racy tests. This function basically works
|
||||
on sets, and the idea behind it is simple. It takes all the sets that
|
||||
refer to the same result (for example, all the sets that contain PASS
|
||||
tests), and compare them. If a test is present in all PASS sets, then
|
||||
it is not racy. Otherwise, it is.
|
||||
on sets, and the idea behind it is simple. It takes all the sets that
|
||||
refer to the same result (for example, all the sets that contain PASS
|
||||
tests), and compare them. If a test is present in all PASS sets, then
|
||||
it is not racy. Otherwise, it is.
|
||||
|
||||
This function does that for all sets (PASS, FAIL, KPASS, KFAIL, etc.),
|
||||
and then print a sorted list (without duplicates) of all the tests
|
||||
that were found to be racy."""
|
||||
This function does that for all sets (PASS, FAIL, KPASS, KFAIL, etc.),
|
||||
and then print a sorted list (without duplicates) of all the tests
|
||||
that were found to be racy."""
|
||||
global files_and_tests
|
||||
|
||||
# First, construct two dictionaries that will hold one set of
|
||||
@@ -124,31 +127,31 @@ that were found to be racy."""
|
||||
#
|
||||
# Each set in ALL_TESTS will contain all tests, racy or not, for
|
||||
# that state.
|
||||
nonracy_tests = dict ()
|
||||
all_tests = dict ()
|
||||
nonracy_tests = dict()
|
||||
all_tests = dict()
|
||||
for f in files_and_tests:
|
||||
for state in files_and_tests[f]:
|
||||
try:
|
||||
nonracy_tests[state] &= files_and_tests[f][state].copy ()
|
||||
nonracy_tests[state] &= files_and_tests[f][state].copy()
|
||||
except KeyError:
|
||||
nonracy_tests[state] = files_and_tests[f][state].copy ()
|
||||
nonracy_tests[state] = files_and_tests[f][state].copy()
|
||||
|
||||
try:
|
||||
all_tests[state] |= files_and_tests[f][state].copy ()
|
||||
all_tests[state] |= files_and_tests[f][state].copy()
|
||||
except KeyError:
|
||||
all_tests[state] = files_and_tests[f][state].copy ()
|
||||
all_tests[state] = files_and_tests[f][state].copy()
|
||||
|
||||
# Now, we eliminate the tests that are present in states that need
|
||||
# to be ignored. For example, tests both in the PASS and KFAIL
|
||||
# states should not be considered racy.
|
||||
ignored_tests = set ()
|
||||
for s1, s2 in ignore_relations.iteritems ():
|
||||
ignored_tests = set()
|
||||
for s1, s2 in ignore_relations.iteritems():
|
||||
try:
|
||||
ignored_tests |= (all_tests[s1] & all_tests[s2])
|
||||
ignored_tests |= all_tests[s1] & all_tests[s2]
|
||||
except:
|
||||
continue
|
||||
|
||||
racy_tests = set ()
|
||||
racy_tests = set()
|
||||
for f in files_and_tests:
|
||||
for state in files_and_tests[f]:
|
||||
racy_tests |= files_and_tests[f][state] - nonracy_tests[state]
|
||||
@@ -159,19 +162,20 @@ that were found to be racy."""
|
||||
print "\t\t=== gdb racy tests ===\n"
|
||||
|
||||
# Print each test.
|
||||
for line in sorted (racy_tests):
|
||||
for line in sorted(racy_tests):
|
||||
print line
|
||||
|
||||
# Print the summary.
|
||||
print "\n"
|
||||
print "\t\t=== gdb Summary ===\n"
|
||||
print "# of racy tests:\t\t%d" % len (racy_tests)
|
||||
print "# of racy tests:\t\t%d" % len(racy_tests)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len (sys.argv) < 3:
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 3:
|
||||
# It only makes sense to invoke this program if you pass two
|
||||
# or more files to be analyzed.
|
||||
sys.exit ("Usage: %s [FILE] [FILE] ..." % sys.argv[0])
|
||||
read_sum_files (sys.argv[1:])
|
||||
identify_racy_tests ()
|
||||
exit (0)
|
||||
sys.exit("Usage: %s [FILE] [FILE] ..." % sys.argv[0])
|
||||
read_sum_files(sys.argv[1:])
|
||||
identify_racy_tests()
|
||||
exit(0)
|
||||
|
||||
@@ -22,7 +22,7 @@ class TimeTPrinter:
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
secs = int(self.val['secs'])
|
||||
secs = int(self.val["secs"])
|
||||
return "%s (%d)" % (asctime(gmtime(secs)), secs)
|
||||
|
||||
|
||||
|
||||
@@ -15,21 +15,22 @@
|
||||
|
||||
from perftest import perftest
|
||||
|
||||
class BackTrace (perftest.TestCaseWithBasicMeasurements):
|
||||
|
||||
class BackTrace(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self, depth):
|
||||
super (BackTrace, self).__init__ ("backtrace")
|
||||
super(BackTrace, self).__init__("backtrace")
|
||||
self.depth = depth
|
||||
|
||||
def warm_up(self):
|
||||
# Warm up.
|
||||
gdb.execute ("bt", False, True)
|
||||
gdb.execute ("bt", False, True)
|
||||
gdb.execute("bt", False, True)
|
||||
gdb.execute("bt", False, True)
|
||||
|
||||
def _do_test(self):
|
||||
"""Do backtrace multiple times."""
|
||||
do_test_command = "bt %d" % self.depth
|
||||
for _ in range(1, 15):
|
||||
gdb.execute (do_test_command, False, True)
|
||||
gdb.execute(do_test_command, False, True)
|
||||
|
||||
def execute_test(self):
|
||||
|
||||
@@ -40,8 +41,8 @@ class BackTrace (perftest.TestCaseWithBasicMeasurements):
|
||||
line_size_command = "set dcache line-size %d" % (line_size)
|
||||
size_command = "set dcache size %d" % (4096 * 64 / line_size)
|
||||
# Cache is cleared by changing line-size or size.
|
||||
gdb.execute (line_size_command)
|
||||
gdb.execute (size_command)
|
||||
gdb.execute(line_size_command)
|
||||
gdb.execute(size_command)
|
||||
|
||||
func = lambda: self._do_test()
|
||||
|
||||
|
||||
@@ -15,24 +15,28 @@
|
||||
|
||||
from perftest import perftest
|
||||
|
||||
|
||||
class Disassemble(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self):
|
||||
super (Disassemble, self).__init__ ("disassemble")
|
||||
super(Disassemble, self).__init__("disassemble")
|
||||
|
||||
def warm_up(self):
|
||||
do_test_command = "disassemble ada_evaluate_subexp"
|
||||
gdb.execute (do_test_command, False, True)
|
||||
gdb.execute(do_test_command, False, True)
|
||||
|
||||
def _do_test(self, c):
|
||||
for func in ["evaluate_subexp_standard", "handle_inferior_event", "c_parse_internal"]:
|
||||
for func in [
|
||||
"evaluate_subexp_standard",
|
||||
"handle_inferior_event",
|
||||
"c_parse_internal",
|
||||
]:
|
||||
do_test_command = "disassemble %s" % func
|
||||
for _ in range(c+1):
|
||||
gdb.execute (do_test_command, False, True)
|
||||
for _ in range(c + 1):
|
||||
gdb.execute(do_test_command, False, True)
|
||||
|
||||
def execute_test(self):
|
||||
for i in range(3):
|
||||
# Flush code cache.
|
||||
gdb.execute("set code-cache off");
|
||||
gdb.execute("set code-cache on");
|
||||
gdb.execute("set code-cache off")
|
||||
gdb.execute("set code-cache on")
|
||||
self.measure.measure(lambda: self._do_test(i), i)
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ from perftest import perftest
|
||||
from perftest import measure
|
||||
from perftest import utils
|
||||
|
||||
|
||||
class NullLookup(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self, name, run_names, binfile):
|
||||
# We want to measure time in this test.
|
||||
@@ -33,8 +34,7 @@ class NullLookup(perftest.TestCaseWithBasicMeasurements):
|
||||
|
||||
def execute_test(self):
|
||||
for run in self.run_names:
|
||||
this_run_binfile = "%s-%s" % (self.binfile,
|
||||
utils.convert_spaces(run))
|
||||
this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||
utils.select_file(this_run_binfile)
|
||||
utils.runto_main()
|
||||
utils.safe_execute("mt expand-symtabs")
|
||||
|
||||
@@ -21,6 +21,7 @@ from perftest import perftest
|
||||
from perftest import measure
|
||||
from perftest import utils
|
||||
|
||||
|
||||
class PervasiveTypedef(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self, name, run_names, binfile):
|
||||
# We want to measure time in this test.
|
||||
@@ -37,8 +38,7 @@ class PervasiveTypedef(perftest.TestCaseWithBasicMeasurements):
|
||||
|
||||
def execute_test(self):
|
||||
for run in self.run_names:
|
||||
self.this_run_binfile = "%s-%s" % (self.binfile,
|
||||
utils.convert_spaces(run))
|
||||
self.this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||
iteration = 5
|
||||
while iteration > 0:
|
||||
self.measure.measure(self.func, run)
|
||||
|
||||
@@ -29,6 +29,7 @@ from perftest import perftest
|
||||
from perftest import measure
|
||||
from perftest import utils
|
||||
|
||||
|
||||
class PrintCerr(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self, name, run_names, binfile):
|
||||
super(PrintCerr, self).__init__(name)
|
||||
@@ -40,8 +41,7 @@ class PrintCerr(perftest.TestCaseWithBasicMeasurements):
|
||||
|
||||
def execute_test(self):
|
||||
for run in self.run_names:
|
||||
this_run_binfile = "%s-%s" % (self.binfile,
|
||||
utils.convert_spaces(run))
|
||||
this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||
utils.select_file(this_run_binfile)
|
||||
utils.runto_main()
|
||||
iteration = 5
|
||||
|
||||
@@ -23,6 +23,7 @@ from perftest import perftest
|
||||
from perftest import measure
|
||||
from perftest import utils
|
||||
|
||||
|
||||
class GmonsterPtypeString(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self, name, run_names, binfile):
|
||||
super(GmonsterPtypeString, self).__init__(name)
|
||||
@@ -34,8 +35,7 @@ class GmonsterPtypeString(perftest.TestCaseWithBasicMeasurements):
|
||||
|
||||
def execute_test(self):
|
||||
for run in self.run_names:
|
||||
this_run_binfile = "%s-%s" % (self.binfile,
|
||||
utils.convert_spaces(run))
|
||||
this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||
utils.select_file(this_run_binfile)
|
||||
utils.runto_main()
|
||||
utils.safe_execute("mt expand-symtabs")
|
||||
|
||||
@@ -19,6 +19,7 @@ from perftest import perftest
|
||||
from perftest import measure
|
||||
from perftest import utils
|
||||
|
||||
|
||||
class GmonsterRuntoMain(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self, name, run_names, binfile):
|
||||
super(GmonsterRuntoMain, self).__init__(name)
|
||||
@@ -30,8 +31,7 @@ class GmonsterRuntoMain(perftest.TestCaseWithBasicMeasurements):
|
||||
|
||||
def execute_test(self):
|
||||
for run in self.run_names:
|
||||
this_run_binfile = "%s-%s" % (self.binfile,
|
||||
utils.convert_spaces(run))
|
||||
this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||
utils.select_file(this_run_binfile)
|
||||
iteration = 5
|
||||
while iteration > 0:
|
||||
|
||||
@@ -19,6 +19,7 @@ from perftest import perftest
|
||||
from perftest import measure
|
||||
from perftest import utils
|
||||
|
||||
|
||||
class GmonsterSelectFile(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self, name, run_names, binfile):
|
||||
super(GmonsterSelectFile, self).__init__(name)
|
||||
@@ -34,8 +35,7 @@ class GmonsterSelectFile(perftest.TestCaseWithBasicMeasurements):
|
||||
|
||||
def execute_test(self):
|
||||
for run in self.run_names:
|
||||
this_run_binfile = "%s-%s" % (self.binfile,
|
||||
utils.convert_spaces(run))
|
||||
this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||
iteration = 5
|
||||
while iteration > 0:
|
||||
func = lambda: self._doit(this_run_binfile)
|
||||
|
||||
@@ -17,6 +17,7 @@ import time
|
||||
import os
|
||||
import gc
|
||||
|
||||
|
||||
class Measure(object):
|
||||
"""A class that measure and collect the interesting data for a given testcase.
|
||||
|
||||
@@ -55,6 +56,7 @@ class Measure(object):
|
||||
for m in self.measurements:
|
||||
m.report(reporter, name)
|
||||
|
||||
|
||||
class Measurement(object):
|
||||
"""A measurement for a certain aspect."""
|
||||
|
||||
@@ -63,7 +65,7 @@ class Measurement(object):
|
||||
|
||||
Attribute result is the TestResult associated with measurement.
|
||||
"""
|
||||
self.name = name;
|
||||
self.name = name
|
||||
self.result = result
|
||||
|
||||
def start(self, id):
|
||||
@@ -82,8 +84,10 @@ class Measurement(object):
|
||||
"""Report the measured data by argument reporter."""
|
||||
self.result.report(reporter, name + " " + self.name)
|
||||
|
||||
|
||||
class MeasurementCpuTime(Measurement):
|
||||
"""Measurement on CPU time."""
|
||||
|
||||
# On UNIX, time.clock() measures the amount of CPU time that has
|
||||
# been used by the current process. On Windows it will measure
|
||||
# wall-clock seconds elapsed since the first call to the function.
|
||||
@@ -98,11 +102,12 @@ class MeasurementCpuTime(Measurement):
|
||||
self.start_time = time.clock()
|
||||
|
||||
def stop(self, id):
|
||||
if os.name == 'nt':
|
||||
if os.name == "nt":
|
||||
cpu_time = 0
|
||||
else:
|
||||
cpu_time = time.clock() - self.start_time
|
||||
self.result.record (id, cpu_time)
|
||||
self.result.record(id, cpu_time)
|
||||
|
||||
|
||||
class MeasurementWallTime(Measurement):
|
||||
"""Measurement on Wall time."""
|
||||
@@ -116,7 +121,8 @@ class MeasurementWallTime(Measurement):
|
||||
|
||||
def stop(self, id):
|
||||
wall_time = time.time() - self.start_time
|
||||
self.result.record (id, wall_time)
|
||||
self.result.record(id, wall_time)
|
||||
|
||||
|
||||
class MeasurementVmSize(Measurement):
|
||||
"""Measurement on memory usage represented by VmSize."""
|
||||
@@ -143,4 +149,4 @@ class MeasurementVmSize(Measurement):
|
||||
|
||||
def stop(self, id):
|
||||
memory_used = self._compute_process_memory_usage("VmSize:")
|
||||
self.result.record (id, memory_used)
|
||||
self.result.record(id, memory_used)
|
||||
|
||||
@@ -65,12 +65,15 @@ class TestCase(object):
|
||||
self.execute_test()
|
||||
self.measure.report(reporter.TextReporter(append), self.name)
|
||||
|
||||
|
||||
class TestCaseWithBasicMeasurements(TestCase):
|
||||
"""Test case measuring CPU time, wall time and memory usage."""
|
||||
|
||||
def __init__(self, name):
|
||||
result_factory = testresult.SingleStatisticResultFactory()
|
||||
measurements = [MeasurementCpuTime(result_factory.create_result()),
|
||||
MeasurementWallTime(result_factory.create_result()),
|
||||
MeasurementVmSize(result_factory.create_result())]
|
||||
super (TestCaseWithBasicMeasurements, self).__init__ (name, Measure(measurements))
|
||||
measurements = [
|
||||
MeasurementCpuTime(result_factory.create_result()),
|
||||
MeasurementWallTime(result_factory.create_result()),
|
||||
MeasurementVmSize(result_factory.create_result()),
|
||||
]
|
||||
super(TestCaseWithBasicMeasurements, self).__init__(name, Measure(measurements))
|
||||
|
||||
@@ -57,29 +57,30 @@ class TextReporter(Reporter):
|
||||
"""Report results in a plain text file 'perftest.log'."""
|
||||
|
||||
def __init__(self, append):
|
||||
super (TextReporter, self).__init__(Reporter(append))
|
||||
super(TextReporter, self).__init__(Reporter(append))
|
||||
self.txt_sum = None
|
||||
self.txt_log = None
|
||||
|
||||
def report(self, test_name, measurement_name, data_points):
|
||||
if len(data_points) == 0:
|
||||
self.txt_sum.write("%s %s *no data recorded*\n" % (
|
||||
test_name, measurement_name))
|
||||
self.txt_sum.write(
|
||||
"%s %s *no data recorded*\n" % (test_name, measurement_name)
|
||||
)
|
||||
return
|
||||
average = sum(data_points) / len(data_points)
|
||||
data_min = min(data_points)
|
||||
data_max = max(data_points)
|
||||
self.txt_sum.write("%s %s %s\n" % (
|
||||
test_name, measurement_name, average))
|
||||
self.txt_log.write("%s %s %s, min %s, max %s, data %s\n" % (
|
||||
test_name, measurement_name, average, data_min, data_max,
|
||||
data_points))
|
||||
self.txt_sum.write("%s %s %s\n" % (test_name, measurement_name, average))
|
||||
self.txt_log.write(
|
||||
"%s %s %s, min %s, max %s, data %s\n"
|
||||
% (test_name, measurement_name, average, data_min, data_max, data_points)
|
||||
)
|
||||
|
||||
def start(self):
|
||||
mode = "a+" if self.append else "w"
|
||||
self.txt_sum = open (SUM_FILE_NAME, mode);
|
||||
self.txt_log = open (LOG_FILE_NAME, mode);
|
||||
self.txt_sum = open(SUM_FILE_NAME, mode)
|
||||
self.txt_log = open(LOG_FILE_NAME, mode)
|
||||
|
||||
def end(self):
|
||||
self.txt_sum.close ()
|
||||
self.txt_log.close ()
|
||||
self.txt_sum.close()
|
||||
self.txt_log.close()
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class TestResult(object):
|
||||
"""Base class to record and report test results.
|
||||
|
||||
@@ -27,12 +28,13 @@ class TestResult(object):
|
||||
"""Report the test results by reporter."""
|
||||
raise NotImplementedError("Abstract Method:report.")
|
||||
|
||||
|
||||
class SingleStatisticTestResult(TestResult):
|
||||
"""Test results for the test case with a single statistic."""
|
||||
|
||||
def __init__(self):
|
||||
super (SingleStatisticTestResult, self).__init__ ()
|
||||
self.results = dict ()
|
||||
super(SingleStatisticTestResult, self).__init__()
|
||||
self.results = dict()
|
||||
|
||||
def record(self, parameter, result):
|
||||
if parameter in self.results:
|
||||
@@ -46,6 +48,7 @@ class SingleStatisticTestResult(TestResult):
|
||||
reporter.report(name, key, self.results[key])
|
||||
reporter.end()
|
||||
|
||||
|
||||
class ResultFactory(object):
|
||||
"""A factory to create an instance of TestResult."""
|
||||
|
||||
@@ -53,6 +56,7 @@ class ResultFactory(object):
|
||||
"""Create an instance of TestResult."""
|
||||
raise NotImplementedError("Abstract Method:create_result.")
|
||||
|
||||
|
||||
class SingleStatisticResultFactory(ResultFactory):
|
||||
"""A factory to create an instance of SingleStatisticTestResult."""
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
import gdb
|
||||
|
||||
|
||||
def safe_execute(command):
|
||||
"""Execute command, ignoring any gdb errors."""
|
||||
result = None
|
||||
@@ -37,7 +38,7 @@ def select_file(file_name):
|
||||
"""
|
||||
safe_execute("set confirm off")
|
||||
safe_execute("kill")
|
||||
print ("Selecting file %s" % (file_name))
|
||||
print("Selecting file %s" % (file_name))
|
||||
if file_name is None:
|
||||
gdb.execute("file")
|
||||
else:
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
|
||||
from perftest import perftest
|
||||
|
||||
class SingleStep (perftest.TestCaseWithBasicMeasurements):
|
||||
|
||||
class SingleStep(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self, step):
|
||||
super (SingleStep, self).__init__ ("single-step")
|
||||
super(SingleStep, self).__init__("single-step")
|
||||
self.step = step
|
||||
|
||||
def warm_up(self):
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
|
||||
from perftest import perftest
|
||||
|
||||
class SkipCommand (perftest.TestCaseWithBasicMeasurements):
|
||||
|
||||
class SkipCommand(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self, name, step):
|
||||
super (SkipCommand, self).__init__ (name)
|
||||
super(SkipCommand, self).__init__(name)
|
||||
self.step = step
|
||||
|
||||
def warm_up(self):
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
from perftest import perftest
|
||||
|
||||
|
||||
class SkipPrologue(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self, count):
|
||||
super(SkipPrologue, self).__init__("skip-prologue")
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
from perftest import perftest
|
||||
from perftest import measure
|
||||
|
||||
|
||||
class SolibLoadUnload1(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self, solib_count, measure_load):
|
||||
if measure_load:
|
||||
@@ -26,7 +27,7 @@ class SolibLoadUnload1(perftest.TestCaseWithBasicMeasurements):
|
||||
else:
|
||||
name = "solib_unload"
|
||||
# We want to measure time in this test.
|
||||
super (SolibLoadUnload1, self).__init__ (name)
|
||||
super(SolibLoadUnload1, self).__init__(name)
|
||||
self.solib_count = solib_count
|
||||
self.measure_load = measure_load
|
||||
|
||||
@@ -38,35 +39,36 @@ class SolibLoadUnload1(perftest.TestCaseWithBasicMeasurements):
|
||||
|
||||
def execute_test(self):
|
||||
num = self.solib_count
|
||||
iteration = 5;
|
||||
iteration = 5
|
||||
|
||||
while num > 0 and iteration > 0:
|
||||
# Do inferior calls to do_test_load and do_test_unload in pairs,
|
||||
# but measure differently.
|
||||
if self.measure_load:
|
||||
do_test_load = "call do_test_load (%d)" % num
|
||||
func = lambda: gdb.execute (do_test_load)
|
||||
func = lambda: gdb.execute(do_test_load)
|
||||
|
||||
self.measure.measure(func, num)
|
||||
|
||||
do_test_unload = "call do_test_unload (%d)" % num
|
||||
gdb.execute (do_test_unload)
|
||||
gdb.execute(do_test_unload)
|
||||
|
||||
else:
|
||||
do_test_load = "call do_test_load (%d)" % num
|
||||
gdb.execute (do_test_load)
|
||||
gdb.execute(do_test_load)
|
||||
|
||||
do_test_unload = "call do_test_unload (%d)" % num
|
||||
func = lambda: gdb.execute (do_test_unload)
|
||||
func = lambda: gdb.execute(do_test_unload)
|
||||
|
||||
self.measure.measure(func, num)
|
||||
|
||||
num = num / 2
|
||||
iteration -= 1
|
||||
|
||||
|
||||
class SolibLoadUnload(object):
|
||||
def __init__(self, solib_count):
|
||||
self.solib_count = solib_count;
|
||||
self.solib_count = solib_count
|
||||
|
||||
def run(self):
|
||||
SolibLoadUnload1(self.solib_count, True).run()
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
|
||||
from perftest import perftest
|
||||
|
||||
class TemplateBreakpoints (perftest.TestCaseWithBasicMeasurements):
|
||||
|
||||
class TemplateBreakpoints(perftest.TestCaseWithBasicMeasurements):
|
||||
def __init__(self):
|
||||
super (TemplateBreakpoints, self).__init__ ("template-breakpoints")
|
||||
super(TemplateBreakpoints, self).__init__("template-breakpoints")
|
||||
|
||||
def warm_up(self):
|
||||
for _ in range(0, 2):
|
||||
|
||||
@@ -18,20 +18,18 @@
|
||||
|
||||
import re
|
||||
|
||||
print ("Entering f1.o auto-load script")
|
||||
print("Entering f1.o auto-load script")
|
||||
|
||||
print ("Current objfile is: %s"
|
||||
% gdb.current_objfile ().filename)
|
||||
print("Current objfile is: %s" % gdb.current_objfile().filename)
|
||||
|
||||
print ("Chain loading f2.o...")
|
||||
print("Chain loading f2.o...")
|
||||
|
||||
filename = gdb.current_objfile ().filename
|
||||
filename = re.sub (r"-f1.o$", "-f2.o", filename)
|
||||
r2 = gdb.lookup_global_symbol ('region_2').value ()
|
||||
gdb.execute ("add-symbol-file %s 0x%x" % (filename, r2))
|
||||
filename = gdb.current_objfile().filename
|
||||
filename = re.sub(r"-f1.o$", "-f2.o", filename)
|
||||
r2 = gdb.lookup_global_symbol("region_2").value()
|
||||
gdb.execute("add-symbol-file %s 0x%x" % (filename, r2))
|
||||
|
||||
print ("After loading f2.o...")
|
||||
print ("Current objfile is: %s"
|
||||
% gdb.current_objfile ().filename)
|
||||
print("After loading f2.o...")
|
||||
print("Current objfile is: %s" % gdb.current_objfile().filename)
|
||||
|
||||
print ("Leaving f1.o auto-load script")
|
||||
print("Leaving f1.o auto-load script")
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
# This script is auto-loaded when the py-auto-load-chaining-f2.o
|
||||
# object is loaded.
|
||||
|
||||
print ("Entering f2.o auto-load script")
|
||||
print("Entering f2.o auto-load script")
|
||||
|
||||
print ("Current objfile is: %s"
|
||||
% gdb.current_objfile ().filename)
|
||||
print("Current objfile is: %s" % gdb.current_objfile().filename)
|
||||
|
||||
print ("Leaving f2.o auto-load script")
|
||||
print("Leaving f2.o auto-load script")
|
||||
|
||||
@@ -29,18 +29,18 @@ class BadChildrenContainerPrinter1(object):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return 'container %s with %d elements' % (self.val['name'], self.val['len'])
|
||||
return "container %s with %d elements" % (self.val["name"], self.val["len"])
|
||||
|
||||
@staticmethod
|
||||
def _bad_iterator(pointer, len):
|
||||
start = pointer
|
||||
end = pointer + len
|
||||
while pointer != end:
|
||||
yield 'intentional violation of children iterator protocol'
|
||||
yield "intentional violation of children iterator protocol"
|
||||
pointer += 1
|
||||
|
||||
def children(self):
|
||||
return self._bad_iterator(self.val['elements'], self.val['len'])
|
||||
return self._bad_iterator(self.val["elements"], self.val["len"])
|
||||
|
||||
|
||||
class BadChildrenContainerPrinter2(object):
|
||||
@@ -50,7 +50,7 @@ class BadChildrenContainerPrinter2(object):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return 'container %s with %d elements' % (self.val['name'], self.val['len'])
|
||||
return "container %s with %d elements" % (self.val["name"], self.val["len"])
|
||||
|
||||
@staticmethod
|
||||
def _bad_iterator(pointer, len):
|
||||
@@ -58,20 +58,18 @@ class BadChildrenContainerPrinter2(object):
|
||||
end = pointer + len
|
||||
while pointer != end:
|
||||
# The first argument is supposed to be a string.
|
||||
yield (42, 'intentional violation of children iterator protocol')
|
||||
yield (42, "intentional violation of children iterator protocol")
|
||||
pointer += 1
|
||||
|
||||
def children(self):
|
||||
return self._bad_iterator(self.val['elements'], self.val['len'])
|
||||
return self._bad_iterator(self.val["elements"], self.val["len"])
|
||||
|
||||
|
||||
def build_pretty_printer():
|
||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("bad-printers")
|
||||
|
||||
pp.add_printer('container1', '^container$',
|
||||
BadChildrenContainerPrinter1)
|
||||
pp.add_printer('container2', '^container$',
|
||||
BadChildrenContainerPrinter2)
|
||||
pp.add_printer("container1", "^container$", BadChildrenContainerPrinter1)
|
||||
pp.add_printer("container2", "^container$", BadChildrenContainerPrinter2)
|
||||
|
||||
return pp
|
||||
|
||||
|
||||
@@ -18,13 +18,13 @@ import gdb
|
||||
|
||||
class MyBP(gdb.Breakpoint):
|
||||
def stop(self):
|
||||
print('MyBP.stop was invoked!')
|
||||
print("MyBP.stop was invoked!")
|
||||
# Don't make this breakpoint stop
|
||||
return False
|
||||
|
||||
|
||||
try:
|
||||
bp = MyBP('does_not_exist', gdb.BP_WATCHPOINT)
|
||||
bp = MyBP("does_not_exist", gdb.BP_WATCHPOINT)
|
||||
except RuntimeError:
|
||||
pass
|
||||
else:
|
||||
|
||||
@@ -17,123 +17,190 @@
|
||||
|
||||
import gdb
|
||||
|
||||
class CompleteFileInit(gdb.Command):
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self,'completefileinit',gdb.COMMAND_USER,gdb.COMPLETE_FILENAME)
|
||||
|
||||
def invoke(self,argument,from_tty):
|
||||
raise gdb.GdbError('not implemented')
|
||||
class CompleteFileInit(gdb.Command):
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(
|
||||
self, "completefileinit", gdb.COMMAND_USER, gdb.COMPLETE_FILENAME
|
||||
)
|
||||
|
||||
def invoke(self, argument, from_tty):
|
||||
raise gdb.GdbError("not implemented")
|
||||
|
||||
|
||||
class CompleteFileMethod(gdb.Command):
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self,'completefilemethod',gdb.COMMAND_USER)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "completefilemethod", gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self,argument,from_tty):
|
||||
raise gdb.GdbError('not implemented')
|
||||
def invoke(self, argument, from_tty):
|
||||
raise gdb.GdbError("not implemented")
|
||||
|
||||
def complete(self, text, word):
|
||||
return gdb.COMPLETE_FILENAME
|
||||
|
||||
def complete(self,text,word):
|
||||
return gdb.COMPLETE_FILENAME
|
||||
|
||||
class CompleteFileCommandCond(gdb.Command):
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self,'completefilecommandcond',gdb.COMMAND_USER)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "completefilecommandcond", gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self,argument,from_tty):
|
||||
raise gdb.GdbError('not implemented')
|
||||
def invoke(self, argument, from_tty):
|
||||
raise gdb.GdbError("not implemented")
|
||||
|
||||
def complete(self, text, word):
|
||||
# This is a test made to know if the command
|
||||
# completion still works fine. When the user asks to
|
||||
# complete something like "completefilecommandcond
|
||||
# /path/to/py-completion-t", it should not complete to
|
||||
# "/path/to/py-completion-test/", but instead just
|
||||
# wait for input.
|
||||
if "py-completion-t" in text:
|
||||
return gdb.COMPLETE_COMMAND
|
||||
else:
|
||||
return gdb.COMPLETE_FILENAME
|
||||
|
||||
def complete(self,text,word):
|
||||
# This is a test made to know if the command
|
||||
# completion still works fine. When the user asks to
|
||||
# complete something like "completefilecommandcond
|
||||
# /path/to/py-completion-t", it should not complete to
|
||||
# "/path/to/py-completion-test/", but instead just
|
||||
# wait for input.
|
||||
if "py-completion-t" in text:
|
||||
return gdb.COMPLETE_COMMAND
|
||||
else:
|
||||
return gdb.COMPLETE_FILENAME
|
||||
|
||||
class CompleteLimit1(gdb.Command):
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self,'completelimit1',gdb.COMMAND_USER)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "completelimit1", gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self,argument,from_tty):
|
||||
raise gdb.GdbError('not implemented')
|
||||
def invoke(self, argument, from_tty):
|
||||
raise gdb.GdbError("not implemented")
|
||||
|
||||
def complete(self, text, word):
|
||||
return ["cl11", "cl12", "cl13"]
|
||||
|
||||
def complete(self,text,word):
|
||||
return ["cl11", "cl12", "cl13"]
|
||||
|
||||
class CompleteLimit2(gdb.Command):
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self,'completelimit2',
|
||||
gdb.COMMAND_USER)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "completelimit2", gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self,argument,from_tty):
|
||||
raise gdb.GdbError('not implemented')
|
||||
def invoke(self, argument, from_tty):
|
||||
raise gdb.GdbError("not implemented")
|
||||
|
||||
def complete(self, text, word):
|
||||
return [
|
||||
"cl21",
|
||||
"cl23",
|
||||
"cl25",
|
||||
"cl27",
|
||||
"cl29",
|
||||
"cl22",
|
||||
"cl24",
|
||||
"cl26",
|
||||
"cl28",
|
||||
"cl210",
|
||||
]
|
||||
|
||||
def complete(self,text,word):
|
||||
return ["cl21", "cl23", "cl25", "cl27", "cl29",
|
||||
"cl22", "cl24", "cl26", "cl28", "cl210"]
|
||||
|
||||
class CompleteLimit3(gdb.Command):
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self,'completelimit3',
|
||||
gdb.COMMAND_USER)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "completelimit3", gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self,argument,from_tty):
|
||||
raise gdb.GdbError('not implemented')
|
||||
def invoke(self, argument, from_tty):
|
||||
raise gdb.GdbError("not implemented")
|
||||
|
||||
def complete(self, text, word):
|
||||
return [
|
||||
"cl31",
|
||||
"cl33",
|
||||
"cl35",
|
||||
"cl37",
|
||||
"cl39",
|
||||
"cl32",
|
||||
"cl34",
|
||||
"cl36",
|
||||
"cl38",
|
||||
"cl310",
|
||||
]
|
||||
|
||||
def complete(self,text,word):
|
||||
return ["cl31", "cl33", "cl35", "cl37", "cl39",
|
||||
"cl32", "cl34", "cl36", "cl38", "cl310"]
|
||||
|
||||
class CompleteLimit4(gdb.Command):
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self,'completelimit4',
|
||||
gdb.COMMAND_USER)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "completelimit4", gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self,argument,from_tty):
|
||||
raise gdb.GdbError('not implemented')
|
||||
def invoke(self, argument, from_tty):
|
||||
raise gdb.GdbError("not implemented")
|
||||
|
||||
def complete(self, text, word):
|
||||
return [
|
||||
"cl41",
|
||||
"cl43",
|
||||
"cl45",
|
||||
"cl47",
|
||||
"cl49",
|
||||
"cl42",
|
||||
"cl44",
|
||||
"cl46",
|
||||
"cl48",
|
||||
"cl410",
|
||||
]
|
||||
|
||||
def complete(self,text,word):
|
||||
return ["cl41", "cl43", "cl45", "cl47", "cl49",
|
||||
"cl42", "cl44", "cl46", "cl48", "cl410"]
|
||||
|
||||
class CompleteLimit5(gdb.Command):
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self,'completelimit5',
|
||||
gdb.COMMAND_USER)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "completelimit5", gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self,argument,from_tty):
|
||||
raise gdb.GdbError('not implemented')
|
||||
def invoke(self, argument, from_tty):
|
||||
raise gdb.GdbError("not implemented")
|
||||
|
||||
def complete(self, text, word):
|
||||
return [
|
||||
"cl51",
|
||||
"cl53",
|
||||
"cl55",
|
||||
"cl57",
|
||||
"cl59",
|
||||
"cl52",
|
||||
"cl54",
|
||||
"cl56",
|
||||
"cl58",
|
||||
"cl510",
|
||||
]
|
||||
|
||||
def complete(self,text,word):
|
||||
return ["cl51", "cl53", "cl55", "cl57", "cl59",
|
||||
"cl52", "cl54", "cl56", "cl58", "cl510"]
|
||||
|
||||
class CompleteLimit6(gdb.Command):
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self,'completelimit6',
|
||||
gdb.COMMAND_USER)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "completelimit6", gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self,argument,from_tty):
|
||||
raise gdb.GdbError('not implemented')
|
||||
def invoke(self, argument, from_tty):
|
||||
raise gdb.GdbError("not implemented")
|
||||
|
||||
def complete(self, text, word):
|
||||
return [
|
||||
"cl61",
|
||||
"cl63",
|
||||
"cl65",
|
||||
"cl67",
|
||||
"cl69",
|
||||
"cl62",
|
||||
"cl64",
|
||||
"cl66",
|
||||
"cl68",
|
||||
"cl610",
|
||||
]
|
||||
|
||||
def complete(self,text,word):
|
||||
return ["cl61", "cl63", "cl65", "cl67", "cl69",
|
||||
"cl62", "cl64", "cl66", "cl68", "cl610"]
|
||||
|
||||
class CompleteLimit7(gdb.Command):
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self,'completelimit7',
|
||||
gdb.COMMAND_USER)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "completelimit7", gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self,argument,from_tty):
|
||||
raise gdb.GdbError('not implemented')
|
||||
def invoke(self, argument, from_tty):
|
||||
raise gdb.GdbError("not implemented")
|
||||
|
||||
def complete(self, text, word):
|
||||
return [
|
||||
"cl71",
|
||||
"cl73",
|
||||
"cl75",
|
||||
"cl77",
|
||||
"cl79",
|
||||
"cl72",
|
||||
"cl74",
|
||||
"cl76",
|
||||
"cl78",
|
||||
"cl710",
|
||||
]
|
||||
|
||||
def complete(self,text,word):
|
||||
return ["cl71", "cl73", "cl75", "cl77", "cl79",
|
||||
"cl72", "cl74", "cl76", "cl78", "cl710"]
|
||||
|
||||
CompleteFileInit()
|
||||
CompleteFileMethod()
|
||||
|
||||
@@ -15,11 +15,15 @@
|
||||
|
||||
import gdb
|
||||
|
||||
|
||||
class ClassName(gdb.Command):
|
||||
'a'
|
||||
"a"
|
||||
|
||||
def __init__(self):
|
||||
gdb.Command.__init__ (self, "ClassName", gdb.COMMAND_DATA, prefix=True)
|
||||
gdb.Command.__init__(self, "ClassName", gdb.COMMAND_DATA, prefix=True)
|
||||
|
||||
def invoke(self, args, from_tty):
|
||||
print
|
||||
|
||||
|
||||
ClassName()
|
||||
|
||||
@@ -17,102 +17,114 @@
|
||||
# printers.
|
||||
import gdb
|
||||
|
||||
def signal_stop_handler (event):
|
||||
if (isinstance (event, gdb.StopEvent)):
|
||||
print ("event type: stop")
|
||||
if (isinstance (event, gdb.SignalEvent)):
|
||||
print ("stop reason: signal")
|
||||
print ("stop signal: %s" % (event.stop_signal))
|
||||
if ( event.inferior_thread is not None) :
|
||||
print ("thread num: %s" % (event.inferior_thread.num))
|
||||
|
||||
def breakpoint_stop_handler (event):
|
||||
if (isinstance (event, gdb.StopEvent)):
|
||||
print ("event type: stop")
|
||||
if (isinstance (event, gdb.BreakpointEvent)):
|
||||
print ("stop reason: breakpoint")
|
||||
print ("first breakpoint number: %s" % (event.breakpoint.number))
|
||||
def signal_stop_handler(event):
|
||||
if isinstance(event, gdb.StopEvent):
|
||||
print("event type: stop")
|
||||
if isinstance(event, gdb.SignalEvent):
|
||||
print("stop reason: signal")
|
||||
print("stop signal: %s" % (event.stop_signal))
|
||||
if event.inferior_thread is not None:
|
||||
print("thread num: %s" % (event.inferior_thread.num))
|
||||
|
||||
|
||||
def breakpoint_stop_handler(event):
|
||||
if isinstance(event, gdb.StopEvent):
|
||||
print("event type: stop")
|
||||
if isinstance(event, gdb.BreakpointEvent):
|
||||
print("stop reason: breakpoint")
|
||||
print("first breakpoint number: %s" % (event.breakpoint.number))
|
||||
for bp in event.breakpoints:
|
||||
print ("breakpoint number: %s" % (bp.number))
|
||||
if ( event.inferior_thread is not None) :
|
||||
print ("thread num: %s" % (event.inferior_thread.num))
|
||||
print("breakpoint number: %s" % (bp.number))
|
||||
if event.inferior_thread is not None:
|
||||
print("thread num: %s" % (event.inferior_thread.num))
|
||||
else:
|
||||
print ("all threads stopped")
|
||||
print("all threads stopped")
|
||||
|
||||
def exit_handler (event):
|
||||
assert (isinstance (event, gdb.ExitedEvent))
|
||||
print ("event type: exit")
|
||||
print ("exit code: %d" % (event.exit_code))
|
||||
print ("exit inf: %d" % (event.inferior.num))
|
||||
print ("dir ok: %s" % str('exit_code' in dir(event)))
|
||||
|
||||
def continue_handler (event):
|
||||
assert (isinstance (event, gdb.ContinueEvent))
|
||||
print ("event type: continue")
|
||||
if ( event.inferior_thread is not None) :
|
||||
print ("thread num: %s" % (event.inferior_thread.num))
|
||||
def exit_handler(event):
|
||||
assert isinstance(event, gdb.ExitedEvent)
|
||||
print("event type: exit")
|
||||
print("exit code: %d" % (event.exit_code))
|
||||
print("exit inf: %d" % (event.inferior.num))
|
||||
print("dir ok: %s" % str("exit_code" in dir(event)))
|
||||
|
||||
def new_objfile_handler (event):
|
||||
assert (isinstance (event, gdb.NewObjFileEvent))
|
||||
print ("event type: new_objfile")
|
||||
print ("new objfile name: %s" % (event.new_objfile.filename))
|
||||
|
||||
def clear_objfiles_handler (event):
|
||||
assert (isinstance (event, gdb.ClearObjFilesEvent))
|
||||
print ("event type: clear_objfiles")
|
||||
print ("progspace: %s" % (event.progspace.filename))
|
||||
def continue_handler(event):
|
||||
assert isinstance(event, gdb.ContinueEvent)
|
||||
print("event type: continue")
|
||||
if event.inferior_thread is not None:
|
||||
print("thread num: %s" % (event.inferior_thread.num))
|
||||
|
||||
def inferior_call_handler (event):
|
||||
if (isinstance (event, gdb.InferiorCallPreEvent)):
|
||||
print ("event type: pre-call")
|
||||
elif (isinstance (event, gdb.InferiorCallPostEvent)):
|
||||
print ("event type: post-call")
|
||||
|
||||
def new_objfile_handler(event):
|
||||
assert isinstance(event, gdb.NewObjFileEvent)
|
||||
print("event type: new_objfile")
|
||||
print("new objfile name: %s" % (event.new_objfile.filename))
|
||||
|
||||
|
||||
def clear_objfiles_handler(event):
|
||||
assert isinstance(event, gdb.ClearObjFilesEvent)
|
||||
print("event type: clear_objfiles")
|
||||
print("progspace: %s" % (event.progspace.filename))
|
||||
|
||||
|
||||
def inferior_call_handler(event):
|
||||
if isinstance(event, gdb.InferiorCallPreEvent):
|
||||
print("event type: pre-call")
|
||||
elif isinstance(event, gdb.InferiorCallPostEvent):
|
||||
print("event type: post-call")
|
||||
else:
|
||||
assert False
|
||||
print ("ptid: %s" % (event.ptid,))
|
||||
print ("address: 0x%x" % (event.address))
|
||||
|
||||
def register_changed_handler (event):
|
||||
assert (isinstance (event, gdb.RegisterChangedEvent))
|
||||
print ("event type: register-changed")
|
||||
assert (isinstance (event.frame, gdb.Frame))
|
||||
print ("frame: %s" % (event.frame))
|
||||
print ("num: %s" % (event.regnum))
|
||||
|
||||
def memory_changed_handler (event):
|
||||
assert (isinstance (event, gdb.MemoryChangedEvent))
|
||||
print ("event type: memory-changed")
|
||||
print ("address: %s" % (event.address))
|
||||
print ("length: %s" % (event.length))
|
||||
print("ptid: %s" % (event.ptid,))
|
||||
print("address: 0x%x" % (event.address))
|
||||
|
||||
|
||||
class test_events (gdb.Command):
|
||||
def register_changed_handler(event):
|
||||
assert isinstance(event, gdb.RegisterChangedEvent)
|
||||
print("event type: register-changed")
|
||||
assert isinstance(event.frame, gdb.Frame)
|
||||
print("frame: %s" % (event.frame))
|
||||
print("num: %s" % (event.regnum))
|
||||
|
||||
|
||||
def memory_changed_handler(event):
|
||||
assert isinstance(event, gdb.MemoryChangedEvent)
|
||||
print("event type: memory-changed")
|
||||
print("address: %s" % (event.address))
|
||||
print("length: %s" % (event.length))
|
||||
|
||||
|
||||
class test_events(gdb.Command):
|
||||
"""Test events."""
|
||||
|
||||
def __init__ (self):
|
||||
gdb.Command.__init__ (self, "test-events", gdb.COMMAND_STACK)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "test-events", gdb.COMMAND_STACK)
|
||||
|
||||
def invoke (self, arg, from_tty):
|
||||
gdb.events.stop.connect (signal_stop_handler)
|
||||
gdb.events.stop.connect (breakpoint_stop_handler)
|
||||
gdb.events.exited.connect (exit_handler)
|
||||
gdb.events.cont.connect (continue_handler)
|
||||
gdb.events.inferior_call.connect (inferior_call_handler)
|
||||
gdb.events.memory_changed.connect (memory_changed_handler)
|
||||
gdb.events.register_changed.connect (register_changed_handler)
|
||||
print ("Event testers registered.")
|
||||
def invoke(self, arg, from_tty):
|
||||
gdb.events.stop.connect(signal_stop_handler)
|
||||
gdb.events.stop.connect(breakpoint_stop_handler)
|
||||
gdb.events.exited.connect(exit_handler)
|
||||
gdb.events.cont.connect(continue_handler)
|
||||
gdb.events.inferior_call.connect(inferior_call_handler)
|
||||
gdb.events.memory_changed.connect(memory_changed_handler)
|
||||
gdb.events.register_changed.connect(register_changed_handler)
|
||||
print("Event testers registered.")
|
||||
|
||||
test_events ()
|
||||
|
||||
class test_newobj_events (gdb.Command):
|
||||
test_events()
|
||||
|
||||
|
||||
class test_newobj_events(gdb.Command):
|
||||
"""NewObj events."""
|
||||
|
||||
def __init__ (self):
|
||||
gdb.Command.__init__ (self, "test-objfile-events", gdb.COMMAND_STACK)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "test-objfile-events", gdb.COMMAND_STACK)
|
||||
|
||||
def invoke (self, arg, from_tty):
|
||||
gdb.events.new_objfile.connect (new_objfile_handler)
|
||||
gdb.events.clear_objfiles.connect (clear_objfiles_handler)
|
||||
print ("Object file events registered.")
|
||||
def invoke(self, arg, from_tty):
|
||||
gdb.events.new_objfile.connect(new_objfile_handler)
|
||||
gdb.events.clear_objfiles.connect(clear_objfiles_handler)
|
||||
print("Object file events registered.")
|
||||
|
||||
test_newobj_events ()
|
||||
|
||||
test_newobj_events()
|
||||
|
||||
@@ -15,75 +15,79 @@
|
||||
|
||||
# This file is part of the GDB testsuite. It tests python Finish
|
||||
# Breakpoints.
|
||||
|
||||
class MyFinishBreakpoint (gdb.FinishBreakpoint):
|
||||
def __init__(self, val, frame):
|
||||
gdb.FinishBreakpoint.__init__ (self, frame)
|
||||
print ("MyFinishBreakpoint init")
|
||||
self.val = val
|
||||
|
||||
def stop(self):
|
||||
print ("MyFinishBreakpoint stop with %d" % int (self.val.dereference ()))
|
||||
print ("return_value is: %d" % int (self.return_value))
|
||||
gdb.execute ("where 1")
|
||||
return True
|
||||
|
||||
def out_of_scope(self):
|
||||
print ("MyFinishBreakpoint out of scope")
|
||||
|
||||
|
||||
class MyFinishBreakpoint(gdb.FinishBreakpoint):
|
||||
def __init__(self, val, frame):
|
||||
gdb.FinishBreakpoint.__init__(self, frame)
|
||||
print("MyFinishBreakpoint init")
|
||||
self.val = val
|
||||
|
||||
def stop(self):
|
||||
print("MyFinishBreakpoint stop with %d" % int(self.val.dereference()))
|
||||
print("return_value is: %d" % int(self.return_value))
|
||||
gdb.execute("where 1")
|
||||
return True
|
||||
|
||||
def out_of_scope(self):
|
||||
print("MyFinishBreakpoint out of scope")
|
||||
|
||||
|
||||
class TestBreakpoint(gdb.Breakpoint):
|
||||
def __init__(self):
|
||||
gdb.Breakpoint.__init__ (self, spec="test_1", internal=1)
|
||||
gdb.Breakpoint.__init__(self, spec="test_1", internal=1)
|
||||
self.silent = True
|
||||
self.count = 0
|
||||
print ("TestBreakpoint init")
|
||||
|
||||
print("TestBreakpoint init")
|
||||
|
||||
def stop(self):
|
||||
self.count += 1
|
||||
try:
|
||||
TestFinishBreakpoint (gdb.newest_frame (), self.count)
|
||||
TestFinishBreakpoint(gdb.newest_frame(), self.count)
|
||||
except ValueError as e:
|
||||
print (e)
|
||||
print(e)
|
||||
return False
|
||||
|
||||
class TestFinishBreakpoint (gdb.FinishBreakpoint):
|
||||
def __init__ (self, frame, count):
|
||||
|
||||
class TestFinishBreakpoint(gdb.FinishBreakpoint):
|
||||
def __init__(self, frame, count):
|
||||
self.count = count
|
||||
gdb.FinishBreakpoint.__init__ (self, frame, internal=1)
|
||||
|
||||
|
||||
gdb.FinishBreakpoint.__init__(self, frame, internal=1)
|
||||
|
||||
def stop(self):
|
||||
print ("-->", self.number)
|
||||
if (self.count == 3):
|
||||
print ("test stop: %d" % self.count)
|
||||
print("-->", self.number)
|
||||
if self.count == 3:
|
||||
print("test stop: %d" % self.count)
|
||||
return True
|
||||
else:
|
||||
print ("test don't stop: %d" % self.count)
|
||||
return False
|
||||
|
||||
|
||||
print("test don't stop: %d" % self.count)
|
||||
return False
|
||||
|
||||
def out_of_scope(self):
|
||||
print ("test didn't finish: %d" % self.count)
|
||||
print("test didn't finish: %d" % self.count)
|
||||
|
||||
|
||||
class TestExplicitBreakpoint(gdb.Breakpoint):
|
||||
def stop(self):
|
||||
try:
|
||||
SimpleFinishBreakpoint (gdb.newest_frame ())
|
||||
except ValueError as e:
|
||||
print (e)
|
||||
return False
|
||||
def stop(self):
|
||||
try:
|
||||
SimpleFinishBreakpoint(gdb.newest_frame())
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
|
||||
class SimpleFinishBreakpoint(gdb.FinishBreakpoint):
|
||||
def __init__(self, frame):
|
||||
gdb.FinishBreakpoint.__init__ (self, frame)
|
||||
|
||||
print ("SimpleFinishBreakpoint init")
|
||||
|
||||
def stop(self):
|
||||
print ("SimpleFinishBreakpoint stop" )
|
||||
return True
|
||||
|
||||
def out_of_scope(self):
|
||||
print ("SimpleFinishBreakpoint out of scope")
|
||||
def __init__(self, frame):
|
||||
gdb.FinishBreakpoint.__init__(self, frame)
|
||||
|
||||
print ("Python script imported")
|
||||
print("SimpleFinishBreakpoint init")
|
||||
|
||||
def stop(self):
|
||||
print("SimpleFinishBreakpoint stop")
|
||||
return True
|
||||
|
||||
def out_of_scope(self):
|
||||
print("SimpleFinishBreakpoint out of scope")
|
||||
|
||||
|
||||
print("Python script imported")
|
||||
|
||||
@@ -16,18 +16,19 @@
|
||||
# This file is part of the GDB testsuite. It tests python Finish
|
||||
# Breakpoints.
|
||||
|
||||
|
||||
class ExceptionFinishBreakpoint(gdb.FinishBreakpoint):
|
||||
def __init__(self, frame):
|
||||
gdb.FinishBreakpoint.__init__ (self, frame, internal=1)
|
||||
gdb.FinishBreakpoint.__init__(self, frame, internal=1)
|
||||
self.silent = True
|
||||
print ("init ExceptionFinishBreakpoint")
|
||||
|
||||
print("init ExceptionFinishBreakpoint")
|
||||
|
||||
def stop(self):
|
||||
print ("stopped at ExceptionFinishBreakpoint")
|
||||
return True
|
||||
|
||||
print("stopped at ExceptionFinishBreakpoint")
|
||||
return True
|
||||
|
||||
def out_of_scope(self):
|
||||
print ("exception did not finish ...")
|
||||
print("exception did not finish ...")
|
||||
|
||||
|
||||
print ("Python script imported")
|
||||
print("Python script imported")
|
||||
|
||||
@@ -18,14 +18,16 @@
|
||||
|
||||
import gdb
|
||||
|
||||
class PointPrinter (object):
|
||||
def __init__ (self, val):
|
||||
|
||||
class PointPrinter(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string (self):
|
||||
return 'Pretty Point (%s, %s)' % (self.val['x'], self.val['y'])
|
||||
def to_string(self):
|
||||
return "Pretty Point (%s, %s)" % (self.val["x"], self.val["y"])
|
||||
|
||||
def test_lookup_function (val):
|
||||
|
||||
def test_lookup_function(val):
|
||||
"Look-up and return a pretty-printer that can print val."
|
||||
|
||||
# Get the type.
|
||||
@@ -33,17 +35,18 @@ def test_lookup_function (val):
|
||||
|
||||
# If it points to a reference, get the reference.
|
||||
if type.code == gdb.TYPE_CODE_REF:
|
||||
type = type.target ()
|
||||
type = type.target()
|
||||
|
||||
# Get the unqualified type, stripped of typedefs.
|
||||
type = type.unqualified ().strip_typedefs ()
|
||||
type = type.unqualified().strip_typedefs()
|
||||
|
||||
# Get the type name.
|
||||
typename = type.tag
|
||||
|
||||
if typename == 'point':
|
||||
return PointPrinter (val)
|
||||
if typename == "point":
|
||||
return PointPrinter(val)
|
||||
|
||||
return None
|
||||
|
||||
gdb.pretty_printers.append (test_lookup_function)
|
||||
|
||||
gdb.pretty_printers.append(test_lookup_function)
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
import re
|
||||
import gdb
|
||||
|
||||
class pp_s (object):
|
||||
|
||||
class pp_s(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
@@ -24,19 +25,20 @@ class pp_s (object):
|
||||
m = self.val["m"]
|
||||
return "m=<" + str(self.val["m"]) + ">"
|
||||
|
||||
class pp_ss (object):
|
||||
|
||||
class pp_ss(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return "super struct"
|
||||
|
||||
def children (self):
|
||||
yield 'a', self.val['a']
|
||||
yield 'b', self.val['b']
|
||||
def children(self):
|
||||
yield "a", self.val["a"]
|
||||
yield "b", self.val["b"]
|
||||
|
||||
|
||||
def lookup_function (val):
|
||||
def lookup_function(val):
|
||||
"Look-up and return a pretty-printer that can print val."
|
||||
|
||||
# Get the type.
|
||||
@@ -44,12 +46,12 @@ def lookup_function (val):
|
||||
|
||||
# If it points to a reference, get the reference.
|
||||
if type.code == gdb.TYPE_CODE_REF:
|
||||
type = type.target ()
|
||||
type = type.target()
|
||||
|
||||
# Get the unqualified type, stripped of typedefs.
|
||||
type = type.unqualified ().strip_typedefs ()
|
||||
type = type.unqualified().strip_typedefs()
|
||||
|
||||
# Get the type name.
|
||||
# Get the type name.
|
||||
typename = type.tag
|
||||
if typename == None:
|
||||
return None
|
||||
@@ -58,18 +60,19 @@ def lookup_function (val):
|
||||
# if a printer is registered for that type. Return an
|
||||
# instantiation of the printer if found.
|
||||
for function in pretty_printers_dict:
|
||||
if function.match (typename):
|
||||
return pretty_printers_dict[function] (val)
|
||||
|
||||
if function.match(typename):
|
||||
return pretty_printers_dict[function](val)
|
||||
|
||||
# Cannot find a pretty printer. Return None.
|
||||
return None
|
||||
|
||||
|
||||
def register_pretty_printers ():
|
||||
pretty_printers_dict[re.compile ('^s$')] = pp_s
|
||||
pretty_printers_dict[re.compile ('^ss$')] = pp_ss
|
||||
def register_pretty_printers():
|
||||
pretty_printers_dict[re.compile("^s$")] = pp_s
|
||||
pretty_printers_dict[re.compile("^ss$")] = pp_ss
|
||||
|
||||
|
||||
pretty_printers_dict = {}
|
||||
|
||||
register_pretty_printers ()
|
||||
gdb.pretty_printers.append (lookup_function)
|
||||
register_pretty_printers()
|
||||
gdb.pretty_printers.append(lookup_function)
|
||||
|
||||
@@ -20,33 +20,32 @@ import copy
|
||||
|
||||
# A FrameDecorator that just returns gdb.Frame.pc () from 'function'.
|
||||
# We want to ensure that GDB correctly handles this case.
|
||||
class Function_Returns_Address (FrameDecorator):
|
||||
|
||||
class Function_Returns_Address(FrameDecorator):
|
||||
def __init__(self, fobj):
|
||||
super (Function_Returns_Address, self).__init__ (fobj)
|
||||
super(Function_Returns_Address, self).__init__(fobj)
|
||||
self._fobj = fobj
|
||||
|
||||
def function (self):
|
||||
frame = self.inferior_frame ()
|
||||
return frame.pc ()
|
||||
def function(self):
|
||||
frame = self.inferior_frame()
|
||||
return frame.pc()
|
||||
|
||||
class Frame_Filter ():
|
||||
|
||||
def __init__ (self):
|
||||
class Frame_Filter:
|
||||
def __init__(self):
|
||||
self.name = "function_returns_address"
|
||||
self.priority = 100
|
||||
self.enabled = True
|
||||
gdb.frame_filters [self.name] = self
|
||||
gdb.frame_filters[self.name] = self
|
||||
|
||||
def filter (self, frame_iter):
|
||||
def filter(self, frame_iter):
|
||||
# Python 3.x moved the itertools.imap functionality to map(),
|
||||
# so check if it is available.
|
||||
if hasattr(itertools, "imap"):
|
||||
frame_iter = itertools.imap (Function_Returns_Address,
|
||||
frame_iter)
|
||||
frame_iter = itertools.imap(Function_Returns_Address, frame_iter)
|
||||
else:
|
||||
frame_iter = map(Function_Returns_Address, frame_iter)
|
||||
|
||||
return frame_iter
|
||||
|
||||
|
||||
Frame_Filter()
|
||||
|
||||
@@ -20,40 +20,40 @@ import itertools
|
||||
from gdb.FrameDecorator import FrameDecorator
|
||||
import copy
|
||||
|
||||
class Reverse_Function (FrameDecorator):
|
||||
|
||||
class Reverse_Function(FrameDecorator):
|
||||
def __init__(self, fobj):
|
||||
super(Reverse_Function, self).__init__(fobj)
|
||||
self.fobj = fobj
|
||||
|
||||
def function (self):
|
||||
fname = str (self.fobj.function())
|
||||
if (fname == None or fname == ""):
|
||||
def function(self):
|
||||
fname = str(self.fobj.function())
|
||||
if fname == None or fname == "":
|
||||
return None
|
||||
if fname == 'end_func':
|
||||
extra = self.fobj.inferior_frame().read_var('str').string()
|
||||
if fname == "end_func":
|
||||
extra = self.fobj.inferior_frame().read_var("str").string()
|
||||
else:
|
||||
extra = ''
|
||||
extra = ""
|
||||
fname = fname[::-1] + extra
|
||||
return fname
|
||||
|
||||
class FrameFilter ():
|
||||
|
||||
def __init__ (self):
|
||||
class FrameFilter:
|
||||
def __init__(self):
|
||||
self.name = "Reverse"
|
||||
self.priority = 100
|
||||
self.enabled = True
|
||||
gdb.frame_filters [self.name] = self
|
||||
gdb.frame_filters[self.name] = self
|
||||
|
||||
def filter (self, frame_iter):
|
||||
def filter(self, frame_iter):
|
||||
# Python 3.x moved the itertools.imap functionality to map(),
|
||||
# so check if it is available.
|
||||
if hasattr(itertools, "imap"):
|
||||
frame_iter = itertools.imap (Reverse_Function,
|
||||
frame_iter)
|
||||
frame_iter = itertools.imap(Reverse_Function, frame_iter)
|
||||
else:
|
||||
frame_iter = map(Reverse_Function, frame_iter)
|
||||
|
||||
return frame_iter
|
||||
|
||||
|
||||
FrameFilter()
|
||||
|
||||
@@ -20,71 +20,70 @@ import itertools
|
||||
from gdb.FrameDecorator import FrameDecorator
|
||||
import copy
|
||||
|
||||
class Reverse_Function (FrameDecorator):
|
||||
|
||||
class Reverse_Function(FrameDecorator):
|
||||
def __init__(self, fobj):
|
||||
super(Reverse_Function, self).__init__(fobj)
|
||||
self.fobj = fobj
|
||||
|
||||
def function (self):
|
||||
fname = str (self.fobj.function())
|
||||
if (fname == None or fname == ""):
|
||||
def function(self):
|
||||
fname = str(self.fobj.function())
|
||||
if fname == None or fname == "":
|
||||
return None
|
||||
if fname == 'end_func':
|
||||
extra = self.fobj.inferior_frame().read_var('str').string()
|
||||
if fname == "end_func":
|
||||
extra = self.fobj.inferior_frame().read_var("str").string()
|
||||
else:
|
||||
extra = ''
|
||||
extra = ""
|
||||
fname = fname[::-1] + extra
|
||||
return fname
|
||||
|
||||
class Dummy (FrameDecorator):
|
||||
|
||||
class Dummy(FrameDecorator):
|
||||
def __init__(self, fobj):
|
||||
super(Dummy, self).__init__(fobj)
|
||||
self.fobj = fobj
|
||||
|
||||
def function (self):
|
||||
def function(self):
|
||||
return "Dummy function"
|
||||
|
||||
def address (self):
|
||||
def address(self):
|
||||
return 0x123
|
||||
|
||||
def filename (self):
|
||||
def filename(self):
|
||||
return "Dummy filename"
|
||||
|
||||
def frame_args (self):
|
||||
return [("Foo",gdb.Value(12)),("Bar","Stuff"), ("FooBar",42)]
|
||||
def frame_args(self):
|
||||
return [("Foo", gdb.Value(12)), ("Bar", "Stuff"), ("FooBar", 42)]
|
||||
|
||||
def frame_locals (self):
|
||||
def frame_locals(self):
|
||||
return []
|
||||
|
||||
def line (self):
|
||||
def line(self):
|
||||
return 0
|
||||
|
||||
def elided (self):
|
||||
def elided(self):
|
||||
return None
|
||||
|
||||
class FrameFilter ():
|
||||
|
||||
def __init__ (self):
|
||||
class FrameFilter:
|
||||
def __init__(self):
|
||||
self.name = "Reverse"
|
||||
self.priority = 100
|
||||
self.enabled = True
|
||||
gdb.frame_filters [self.name] = self
|
||||
gdb.frame_filters[self.name] = self
|
||||
|
||||
def filter (self, frame_iter):
|
||||
def filter(self, frame_iter):
|
||||
# Python 3.x moved the itertools.imap functionality to map(),
|
||||
# so check if it is available.
|
||||
if hasattr(itertools, "imap"):
|
||||
frame_iter = itertools.imap (Reverse_Function,
|
||||
frame_iter)
|
||||
frame_iter = itertools.imap(Reverse_Function, frame_iter)
|
||||
else:
|
||||
frame_iter = map(Reverse_Function, frame_iter)
|
||||
|
||||
return frame_iter
|
||||
|
||||
class ElidingFrameDecorator(FrameDecorator):
|
||||
|
||||
class ElidingFrameDecorator(FrameDecorator):
|
||||
def __init__(self, frame, elided_frames):
|
||||
super(ElidingFrameDecorator, self).__init__(frame)
|
||||
self.elided_frames = elided_frames
|
||||
@@ -92,11 +91,12 @@ class ElidingFrameDecorator(FrameDecorator):
|
||||
def elided(self):
|
||||
return iter(self.elided_frames)
|
||||
|
||||
def address (self):
|
||||
def address(self):
|
||||
# Regression test for an overflow in the python layer.
|
||||
bitsize = 8 * gdb.lookup_type('void').pointer().sizeof
|
||||
bitsize = 8 * gdb.lookup_type("void").pointer().sizeof
|
||||
mask = (1 << bitsize) - 1
|
||||
return 0xffffffffffffffff & mask
|
||||
return 0xFFFFFFFFFFFFFFFF & mask
|
||||
|
||||
|
||||
class ElidingIterator:
|
||||
def __init__(self, ii):
|
||||
@@ -107,7 +107,7 @@ class ElidingIterator:
|
||||
|
||||
def next(self):
|
||||
frame = next(self.input_iterator)
|
||||
if str(frame.function()) != 'func1':
|
||||
if str(frame.function()) != "func1":
|
||||
return frame
|
||||
|
||||
# Suppose we want to return the 'func1' frame but elide the
|
||||
@@ -123,16 +123,17 @@ class ElidingIterator:
|
||||
def __next__(self):
|
||||
return self.next()
|
||||
|
||||
class FrameElider ():
|
||||
|
||||
def __init__ (self):
|
||||
class FrameElider:
|
||||
def __init__(self):
|
||||
self.name = "Elider"
|
||||
self.priority = 900
|
||||
self.enabled = True
|
||||
gdb.frame_filters [self.name] = self
|
||||
gdb.frame_filters[self.name] = self
|
||||
|
||||
def filter(self, frame_iter):
|
||||
return ElidingIterator(frame_iter)
|
||||
|
||||
def filter (self, frame_iter):
|
||||
return ElidingIterator (frame_iter)
|
||||
|
||||
# This is here so the test can change the kind of error that is
|
||||
# thrown.
|
||||
@@ -144,24 +145,26 @@ class ErrorInName(FrameDecorator):
|
||||
FrameDecorator.__init__(self, frame)
|
||||
|
||||
def function(self):
|
||||
raise name_error('whoops')
|
||||
raise name_error("whoops")
|
||||
|
||||
|
||||
# A filter that supplies buggy frames. Disabled by default.
|
||||
class ErrorFilter():
|
||||
def __init__ (self):
|
||||
class ErrorFilter:
|
||||
def __init__(self):
|
||||
self.name = "Error"
|
||||
self.priority = 1
|
||||
self.enabled = False
|
||||
gdb.frame_filters [self.name] = self
|
||||
gdb.frame_filters[self.name] = self
|
||||
|
||||
def filter(self, frame_iter):
|
||||
# Python 3.x moved the itertools.imap functionality to map(),
|
||||
# so check if it is available.
|
||||
if hasattr(itertools, "imap"):
|
||||
return itertools.imap (ErrorInName, frame_iter)
|
||||
return itertools.imap(ErrorInName, frame_iter)
|
||||
else:
|
||||
return map(ErrorInName, frame_iter)
|
||||
|
||||
|
||||
FrameFilter()
|
||||
FrameElider()
|
||||
ErrorFilter()
|
||||
|
||||
@@ -22,31 +22,33 @@ import gdb
|
||||
stop_handler_str = ""
|
||||
cont_handler_str = ""
|
||||
|
||||
def signal_stop_handler (event):
|
||||
|
||||
def signal_stop_handler(event):
|
||||
"""Stop event handler"""
|
||||
assert (isinstance (event, gdb.StopEvent))
|
||||
assert isinstance(event, gdb.StopEvent)
|
||||
global stop_handler_str
|
||||
stop_handler_str = "stop_handler\n"
|
||||
stop_handler_str += gdb.execute("info break", False, True)
|
||||
|
||||
|
||||
def continue_handler (event):
|
||||
def continue_handler(event):
|
||||
"""Continue event handler"""
|
||||
assert (isinstance (event, gdb.ContinueEvent))
|
||||
assert isinstance(event, gdb.ContinueEvent)
|
||||
global cont_handler_str
|
||||
cont_handler_str = "continue_handler\n"
|
||||
cont_handler_str += gdb.execute("info break", False, True)
|
||||
|
||||
|
||||
class test_events (gdb.Command):
|
||||
class test_events(gdb.Command):
|
||||
"""Test events."""
|
||||
|
||||
def __init__ (self):
|
||||
gdb.Command.__init__ (self, "test-events", gdb.COMMAND_STACK)
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, "test-events", gdb.COMMAND_STACK)
|
||||
|
||||
def invoke (self, arg, from_tty):
|
||||
gdb.events.stop.connect (signal_stop_handler)
|
||||
gdb.events.cont.connect (continue_handler)
|
||||
print ("Event testers registered.")
|
||||
def invoke(self, arg, from_tty):
|
||||
gdb.events.stop.connect(signal_stop_handler)
|
||||
gdb.events.cont.connect(continue_handler)
|
||||
print("Event testers registered.")
|
||||
|
||||
test_events ()
|
||||
|
||||
test_events()
|
||||
|
||||
@@ -23,35 +23,35 @@ if sys.version_info[0] > 2:
|
||||
|
||||
|
||||
class cons_pp(object):
|
||||
def __init__(self, val):
|
||||
self._val = val
|
||||
def __init__(self, val):
|
||||
self._val = val
|
||||
|
||||
def to_string(self):
|
||||
if long(self._val) == 0:
|
||||
return "nil"
|
||||
elif long(self._val['type']) == 0:
|
||||
return "( . )"
|
||||
else:
|
||||
return "%d" % self._val['atom']['ival']
|
||||
def to_string(self):
|
||||
if long(self._val) == 0:
|
||||
return "nil"
|
||||
elif long(self._val["type"]) == 0:
|
||||
return "( . )"
|
||||
else:
|
||||
return "%d" % self._val["atom"]["ival"]
|
||||
|
||||
def children(self):
|
||||
if long(self._val) == 0:
|
||||
return []
|
||||
elif long(self._val["type"]) == 0:
|
||||
return [("atom", self._val["atom"])]
|
||||
else:
|
||||
return [
|
||||
("car", self._val["slots"][0]),
|
||||
("cdr", self._val["slots"][1]),
|
||||
]
|
||||
|
||||
def children(self):
|
||||
if long(self._val) == 0:
|
||||
return []
|
||||
elif long(self._val['type']) == 0:
|
||||
return [
|
||||
('atom', self._val['atom'])
|
||||
]
|
||||
else:
|
||||
return [
|
||||
('car' , self._val["slots"][0]),
|
||||
('cdr' , self._val["slots"][1]),
|
||||
]
|
||||
|
||||
def cons_pp_lookup(val):
|
||||
if str(val.type) == 'struct cons *':
|
||||
return cons_pp(val)
|
||||
else:
|
||||
return None
|
||||
if str(val.type) == "struct cons *":
|
||||
return cons_pp(val)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
del gdb.pretty_printers[1:]
|
||||
gdb.pretty_printers.append(cons_pp_lookup)
|
||||
|
||||
@@ -19,15 +19,17 @@
|
||||
import re
|
||||
import gdb
|
||||
|
||||
def _iterator1 (pointer, len):
|
||||
|
||||
def _iterator1(pointer, len):
|
||||
while len > 0:
|
||||
map = pointer.dereference()
|
||||
yield ('', map['name'])
|
||||
yield ('', map.dereference())
|
||||
yield ("", map["name"])
|
||||
yield ("", map.dereference())
|
||||
pointer += 1
|
||||
len -= 1
|
||||
|
||||
def _iterator2 (pointer1, pointer2, len):
|
||||
|
||||
def _iterator2(pointer1, pointer2, len):
|
||||
while len > 0:
|
||||
yield ("", pointer1.dereference())
|
||||
yield ("", pointer2.dereference())
|
||||
@@ -35,42 +37,42 @@ def _iterator2 (pointer1, pointer2, len):
|
||||
pointer2 += 1
|
||||
len -= 1
|
||||
|
||||
class pp_map (object):
|
||||
|
||||
class pp_map(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
if (self.val['show_header'] == 0):
|
||||
if self.val["show_header"] == 0:
|
||||
return None
|
||||
else:
|
||||
return "pp_map"
|
||||
|
||||
def children(self):
|
||||
return _iterator2(self.val['keys'],
|
||||
self.val['values'],
|
||||
self.val['length'])
|
||||
return _iterator2(self.val["keys"], self.val["values"], self.val["length"])
|
||||
|
||||
def display_hint (self):
|
||||
return 'map'
|
||||
def display_hint(self):
|
||||
return "map"
|
||||
|
||||
class pp_map_map (object):
|
||||
|
||||
class pp_map_map(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
if (self.val['show_header'] == 0):
|
||||
if self.val["show_header"] == 0:
|
||||
return None
|
||||
else:
|
||||
return "pp_map_map"
|
||||
|
||||
def children(self):
|
||||
return _iterator1(self.val['values'],
|
||||
self.val['length'])
|
||||
return _iterator1(self.val["values"], self.val["length"])
|
||||
|
||||
def display_hint (self):
|
||||
return 'map'
|
||||
def display_hint(self):
|
||||
return "map"
|
||||
|
||||
def lookup_function (val):
|
||||
|
||||
def lookup_function(val):
|
||||
"Look-up and return a pretty-printer that can print val."
|
||||
|
||||
# Get the type.
|
||||
@@ -78,10 +80,10 @@ def lookup_function (val):
|
||||
|
||||
# If it points to a reference, get the reference.
|
||||
if type.code == gdb.TYPE_CODE_REF:
|
||||
type = type.target ()
|
||||
type = type.target()
|
||||
|
||||
# Get the unqualified type, stripped of typedefs.
|
||||
type = type.unqualified ().strip_typedefs ()
|
||||
type = type.unqualified().strip_typedefs()
|
||||
|
||||
# Get the type name.
|
||||
typename = type.tag
|
||||
@@ -93,14 +95,15 @@ def lookup_function (val):
|
||||
# if a printer is registered for that type. Return an
|
||||
# instantiation of the printer if found.
|
||||
for function in pretty_printers_dict:
|
||||
if function.match (typename):
|
||||
return pretty_printers_dict[function] (val)
|
||||
if function.match(typename):
|
||||
return pretty_printers_dict[function](val)
|
||||
|
||||
# Cannot find a pretty printer. Return None.
|
||||
return None
|
||||
|
||||
|
||||
# Lookup a printer for VAL in the typedefs dict.
|
||||
def lookup_typedefs_function (val):
|
||||
def lookup_typedefs_function(val):
|
||||
"Look-up and return a pretty-printer that can print val (typedefs)."
|
||||
|
||||
# Get the type.
|
||||
@@ -113,23 +116,25 @@ def lookup_typedefs_function (val):
|
||||
# printer is registered for that type. Return an instantiation of
|
||||
# the printer if found.
|
||||
for function in typedefs_pretty_printers_dict:
|
||||
if function.match (type.name):
|
||||
return typedefs_pretty_printers_dict[function] (val)
|
||||
if function.match(type.name):
|
||||
return typedefs_pretty_printers_dict[function](val)
|
||||
|
||||
# Cannot find a pretty printer.
|
||||
return None
|
||||
|
||||
def register_pretty_printers ():
|
||||
pretty_printers_dict[re.compile ('^struct map_t$')] = pp_map
|
||||
pretty_printers_dict[re.compile ('^map_t$')] = pp_map
|
||||
pretty_printers_dict[re.compile ('^struct map_map_t$')] = pp_map_map
|
||||
pretty_printers_dict[re.compile ('^map_map_t$')] = pp_map_map
|
||||
|
||||
def register_pretty_printers():
|
||||
pretty_printers_dict[re.compile("^struct map_t$")] = pp_map
|
||||
pretty_printers_dict[re.compile("^map_t$")] = pp_map
|
||||
pretty_printers_dict[re.compile("^struct map_map_t$")] = pp_map_map
|
||||
pretty_printers_dict[re.compile("^map_map_t$")] = pp_map_map
|
||||
|
||||
|
||||
# Dict for struct types with typedefs fully stripped.
|
||||
pretty_printers_dict = {}
|
||||
# Dict for typedef types.
|
||||
typedefs_pretty_printers_dict = {}
|
||||
|
||||
register_pretty_printers ()
|
||||
gdb.pretty_printers.append (lookup_function)
|
||||
gdb.pretty_printers.append (lookup_typedefs_function)
|
||||
register_pretty_printers()
|
||||
gdb.pretty_printers.append(lookup_function)
|
||||
gdb.pretty_printers.append(lookup_typedefs_function)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import re
|
||||
|
||||
|
||||
class pp_ss:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
@@ -24,7 +25,8 @@ class pp_ss:
|
||||
def to_string(self):
|
||||
return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
||||
|
||||
def lookup_function (val):
|
||||
|
||||
def lookup_function(val):
|
||||
"Look-up and return a pretty-printer that can print val."
|
||||
|
||||
# Get the type.
|
||||
@@ -32,12 +34,12 @@ def lookup_function (val):
|
||||
|
||||
# If it points to a reference, get the reference.
|
||||
if type.code == gdb.TYPE_CODE_REF:
|
||||
type = type.target ()
|
||||
type = type.target()
|
||||
|
||||
# Get the unqualified type, stripped of typedefs.
|
||||
type = type.unqualified ().strip_typedefs ()
|
||||
type = type.unqualified().strip_typedefs()
|
||||
|
||||
# Get the type name.
|
||||
# Get the type name.
|
||||
typename = type.tag
|
||||
|
||||
if typename == None:
|
||||
@@ -47,17 +49,19 @@ def lookup_function (val):
|
||||
# if a printer is registered for that type. Return an
|
||||
# instantiation of the printer if found.
|
||||
for function in pretty_printers_dict:
|
||||
if function.match (typename):
|
||||
return pretty_printers_dict[function] (val)
|
||||
|
||||
if function.match(typename):
|
||||
return pretty_printers_dict[function](val)
|
||||
|
||||
# Cannot find a pretty printer. Return None.
|
||||
|
||||
return None
|
||||
|
||||
def register_pretty_printers ():
|
||||
pretty_printers_dict[re.compile ('^ss$')] = pp_ss
|
||||
|
||||
def register_pretty_printers():
|
||||
pretty_printers_dict[re.compile("^ss$")] = pp_ss
|
||||
|
||||
|
||||
pretty_printers_dict = {}
|
||||
|
||||
register_pretty_printers ()
|
||||
gdb.current_progspace().pretty_printers.append (lookup_function)
|
||||
register_pretty_printers()
|
||||
gdb.current_progspace().pretty_printers.append(lookup_function)
|
||||
|
||||
@@ -27,7 +27,7 @@ class TimePrinter:
|
||||
|
||||
|
||||
def time_sniffer(val):
|
||||
if hasattr(val.type, 'name') and val.type.name == "time_t":
|
||||
if hasattr(val.type, "name") and val.type.name == "time_t":
|
||||
return TimePrinter(val)
|
||||
return None
|
||||
|
||||
|
||||
@@ -27,8 +27,7 @@ def lookup_function_lookup_test(val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return ("x=<" + str(self.val["x"]) +
|
||||
"> y=<" + str(self.val["y"]) + ">")
|
||||
return "x=<" + str(self.val["x"]) + "> y=<" + str(self.val["y"]) + ">"
|
||||
|
||||
typename = gdb.types.get_basic_type(val.type).tag
|
||||
# Note: typename could be None.
|
||||
@@ -37,7 +36,7 @@ def lookup_function_lookup_test(val):
|
||||
return None
|
||||
|
||||
|
||||
class pp_s (object):
|
||||
class pp_s(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
@@ -49,7 +48,7 @@ class pp_s (object):
|
||||
return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
||||
|
||||
|
||||
class pp_ss (object):
|
||||
class pp_ss(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
@@ -60,15 +59,18 @@ class pp_ss (object):
|
||||
def build_pretty_printer():
|
||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
|
||||
|
||||
pp.add_printer('struct s', '^struct s$', pp_s)
|
||||
pp.add_printer('s', '^s$', pp_s)
|
||||
pp.add_printer("struct s", "^struct s$", pp_s)
|
||||
pp.add_printer("s", "^s$", pp_s)
|
||||
|
||||
# Use a lambda this time to exercise doing things this way.
|
||||
pp.add_printer('struct ss', '^struct ss$', lambda val: pp_ss(val))
|
||||
pp.add_printer('ss', '^ss$', lambda val: pp_ss(val))
|
||||
pp.add_printer("struct ss", "^struct ss$", lambda val: pp_ss(val))
|
||||
pp.add_printer("ss", "^ss$", lambda val: pp_ss(val))
|
||||
|
||||
pp.add_printer('enum flag_enum', '^flag_enum$',
|
||||
gdb.printing.FlagEnumerationPrinter('enum flag_enum'))
|
||||
pp.add_printer(
|
||||
"enum flag_enum",
|
||||
"^flag_enum$",
|
||||
gdb.printing.FlagEnumerationPrinter("enum flag_enum"),
|
||||
)
|
||||
|
||||
return pp
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class TimePrinter:
|
||||
|
||||
def build_pretty_printer():
|
||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-notag")
|
||||
pp.add_printer('time_t', 'time_t', TimePrinter)
|
||||
pp.add_printer("time_t", "time_t", TimePrinter)
|
||||
return pp
|
||||
|
||||
|
||||
|
||||
@@ -27,8 +27,7 @@ def lookup_function_lookup_test(val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return ("x=<" + str(self.val["x"]) +
|
||||
"> y=<" + str(self.val["y"]) + ">")
|
||||
return "x=<" + str(self.val["x"]) + "> y=<" + str(self.val["y"]) + ">"
|
||||
|
||||
typename = gdb.types.get_basic_type(val.type).tag
|
||||
# Note: typename could be None.
|
||||
@@ -37,7 +36,7 @@ def lookup_function_lookup_test(val):
|
||||
return None
|
||||
|
||||
|
||||
class pp_s1 (object):
|
||||
class pp_s1(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
@@ -47,7 +46,7 @@ class pp_s1 (object):
|
||||
return "s1 a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
||||
|
||||
|
||||
class pp_s2 (object):
|
||||
class pp_s2(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
@@ -60,8 +59,8 @@ class pp_s2 (object):
|
||||
def build_pretty_printer1():
|
||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
|
||||
|
||||
pp.add_printer('struct s', '^struct s$', pp_s1)
|
||||
pp.add_printer('s', '^s$', pp_s1)
|
||||
pp.add_printer("struct s", "^struct s$", pp_s1)
|
||||
pp.add_printer("s", "^s$", pp_s1)
|
||||
|
||||
return pp
|
||||
|
||||
@@ -72,9 +71,10 @@ def build_pretty_printer2():
|
||||
# register_pretty_printer.
|
||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
|
||||
|
||||
pp.add_printer('struct s', '^struct s$', pp_s2)
|
||||
pp.add_printer('s', '^s$', pp_s2)
|
||||
pp.add_printer("struct s", "^struct s$", pp_s2)
|
||||
pp.add_printer("s", "^s$", pp_s2)
|
||||
|
||||
return pp
|
||||
|
||||
|
||||
# Note: Registering the printers is done in the .exp file.
|
||||
|
||||
@@ -19,73 +19,78 @@
|
||||
import re
|
||||
import gdb
|
||||
|
||||
def _iterator (pointer, len):
|
||||
|
||||
def _iterator(pointer, len):
|
||||
start = pointer
|
||||
end = pointer + len
|
||||
while pointer != end:
|
||||
yield ('[%d]' % int (pointer - start), pointer.dereference())
|
||||
yield ("[%d]" % int(pointer - start), pointer.dereference())
|
||||
pointer += 1
|
||||
|
||||
|
||||
# Same as _iterator but can be told to raise an exception.
|
||||
def _iterator_except (pointer, len):
|
||||
def _iterator_except(pointer, len):
|
||||
start = pointer
|
||||
end = pointer + len
|
||||
while pointer != end:
|
||||
if exception_flag:
|
||||
raise gdb.MemoryError ('hi bob')
|
||||
yield ('[%d]' % int (pointer - start), pointer.dereference())
|
||||
raise gdb.MemoryError("hi bob")
|
||||
yield ("[%d]" % int(pointer - start), pointer.dereference())
|
||||
pointer += 1
|
||||
|
||||
|
||||
# Test returning a Value from a printer.
|
||||
class string_print (object):
|
||||
class string_print(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return self.val['whybother']['contents']
|
||||
return self.val["whybother"]["contents"]
|
||||
|
||||
|
||||
# Test a class-based printer.
|
||||
class ContainerPrinter (object):
|
||||
|
||||
class ContainerPrinter(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return 'container %s with %d elements' % (self.val['name'], self.val['len'])
|
||||
return "container %s with %d elements" % (self.val["name"], self.val["len"])
|
||||
|
||||
def children(self):
|
||||
return _iterator(self.val['elements'], self.val['len'])
|
||||
return _iterator(self.val["elements"], self.val["len"])
|
||||
|
||||
def display_hint (self):
|
||||
if (self.val['is_map_p'] and self.val['is_array_p']):
|
||||
raise Exception ("invalid object state found in display_hint")
|
||||
def display_hint(self):
|
||||
if self.val["is_map_p"] and self.val["is_array_p"]:
|
||||
raise Exception("invalid object state found in display_hint")
|
||||
|
||||
if (self.val['is_map_p']):
|
||||
return 'map'
|
||||
elif (self.val['is_array_p']):
|
||||
return 'array'
|
||||
if self.val["is_map_p"]:
|
||||
return "map"
|
||||
elif self.val["is_array_p"]:
|
||||
return "array"
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
# Treats a container as array.
|
||||
class ArrayPrinter (object):
|
||||
class ArrayPrinter(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return 'array %s with %d elements' % (self.val['name'], self.val['len'])
|
||||
return "array %s with %d elements" % (self.val["name"], self.val["len"])
|
||||
|
||||
def children(self):
|
||||
return _iterator(self.val['elements'], self.val['len'])
|
||||
return _iterator(self.val["elements"], self.val["len"])
|
||||
|
||||
def display_hint(self):
|
||||
return "array"
|
||||
|
||||
def display_hint (self):
|
||||
return 'array'
|
||||
|
||||
# Flag to make NoStringContainerPrinter throw an exception.
|
||||
exception_flag = False
|
||||
|
||||
# Test a printer where to_string is None
|
||||
class NoStringContainerPrinter (object):
|
||||
class NoStringContainerPrinter(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
@@ -93,28 +98,29 @@ class NoStringContainerPrinter (object):
|
||||
return None
|
||||
|
||||
def children(self):
|
||||
return _iterator_except (self.val['elements'], self.val['len'])
|
||||
return _iterator_except(self.val["elements"], self.val["len"])
|
||||
|
||||
|
||||
# See ToStringReturnsValueWrapper.
|
||||
class ToStringReturnsValueInner:
|
||||
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return 'Inner to_string {}'.format(int(self.val['val']))
|
||||
return "Inner to_string {}".format(int(self.val["val"]))
|
||||
|
||||
|
||||
# Test a printer that returns a gdb.Value in its to_string. That gdb.Value
|
||||
# also has its own pretty-printer.
|
||||
class ToStringReturnsValueWrapper:
|
||||
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return self.val['inner']
|
||||
return self.val["inner"]
|
||||
|
||||
class pp_s (object):
|
||||
|
||||
class pp_s(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
@@ -125,155 +131,174 @@ class pp_s (object):
|
||||
raise Exception("&a(%s) != b(%s)" % (str(a.address), str(b)))
|
||||
return " a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
||||
|
||||
class pp_ss (object):
|
||||
|
||||
class pp_ss(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
||||
|
||||
class pp_sss (object):
|
||||
|
||||
class pp_sss(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return "a=<" + str(self.val['a']) + "> b=<" + str(self.val["b"]) + ">"
|
||||
return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
||||
|
||||
class pp_multiple_virtual (object):
|
||||
def __init__ (self, val):
|
||||
|
||||
class pp_multiple_virtual(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string (self):
|
||||
return "pp value variable is: " + str (self.val['value'])
|
||||
def to_string(self):
|
||||
return "pp value variable is: " + str(self.val["value"])
|
||||
|
||||
class pp_vbase1 (object):
|
||||
def __init__ (self, val):
|
||||
|
||||
class pp_vbase1(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string (self):
|
||||
def to_string(self):
|
||||
return "pp class name: " + self.val.type.tag
|
||||
|
||||
class pp_nullstr (object):
|
||||
|
||||
class pp_nullstr(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return self.val['s'].string(gdb.target_charset())
|
||||
return self.val["s"].string(gdb.target_charset())
|
||||
|
||||
class pp_ns (object):
|
||||
|
||||
class pp_ns(object):
|
||||
"Print a std::basic_string of some kind"
|
||||
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
len = self.val['length']
|
||||
return self.val['null_str'].string (gdb.target_charset(), length = len)
|
||||
len = self.val["length"]
|
||||
return self.val["null_str"].string(gdb.target_charset(), length=len)
|
||||
|
||||
def display_hint(self):
|
||||
return "string"
|
||||
|
||||
def display_hint (self):
|
||||
return 'string'
|
||||
|
||||
pp_ls_encoding = None
|
||||
|
||||
class pp_ls (object):
|
||||
|
||||
class pp_ls(object):
|
||||
"Print a std::basic_string of some kind"
|
||||
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
length = self.val['len']
|
||||
length = self.val["len"]
|
||||
if pp_ls_encoding is not None:
|
||||
if length >= 0:
|
||||
return self.val['lazy_str'].lazy_string(
|
||||
encoding = pp_ls_encoding,
|
||||
length = length)
|
||||
return self.val["lazy_str"].lazy_string(
|
||||
encoding=pp_ls_encoding, length=length
|
||||
)
|
||||
else:
|
||||
return self.val['lazy_str'].lazy_string(
|
||||
encoding = pp_ls_encoding)
|
||||
return self.val["lazy_str"].lazy_string(encoding=pp_ls_encoding)
|
||||
else:
|
||||
if length >= 0:
|
||||
return self.val['lazy_str'].lazy_string(length = length)
|
||||
return self.val["lazy_str"].lazy_string(length=length)
|
||||
else:
|
||||
return self.val['lazy_str'].lazy_string()
|
||||
return self.val["lazy_str"].lazy_string()
|
||||
|
||||
def display_hint (self):
|
||||
return 'string'
|
||||
def display_hint(self):
|
||||
return "string"
|
||||
|
||||
class pp_hint_error (object):
|
||||
|
||||
class pp_hint_error(object):
|
||||
"Throw error from display_hint"
|
||||
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return 'hint_error_val'
|
||||
return "hint_error_val"
|
||||
|
||||
def display_hint (self):
|
||||
def display_hint(self):
|
||||
raise Exception("hint failed")
|
||||
|
||||
class pp_children_as_list (object):
|
||||
|
||||
class pp_children_as_list(object):
|
||||
"Throw error from display_hint"
|
||||
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return 'children_as_list_val'
|
||||
return "children_as_list_val"
|
||||
|
||||
def children (self):
|
||||
return [('one', 1)]
|
||||
def children(self):
|
||||
return [("one", 1)]
|
||||
|
||||
class pp_outer (object):
|
||||
|
||||
class pp_outer(object):
|
||||
"Print struct outer"
|
||||
|
||||
def __init__ (self, val):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string (self):
|
||||
return "x = %s" % self.val['x']
|
||||
def to_string(self):
|
||||
return "x = %s" % self.val["x"]
|
||||
|
||||
def children (self):
|
||||
yield 's', self.val['s']
|
||||
yield 'x', self.val['x']
|
||||
def children(self):
|
||||
yield "s", self.val["s"]
|
||||
yield "x", self.val["x"]
|
||||
|
||||
class MemoryErrorString (object):
|
||||
|
||||
class MemoryErrorString(object):
|
||||
"Raise an error"
|
||||
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
raise gdb.MemoryError ("Cannot access memory.")
|
||||
raise gdb.MemoryError("Cannot access memory.")
|
||||
|
||||
def display_hint (self):
|
||||
return 'string'
|
||||
def display_hint(self):
|
||||
return "string"
|
||||
|
||||
class pp_eval_type (object):
|
||||
|
||||
class pp_eval_type(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
gdb.execute("bt", to_string=True)
|
||||
return "eval=<" + str(gdb.parse_and_eval("eval_func (123456789, 2, 3, 4, 5, 6, 7, 8)")) + ">"
|
||||
return (
|
||||
"eval=<"
|
||||
+ str(gdb.parse_and_eval("eval_func (123456789, 2, 3, 4, 5, 6, 7, 8)"))
|
||||
+ ">"
|
||||
)
|
||||
|
||||
class pp_int_typedef (object):
|
||||
|
||||
class pp_int_typedef(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return "type=%s, val=%s" % (self.val.type, int(self.val))
|
||||
|
||||
class pp_int_typedef3 (object):
|
||||
|
||||
class pp_int_typedef3(object):
|
||||
"A printer without a to_string method"
|
||||
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def children(self):
|
||||
yield 's', 27
|
||||
yield "s", 27
|
||||
|
||||
def lookup_function (val):
|
||||
|
||||
def lookup_function(val):
|
||||
"Look-up and return a pretty-printer that can print val."
|
||||
|
||||
# Get the type.
|
||||
@@ -281,12 +306,12 @@ def lookup_function (val):
|
||||
|
||||
# If it points to a reference, get the reference.
|
||||
if type.code == gdb.TYPE_CODE_REF:
|
||||
type = type.target ()
|
||||
type = type.target()
|
||||
|
||||
# Get the unqualified type, stripped of typedefs.
|
||||
type = type.unqualified ().strip_typedefs ()
|
||||
type = type.unqualified().strip_typedefs()
|
||||
|
||||
# Get the type name.
|
||||
# Get the type name.
|
||||
typename = type.tag
|
||||
|
||||
if typename == None:
|
||||
@@ -296,21 +321,24 @@ def lookup_function (val):
|
||||
# if a printer is registered for that type. Return an
|
||||
# instantiation of the printer if found.
|
||||
for function in pretty_printers_dict:
|
||||
if function.match (typename):
|
||||
return pretty_printers_dict[function] (val)
|
||||
|
||||
if function.match(typename):
|
||||
return pretty_printers_dict[function](val)
|
||||
|
||||
# Cannot find a pretty printer. Return None.
|
||||
|
||||
return None
|
||||
|
||||
def disable_lookup_function ():
|
||||
|
||||
def disable_lookup_function():
|
||||
lookup_function.enabled = False
|
||||
|
||||
def enable_lookup_function ():
|
||||
|
||||
def enable_lookup_function():
|
||||
lookup_function.enabled = True
|
||||
|
||||
|
||||
# Lookup a printer for VAL in the typedefs dict.
|
||||
def lookup_typedefs_function (val):
|
||||
def lookup_typedefs_function(val):
|
||||
"Look-up and return a pretty-printer that can print val (typedefs)."
|
||||
|
||||
# Get the type.
|
||||
@@ -323,72 +351,82 @@ def lookup_typedefs_function (val):
|
||||
# printer is registered for that type. Return an instantiation of
|
||||
# the printer if found.
|
||||
for function in typedefs_pretty_printers_dict:
|
||||
if function.match (type.name):
|
||||
return typedefs_pretty_printers_dict[function] (val)
|
||||
if function.match(type.name):
|
||||
return typedefs_pretty_printers_dict[function](val)
|
||||
|
||||
# Cannot find a pretty printer.
|
||||
return None
|
||||
|
||||
def register_pretty_printers ():
|
||||
pretty_printers_dict[re.compile ('^struct s$')] = pp_s
|
||||
pretty_printers_dict[re.compile ('^s$')] = pp_s
|
||||
pretty_printers_dict[re.compile ('^S$')] = pp_s
|
||||
|
||||
pretty_printers_dict[re.compile ('^struct ss$')] = pp_ss
|
||||
pretty_printers_dict[re.compile ('^ss$')] = pp_ss
|
||||
pretty_printers_dict[re.compile ('^const S &$')] = pp_s
|
||||
pretty_printers_dict[re.compile ('^SSS$')] = pp_sss
|
||||
|
||||
pretty_printers_dict[re.compile ('^VirtualTest$')] = pp_multiple_virtual
|
||||
pretty_printers_dict[re.compile ('^Vbase1$')] = pp_vbase1
|
||||
def register_pretty_printers():
|
||||
pretty_printers_dict[re.compile("^struct s$")] = pp_s
|
||||
pretty_printers_dict[re.compile("^s$")] = pp_s
|
||||
pretty_printers_dict[re.compile("^S$")] = pp_s
|
||||
|
||||
pretty_printers_dict[re.compile("^struct ss$")] = pp_ss
|
||||
pretty_printers_dict[re.compile("^ss$")] = pp_ss
|
||||
pretty_printers_dict[re.compile("^const S &$")] = pp_s
|
||||
pretty_printers_dict[re.compile("^SSS$")] = pp_sss
|
||||
|
||||
pretty_printers_dict[re.compile("^VirtualTest$")] = pp_multiple_virtual
|
||||
pretty_printers_dict[re.compile("^Vbase1$")] = pp_vbase1
|
||||
|
||||
pretty_printers_dict[re.compile("^struct nullstr$")] = pp_nullstr
|
||||
pretty_printers_dict[re.compile("^nullstr$")] = pp_nullstr
|
||||
|
||||
pretty_printers_dict[re.compile ('^struct nullstr$')] = pp_nullstr
|
||||
pretty_printers_dict[re.compile ('^nullstr$')] = pp_nullstr
|
||||
|
||||
# Note that we purposely omit the typedef names here.
|
||||
# Printer lookup is based on canonical name.
|
||||
# However, we do need both tagged and untagged variants, to handle
|
||||
# both the C and C++ cases.
|
||||
pretty_printers_dict[re.compile ('^struct string_repr$')] = string_print
|
||||
pretty_printers_dict[re.compile ('^struct container$')] = ContainerPrinter
|
||||
pretty_printers_dict[re.compile ('^struct justchildren$')] = NoStringContainerPrinter
|
||||
pretty_printers_dict[re.compile ('^string_repr$')] = string_print
|
||||
pretty_printers_dict[re.compile ('^container$')] = ContainerPrinter
|
||||
pretty_printers_dict[re.compile ('^justchildren$')] = NoStringContainerPrinter
|
||||
pretty_printers_dict[re.compile("^struct string_repr$")] = string_print
|
||||
pretty_printers_dict[re.compile("^struct container$")] = ContainerPrinter
|
||||
pretty_printers_dict[re.compile("^struct justchildren$")] = NoStringContainerPrinter
|
||||
pretty_printers_dict[re.compile("^string_repr$")] = string_print
|
||||
pretty_printers_dict[re.compile("^container$")] = ContainerPrinter
|
||||
pretty_printers_dict[re.compile("^justchildren$")] = NoStringContainerPrinter
|
||||
|
||||
pretty_printers_dict[re.compile ('^struct to_string_returns_value_inner$')] = ToStringReturnsValueInner
|
||||
pretty_printers_dict[re.compile ('^to_string_returns_value_inner$')] = ToStringReturnsValueInner
|
||||
pretty_printers_dict[re.compile ('^struct to_string_returns_value_wrapper$')] = ToStringReturnsValueWrapper
|
||||
pretty_printers_dict[re.compile ('^to_string_returns_value_wrapper$')] = ToStringReturnsValueWrapper
|
||||
pretty_printers_dict[
|
||||
re.compile("^struct to_string_returns_value_inner$")
|
||||
] = ToStringReturnsValueInner
|
||||
pretty_printers_dict[
|
||||
re.compile("^to_string_returns_value_inner$")
|
||||
] = ToStringReturnsValueInner
|
||||
pretty_printers_dict[
|
||||
re.compile("^struct to_string_returns_value_wrapper$")
|
||||
] = ToStringReturnsValueWrapper
|
||||
pretty_printers_dict[
|
||||
re.compile("^to_string_returns_value_wrapper$")
|
||||
] = ToStringReturnsValueWrapper
|
||||
|
||||
pretty_printers_dict[re.compile ('^struct ns$')] = pp_ns
|
||||
pretty_printers_dict[re.compile ('^ns$')] = pp_ns
|
||||
pretty_printers_dict[re.compile("^struct ns$")] = pp_ns
|
||||
pretty_printers_dict[re.compile("^ns$")] = pp_ns
|
||||
|
||||
pretty_printers_dict[re.compile ('^struct lazystring$')] = pp_ls
|
||||
pretty_printers_dict[re.compile ('^lazystring$')] = pp_ls
|
||||
pretty_printers_dict[re.compile("^struct lazystring$")] = pp_ls
|
||||
pretty_printers_dict[re.compile("^lazystring$")] = pp_ls
|
||||
|
||||
pretty_printers_dict[re.compile ('^struct outerstruct$')] = pp_outer
|
||||
pretty_printers_dict[re.compile ('^outerstruct$')] = pp_outer
|
||||
pretty_printers_dict[re.compile("^struct outerstruct$")] = pp_outer
|
||||
pretty_printers_dict[re.compile("^outerstruct$")] = pp_outer
|
||||
|
||||
pretty_printers_dict[re.compile ('^struct hint_error$')] = pp_hint_error
|
||||
pretty_printers_dict[re.compile ('^hint_error$')] = pp_hint_error
|
||||
pretty_printers_dict[re.compile("^struct hint_error$")] = pp_hint_error
|
||||
pretty_printers_dict[re.compile("^hint_error$")] = pp_hint_error
|
||||
|
||||
pretty_printers_dict[re.compile ('^struct children_as_list$')] = pp_children_as_list
|
||||
pretty_printers_dict[re.compile ('^children_as_list$')] = pp_children_as_list
|
||||
pretty_printers_dict[re.compile("^struct children_as_list$")] = pp_children_as_list
|
||||
pretty_printers_dict[re.compile("^children_as_list$")] = pp_children_as_list
|
||||
|
||||
pretty_printers_dict[re.compile ('^memory_error$')] = MemoryErrorString
|
||||
pretty_printers_dict[re.compile("^memory_error$")] = MemoryErrorString
|
||||
|
||||
pretty_printers_dict[re.compile ('^eval_type_s$')] = pp_eval_type
|
||||
pretty_printers_dict[re.compile("^eval_type_s$")] = pp_eval_type
|
||||
|
||||
typedefs_pretty_printers_dict[re.compile("^int_type$")] = pp_int_typedef
|
||||
typedefs_pretty_printers_dict[re.compile("^int_type2$")] = pp_int_typedef
|
||||
typedefs_pretty_printers_dict[re.compile("^int_type3$")] = pp_int_typedef3
|
||||
|
||||
typedefs_pretty_printers_dict[re.compile ('^int_type$')] = pp_int_typedef
|
||||
typedefs_pretty_printers_dict[re.compile ('^int_type2$')] = pp_int_typedef
|
||||
typedefs_pretty_printers_dict[re.compile ('^int_type3$')] = pp_int_typedef3
|
||||
|
||||
# Dict for struct types with typedefs fully stripped.
|
||||
pretty_printers_dict = {}
|
||||
# Dict for typedef types.
|
||||
typedefs_pretty_printers_dict = {}
|
||||
|
||||
register_pretty_printers ()
|
||||
gdb.pretty_printers.append (lookup_function)
|
||||
gdb.pretty_printers.append (lookup_typedefs_function)
|
||||
register_pretty_printers()
|
||||
gdb.pretty_printers.append(lookup_function)
|
||||
gdb.pretty_printers.append(lookup_typedefs_function)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# This unwinder never does any unwinding. It'll (pretend to) "sniff"
|
||||
# the frame and ultimately return None, indicating that actual unwinding
|
||||
# should be performed by some other unwinder.
|
||||
#
|
||||
#
|
||||
# But, prior to returning None, it will attempt to obtain the value
|
||||
# associated with a symbol via a call to gdb.parse_and_eval(). In
|
||||
# the course of doing this evaluation, GDB will potentially access
|
||||
@@ -28,23 +28,24 @@
|
||||
import gdb
|
||||
from gdb.unwinder import Unwinder
|
||||
|
||||
|
||||
class TestUnwinder(Unwinder):
|
||||
|
||||
count = 0
|
||||
|
||||
@classmethod
|
||||
def reset_count (cls):
|
||||
def reset_count(cls):
|
||||
cls.count = 0
|
||||
|
||||
@classmethod
|
||||
def inc_count (cls):
|
||||
def inc_count(cls):
|
||||
cls.count += 1
|
||||
|
||||
test = 'check_undefined_symbol'
|
||||
test = "check_undefined_symbol"
|
||||
|
||||
@classmethod
|
||||
def set_test (cls, test) :
|
||||
cls.test = test
|
||||
def set_test(cls, test):
|
||||
cls.test = test
|
||||
|
||||
def __init__(self):
|
||||
Unwinder.__init__(self, "test unwinder")
|
||||
@@ -59,19 +60,19 @@ class TestUnwinder(Unwinder):
|
||||
self.recurse_level += 1
|
||||
TestUnwinder.inc_count()
|
||||
|
||||
if TestUnwinder.test == 'check_user_reg_pc' :
|
||||
if TestUnwinder.test == "check_user_reg_pc":
|
||||
|
||||
pc = pending_frame.read_register('pc')
|
||||
pc_as_int = int(pc.cast(gdb.lookup_type('int')))
|
||||
pc = pending_frame.read_register("pc")
|
||||
pc_as_int = int(pc.cast(gdb.lookup_type("int")))
|
||||
# gdb.write("In unwinder: pc=%x\n" % pc_as_int)
|
||||
|
||||
elif TestUnwinder.test == 'check_pae_pc' :
|
||||
elif TestUnwinder.test == "check_pae_pc":
|
||||
|
||||
pc = gdb.parse_and_eval('$pc')
|
||||
pc_as_int = int(pc.cast(gdb.lookup_type('int')))
|
||||
pc = gdb.parse_and_eval("$pc")
|
||||
pc_as_int = int(pc.cast(gdb.lookup_type("int")))
|
||||
# gdb.write("In unwinder: pc=%x\n" % pc_as_int)
|
||||
|
||||
elif TestUnwinder.test == 'check_undefined_symbol' :
|
||||
elif TestUnwinder.test == "check_undefined_symbol":
|
||||
|
||||
try:
|
||||
val = gdb.parse_and_eval("undefined_symbol")
|
||||
@@ -83,5 +84,6 @@ class TestUnwinder(Unwinder):
|
||||
|
||||
return None
|
||||
|
||||
|
||||
gdb.unwinder.register_unwinder(None, TestUnwinder(), True)
|
||||
gdb.write("Python script imported\n")
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import re
|
||||
|
||||
|
||||
class pp_ss:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
@@ -24,7 +25,8 @@ class pp_ss:
|
||||
def to_string(self):
|
||||
return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
||||
|
||||
def lookup_function (val):
|
||||
|
||||
def lookup_function(val):
|
||||
"Look-up and return a pretty-printer that can print val."
|
||||
|
||||
# Get the type.
|
||||
@@ -32,12 +34,12 @@ def lookup_function (val):
|
||||
|
||||
# If it points to a reference, get the reference.
|
||||
if type.code == gdb.TYPE_CODE_REF:
|
||||
type = type.target ()
|
||||
type = type.target()
|
||||
|
||||
# Get the unqualified type, stripped of typedefs.
|
||||
type = type.unqualified ().strip_typedefs ()
|
||||
type = type.unqualified().strip_typedefs()
|
||||
|
||||
# Get the type name.
|
||||
# Get the type name.
|
||||
typename = type.tag
|
||||
|
||||
if typename == None:
|
||||
@@ -47,17 +49,19 @@ def lookup_function (val):
|
||||
# if a printer is registered for that type. Return an
|
||||
# instantiation of the printer if found.
|
||||
for function in pretty_printers_dict:
|
||||
if function.match (typename):
|
||||
return pretty_printers_dict[function] (val)
|
||||
|
||||
if function.match(typename):
|
||||
return pretty_printers_dict[function](val)
|
||||
|
||||
# Cannot find a pretty printer. Return None.
|
||||
|
||||
return None
|
||||
|
||||
def register_pretty_printers ():
|
||||
pretty_printers_dict[re.compile ('^ss$')] = pp_ss
|
||||
|
||||
def register_pretty_printers():
|
||||
pretty_printers_dict[re.compile("^ss$")] = pp_ss
|
||||
|
||||
|
||||
pretty_printers_dict = {}
|
||||
|
||||
register_pretty_printers ()
|
||||
gdb.current_progspace().pretty_printers.append (lookup_function)
|
||||
register_pretty_printers()
|
||||
gdb.current_progspace().pretty_printers.append(lookup_function)
|
||||
|
||||
@@ -15,21 +15,24 @@
|
||||
|
||||
import gdb
|
||||
|
||||
|
||||
class Recognizer(object):
|
||||
def __init__(self):
|
||||
self.enabled = True
|
||||
|
||||
def recognize(self, type_obj):
|
||||
if type_obj.tag == 'basic_string':
|
||||
return 'string'
|
||||
if type_obj.tag == "basic_string":
|
||||
return "string"
|
||||
return None
|
||||
|
||||
|
||||
class StringTypePrinter(object):
|
||||
def __init__(self):
|
||||
self.name = 'string'
|
||||
self.name = "string"
|
||||
self.enabled = True
|
||||
|
||||
def instantiate(self):
|
||||
return Recognizer()
|
||||
|
||||
|
||||
gdb.type_printers.append(StringTypePrinter())
|
||||
|
||||
@@ -23,49 +23,50 @@ from gdb.unwinder import Unwinder
|
||||
|
||||
apb_global = None
|
||||
|
||||
class dummy_unwinder (Unwinder):
|
||||
""" A dummy unwinder that looks at a bunch of registers as part of
|
||||
|
||||
class dummy_unwinder(Unwinder):
|
||||
"""A dummy unwinder that looks at a bunch of registers as part of
|
||||
the unwinding process."""
|
||||
|
||||
class frame_id (object):
|
||||
""" Basic frame id."""
|
||||
class frame_id(object):
|
||||
"""Basic frame id."""
|
||||
|
||||
def __init__ (self, sp, pc):
|
||||
""" Create the frame id."""
|
||||
def __init__(self, sp, pc):
|
||||
"""Create the frame id."""
|
||||
self.sp = sp
|
||||
self.pc = pc
|
||||
|
||||
def __init__ (self):
|
||||
def __init__(self):
|
||||
"""Create the unwinder."""
|
||||
Unwinder.__init__ (self, "dummy stack unwinder")
|
||||
Unwinder.__init__(self, "dummy stack unwinder")
|
||||
self.void_ptr_t = gdb.lookup_type("void").pointer()
|
||||
self.regs = None
|
||||
|
||||
def get_regs (self, pending_frame):
|
||||
def get_regs(self, pending_frame):
|
||||
"""Return a list of register names that should be read. Only
|
||||
gathers the list once, then caches the result."""
|
||||
if (self.regs != None):
|
||||
if self.regs != None:
|
||||
return self.regs
|
||||
|
||||
# Collect the names of all registers to read.
|
||||
self.regs = list (pending_frame.architecture ()
|
||||
.register_names ())
|
||||
self.regs = list(pending_frame.architecture().register_names())
|
||||
|
||||
return self.regs
|
||||
|
||||
def __call__ (self, pending_frame):
|
||||
def __call__(self, pending_frame):
|
||||
"""Actually performs the unwind, or at least sniffs this frame
|
||||
to see if the unwinder should claim it, which is never does."""
|
||||
try:
|
||||
for r in (self.get_regs (pending_frame)):
|
||||
v = pending_frame.read_register (r).cast (self.void_ptr_t)
|
||||
for r in self.get_regs(pending_frame):
|
||||
v = pending_frame.read_register(r).cast(self.void_ptr_t)
|
||||
except:
|
||||
print ("Dummy unwinder, exception")
|
||||
print("Dummy unwinder, exception")
|
||||
raise
|
||||
|
||||
return None
|
||||
|
||||
# Register the ComRV stack unwinder.
|
||||
gdb.unwinder.register_unwinder (None, dummy_unwinder (), True)
|
||||
|
||||
print ("Python script imported")
|
||||
# Register the ComRV stack unwinder.
|
||||
gdb.unwinder.register_unwinder(None, dummy_unwinder(), True)
|
||||
|
||||
print("Python script imported")
|
||||
|
||||
@@ -19,6 +19,7 @@ import re
|
||||
import gdb.types
|
||||
from gdb.unwinder import Unwinder, register_unwinder
|
||||
|
||||
|
||||
class TestGlobalUnwinder(Unwinder):
|
||||
def __init__(self):
|
||||
super(TestGlobalUnwinder, self).__init__("global_unwinder")
|
||||
@@ -27,6 +28,7 @@ class TestGlobalUnwinder(Unwinder):
|
||||
print("%s called" % self.name)
|
||||
return None
|
||||
|
||||
|
||||
class TestProgspaceUnwinder(Unwinder):
|
||||
def __init__(self, name):
|
||||
super(TestProgspaceUnwinder, self).__init__("%s_ps_unwinder" % name)
|
||||
@@ -35,6 +37,7 @@ class TestProgspaceUnwinder(Unwinder):
|
||||
print("%s called" % self.name)
|
||||
return None
|
||||
|
||||
|
||||
class TestObjfileUnwinder(Unwinder):
|
||||
def __init__(self, name):
|
||||
super(TestObjfileUnwinder, self).__init__("%s_obj_unwinder" % name)
|
||||
@@ -44,7 +47,6 @@ class TestObjfileUnwinder(Unwinder):
|
||||
return None
|
||||
|
||||
|
||||
|
||||
gdb.unwinder.register_unwinder(None, TestGlobalUnwinder())
|
||||
saw_runtime_error = False
|
||||
try:
|
||||
@@ -54,6 +56,7 @@ except RuntimeError:
|
||||
if not saw_runtime_error:
|
||||
raise RuntimeError("Missing runtime error from register_unwinder.")
|
||||
gdb.unwinder.register_unwinder(None, TestGlobalUnwinder(), replace=True)
|
||||
gdb.unwinder.register_unwinder(gdb.current_progspace(),
|
||||
TestProgspaceUnwinder("py_unwind_maint"))
|
||||
gdb.unwinder.register_unwinder(
|
||||
gdb.current_progspace(), TestProgspaceUnwinder("py_unwind_maint")
|
||||
)
|
||||
print("Python script imported")
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
import gdb
|
||||
from gdb.unwinder import Unwinder
|
||||
|
||||
class FrameId(object):
|
||||
|
||||
class FrameId(object):
|
||||
def __init__(self, sp, pc):
|
||||
self._sp = sp
|
||||
self._pc = pc
|
||||
@@ -30,6 +30,7 @@ class FrameId(object):
|
||||
def pc(self):
|
||||
return self._pc
|
||||
|
||||
|
||||
class TestUnwinder(Unwinder):
|
||||
AMD64_RBP = 6
|
||||
AMD64_RSP = 7
|
||||
@@ -42,9 +43,9 @@ class TestUnwinder(Unwinder):
|
||||
self._last_arch = None
|
||||
|
||||
# Update the register descriptor AMD64_RIP based on ARCH.
|
||||
def _update_register_descriptors (self, arch):
|
||||
if (self._last_arch != arch):
|
||||
TestUnwinder.AMD64_RIP = arch.registers ().find ("rip")
|
||||
def _update_register_descriptors(self, arch):
|
||||
if self._last_arch != arch:
|
||||
TestUnwinder.AMD64_RIP = arch.registers().find("rip")
|
||||
self._last_arch = arch
|
||||
|
||||
def _read_word(self, address):
|
||||
@@ -79,12 +80,12 @@ class TestUnwinder(Unwinder):
|
||||
# Check that we can access the architecture of the pending
|
||||
# frame, and that this is the same architecture as for the
|
||||
# currently selected inferior.
|
||||
inf_arch = gdb.selected_inferior ().architecture ()
|
||||
frame_arch = pending_frame.architecture ()
|
||||
if (inf_arch != frame_arch):
|
||||
raise gdb.GdbError ("architecture mismatch")
|
||||
inf_arch = gdb.selected_inferior().architecture()
|
||||
frame_arch = pending_frame.architecture()
|
||||
if inf_arch != frame_arch:
|
||||
raise gdb.GdbError("architecture mismatch")
|
||||
|
||||
self._update_register_descriptors (frame_arch)
|
||||
self._update_register_descriptors(frame_arch)
|
||||
|
||||
try:
|
||||
# NOTE: the registers in Unwinder API can be referenced
|
||||
@@ -102,15 +103,16 @@ class TestUnwinder(Unwinder):
|
||||
|
||||
frame_id = FrameId(
|
||||
pending_frame.read_register(TestUnwinder.AMD64_RSP),
|
||||
pending_frame.read_register(TestUnwinder.AMD64_RIP))
|
||||
pending_frame.read_register(TestUnwinder.AMD64_RIP),
|
||||
)
|
||||
unwind_info = pending_frame.create_unwind_info(frame_id)
|
||||
unwind_info.add_saved_register(TestUnwinder.AMD64_RBP,
|
||||
previous_bp)
|
||||
unwind_info.add_saved_register(TestUnwinder.AMD64_RBP, previous_bp)
|
||||
unwind_info.add_saved_register("rip", previous_ip)
|
||||
unwind_info.add_saved_register("rsp", previous_sp)
|
||||
return unwind_info
|
||||
except (gdb.error, RuntimeError):
|
||||
return None
|
||||
|
||||
|
||||
gdb.unwinder.register_unwinder(None, TestUnwinder(), True)
|
||||
print("Python script imported")
|
||||
|
||||
@@ -25,52 +25,55 @@ from gdb.xmethod import SimpleXMethodMatcher
|
||||
|
||||
|
||||
def A_plus_A(obj, opr):
|
||||
print('From Python <A_plus_A>:')
|
||||
return obj['a'] + opr['a']
|
||||
print("From Python <A_plus_A>:")
|
||||
return obj["a"] + opr["a"]
|
||||
|
||||
|
||||
def plus_plus_A(obj):
|
||||
print('From Python <plus_plus_A>:')
|
||||
return obj['a'] + 1
|
||||
print("From Python <plus_plus_A>:")
|
||||
return obj["a"] + 1
|
||||
|
||||
|
||||
def A_geta(obj):
|
||||
print('From Python <A_geta>:')
|
||||
return obj['a']
|
||||
print("From Python <A_geta>:")
|
||||
return obj["a"]
|
||||
|
||||
|
||||
def A_getarrayind(obj, index):
|
||||
print('From Python <A_getarrayind>:')
|
||||
return obj['array'][index]
|
||||
print("From Python <A_getarrayind>:")
|
||||
return obj["array"][index]
|
||||
|
||||
|
||||
def A_indexoper(obj, index):
|
||||
return obj['array'][index].reference_value()
|
||||
return obj["array"][index].reference_value()
|
||||
|
||||
|
||||
def B_indexoper(obj, index):
|
||||
return obj['array'][index].const_value().reference_value()
|
||||
return obj["array"][index].const_value().reference_value()
|
||||
|
||||
|
||||
type_A = gdb.parse_and_eval('(dop::A *) 0').type.target()
|
||||
type_B = gdb.parse_and_eval('(dop::B *) 0').type.target()
|
||||
type_int = gdb.parse_and_eval('(int *) 0').type.target()
|
||||
type_A = gdb.parse_and_eval("(dop::A *) 0").type.target()
|
||||
type_B = gdb.parse_and_eval("(dop::B *) 0").type.target()
|
||||
type_int = gdb.parse_and_eval("(int *) 0").type.target()
|
||||
|
||||
|
||||
# The E class matcher and worker test two things:
|
||||
# 1. xmethod returning None.
|
||||
# 2. Matcher returning a list of workers.
|
||||
|
||||
|
||||
class E_method_char_worker(XMethodWorker):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get_arg_types(self):
|
||||
return gdb.lookup_type('char')
|
||||
return gdb.lookup_type("char")
|
||||
|
||||
def get_result_type(self, obj, arg):
|
||||
return gdb.lookup_type('void')
|
||||
return gdb.lookup_type("void")
|
||||
|
||||
def __call__(self, obj, arg):
|
||||
print('From Python <E_method_char>')
|
||||
print("From Python <E_method_char>")
|
||||
return None
|
||||
|
||||
|
||||
@@ -79,25 +82,25 @@ class E_method_int_worker(XMethodWorker):
|
||||
pass
|
||||
|
||||
def get_arg_types(self):
|
||||
return gdb.lookup_type('int')
|
||||
return gdb.lookup_type("int")
|
||||
|
||||
# Note: get_result_type method elided on purpose
|
||||
|
||||
def __call__(self, obj, arg):
|
||||
print('From Python <E_method_int>')
|
||||
print("From Python <E_method_int>")
|
||||
return None
|
||||
|
||||
|
||||
class E_method_matcher(XMethodMatcher):
|
||||
def __init__(self):
|
||||
XMethodMatcher.__init__(self, 'E_methods')
|
||||
self.methods = [XMethod('method_int'), XMethod('method_char')]
|
||||
XMethodMatcher.__init__(self, "E_methods")
|
||||
self.methods = [XMethod("method_int"), XMethod("method_char")]
|
||||
|
||||
def match(self, class_type, method_name):
|
||||
class_tag = class_type.unqualified().tag
|
||||
if not re.match('^dop::E$', class_tag):
|
||||
if not re.match("^dop::E$", class_tag):
|
||||
return None
|
||||
if not re.match('^method$', method_name):
|
||||
if not re.match("^method$", method_name):
|
||||
return None
|
||||
workers = []
|
||||
if self.methods[0].enabled:
|
||||
@@ -111,6 +114,7 @@ class E_method_matcher(XMethodMatcher):
|
||||
# xmethod matchers and workers for template classes and template
|
||||
# methods.
|
||||
|
||||
|
||||
class G_size_diff_worker(XMethodWorker):
|
||||
def __init__(self, class_template_type, method_template_type):
|
||||
self._class_template_type = class_template_type
|
||||
@@ -120,9 +124,8 @@ class G_size_diff_worker(XMethodWorker):
|
||||
pass
|
||||
|
||||
def __call__(self, obj):
|
||||
print('From Python G<>::size_diff()')
|
||||
return (self._method_template_type.sizeof -
|
||||
self._class_template_type.sizeof)
|
||||
print("From Python G<>::size_diff()")
|
||||
return self._method_template_type.sizeof - self._class_template_type.sizeof
|
||||
|
||||
|
||||
class G_size_mul_worker(XMethodWorker):
|
||||
@@ -134,7 +137,7 @@ class G_size_mul_worker(XMethodWorker):
|
||||
pass
|
||||
|
||||
def __call__(self, obj):
|
||||
print('From Python G<>::size_mul()')
|
||||
print("From Python G<>::size_mul()")
|
||||
return self._class_template_type.sizeof * self._method_template_val
|
||||
|
||||
|
||||
@@ -147,16 +150,14 @@ class G_mul_worker(XMethodWorker):
|
||||
return self._method_template_type
|
||||
|
||||
def __call__(self, obj, arg):
|
||||
print('From Python G<>::mul()')
|
||||
return obj['t'] * arg
|
||||
print("From Python G<>::mul()")
|
||||
return obj["t"] * arg
|
||||
|
||||
|
||||
class G_methods_matcher(XMethodMatcher):
|
||||
def __init__(self):
|
||||
XMethodMatcher.__init__(self, 'G_methods')
|
||||
self.methods = [XMethod('size_diff'),
|
||||
XMethod('size_mul'),
|
||||
XMethod('mul')]
|
||||
XMethodMatcher.__init__(self, "G_methods")
|
||||
self.methods = [XMethod("size_diff"), XMethod("size_mul"), XMethod("mul")]
|
||||
|
||||
def _is_enabled(self, name):
|
||||
for method in self.methods:
|
||||
@@ -165,16 +166,15 @@ class G_methods_matcher(XMethodMatcher):
|
||||
|
||||
def match(self, class_type, method_name):
|
||||
class_tag = class_type.unqualified().tag
|
||||
if not re.match('^dop::G<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$',
|
||||
class_tag):
|
||||
if not re.match("^dop::G<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$", class_tag):
|
||||
return None
|
||||
t_name = class_tag[7:-1]
|
||||
try:
|
||||
t_type = gdb.lookup_type(t_name)
|
||||
except gdb.error:
|
||||
return None
|
||||
if re.match('^size_diff<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$', method_name):
|
||||
if not self._is_enabled('size_diff'):
|
||||
if re.match("^size_diff<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$", method_name):
|
||||
if not self._is_enabled("size_diff"):
|
||||
return None
|
||||
t1_name = method_name[10:-1]
|
||||
try:
|
||||
@@ -182,13 +182,13 @@ class G_methods_matcher(XMethodMatcher):
|
||||
return G_size_diff_worker(t_type, t1_type)
|
||||
except gdb.error:
|
||||
return None
|
||||
if re.match('^size_mul<[ ]*[0-9]+[ ]*>$', method_name):
|
||||
if not self._is_enabled('size_mul'):
|
||||
if re.match("^size_mul<[ ]*[0-9]+[ ]*>$", method_name):
|
||||
if not self._is_enabled("size_mul"):
|
||||
return None
|
||||
m_val = int(method_name[9:-1])
|
||||
return G_size_mul_worker(t_type, m_val)
|
||||
if re.match('^mul<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$', method_name):
|
||||
if not self._is_enabled('mul'):
|
||||
if re.match("^mul<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$", method_name):
|
||||
if not self._is_enabled("mul"):
|
||||
return None
|
||||
t1_name = method_name[4:-1]
|
||||
try:
|
||||
@@ -199,41 +199,29 @@ class G_methods_matcher(XMethodMatcher):
|
||||
|
||||
|
||||
global_dm_list = [
|
||||
SimpleXMethodMatcher(r'A_plus_A',
|
||||
r'^dop::A$',
|
||||
r'operator\+',
|
||||
A_plus_A,
|
||||
# This is a replacement, hence match the arg type
|
||||
# exactly!
|
||||
type_A.const().reference()),
|
||||
SimpleXMethodMatcher(r'plus_plus_A',
|
||||
r'^dop::A$',
|
||||
r'operator\+\+',
|
||||
plus_plus_A),
|
||||
SimpleXMethodMatcher(r'A_geta',
|
||||
r'^dop::A$',
|
||||
r'^geta$',
|
||||
A_geta),
|
||||
SimpleXMethodMatcher(r'A_getarrayind',
|
||||
r'^dop::A$',
|
||||
r'^getarrayind$',
|
||||
A_getarrayind,
|
||||
type_int),
|
||||
SimpleXMethodMatcher(r'A_indexoper',
|
||||
r'^dop::A$',
|
||||
r'operator\[\]',
|
||||
A_indexoper,
|
||||
type_int),
|
||||
SimpleXMethodMatcher(r'B_indexoper',
|
||||
r'^dop::B$',
|
||||
r'operator\[\]',
|
||||
B_indexoper,
|
||||
type_int)
|
||||
SimpleXMethodMatcher(
|
||||
r"A_plus_A",
|
||||
r"^dop::A$",
|
||||
r"operator\+",
|
||||
A_plus_A,
|
||||
# This is a replacement, hence match the arg type
|
||||
# exactly!
|
||||
type_A.const().reference(),
|
||||
),
|
||||
SimpleXMethodMatcher(r"plus_plus_A", r"^dop::A$", r"operator\+\+", plus_plus_A),
|
||||
SimpleXMethodMatcher(r"A_geta", r"^dop::A$", r"^geta$", A_geta),
|
||||
SimpleXMethodMatcher(
|
||||
r"A_getarrayind", r"^dop::A$", r"^getarrayind$", A_getarrayind, type_int
|
||||
),
|
||||
SimpleXMethodMatcher(
|
||||
r"A_indexoper", r"^dop::A$", r"operator\[\]", A_indexoper, type_int
|
||||
),
|
||||
SimpleXMethodMatcher(
|
||||
r"B_indexoper", r"^dop::B$", r"operator\[\]", B_indexoper, type_int
|
||||
),
|
||||
]
|
||||
|
||||
for matcher in global_dm_list:
|
||||
gdb.xmethod.register_xmethod_matcher(gdb, matcher)
|
||||
gdb.xmethod.register_xmethod_matcher(gdb.current_progspace(),
|
||||
G_methods_matcher())
|
||||
gdb.xmethod.register_xmethod_matcher(gdb.current_progspace(),
|
||||
E_method_matcher())
|
||||
gdb.xmethod.register_xmethod_matcher(gdb.current_progspace(), G_methods_matcher())
|
||||
gdb.xmethod.register_xmethod_matcher(gdb.current_progspace(), E_method_matcher())
|
||||
|
||||
@@ -15,4 +15,4 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
print ('y%ss' % 'e')
|
||||
print("y%ss" % "e")
|
||||
|
||||
@@ -28,62 +28,65 @@ cleanup_properly = False
|
||||
# A global place into which we can write the window title.
|
||||
titles_at_the_close = {}
|
||||
|
||||
|
||||
class EventWindow:
|
||||
def __init__ (self, win):
|
||||
def __init__(self, win):
|
||||
self._win = win
|
||||
self._count = 0
|
||||
win.title = "This Is The Event Window"
|
||||
self._stop_listener = lambda e : self._event ('stop', e)
|
||||
gdb.events.stop.connect (self._stop_listener)
|
||||
self._exit_listener = lambda e : self._event ('exit', e)
|
||||
gdb.events.exited.connect (self._exit_listener)
|
||||
self._stop_listener = lambda e: self._event("stop", e)
|
||||
gdb.events.stop.connect(self._stop_listener)
|
||||
self._exit_listener = lambda e: self._event("exit", e)
|
||||
gdb.events.exited.connect(self._exit_listener)
|
||||
self._events = []
|
||||
|
||||
# Ensure we can erase and write to the window from the
|
||||
# constructor, the window should be valid by this point.
|
||||
self._win.erase ()
|
||||
self._win.write ("Hello world...")
|
||||
self._win.erase()
|
||||
self._win.write("Hello world...")
|
||||
|
||||
def close (self):
|
||||
def close(self):
|
||||
global cleanup_properly
|
||||
global titles_at_the_close
|
||||
|
||||
# Ensure that window properties can be read within the close method.
|
||||
titles_at_the_close[self._win.title] = dict (width=self._win.width,
|
||||
height=self._win.height)
|
||||
titles_at_the_close[self._win.title] = dict(
|
||||
width=self._win.width, height=self._win.height
|
||||
)
|
||||
|
||||
# The following calls are pretty pointless, but this ensures
|
||||
# that we can erase and write to a window from the close
|
||||
# method, the last moment a window should be valid.
|
||||
self._win.erase ()
|
||||
self._win.write ("Goodbye cruel world...")
|
||||
self._win.erase()
|
||||
self._win.write("Goodbye cruel world...")
|
||||
|
||||
if cleanup_properly:
|
||||
# Disconnect the listeners and delete the lambda functions.
|
||||
# This removes cyclic references to SELF, and so alows SELF to
|
||||
# be deleted.
|
||||
gdb.events.stop.disconnect (self._stop_listener)
|
||||
gdb.events.exited.disconnect (self._exit_listener)
|
||||
gdb.events.stop.disconnect(self._stop_listener)
|
||||
gdb.events.exited.disconnect(self._exit_listener)
|
||||
self._stop_listener = None
|
||||
self._exit_listener = None
|
||||
|
||||
def _event (self, type, event):
|
||||
def _event(self, type, event):
|
||||
global perform_valid_check
|
||||
global update_title
|
||||
|
||||
self._count += 1
|
||||
self._events.insert (0, type)
|
||||
if not perform_valid_check or self._win.is_valid ():
|
||||
self._events.insert(0, type)
|
||||
if not perform_valid_check or self._win.is_valid():
|
||||
if update_title:
|
||||
self._win.title = "This Is The Event Window (" + str (self._count) + ")"
|
||||
self._win.title = "This Is The Event Window (" + str(self._count) + ")"
|
||||
else:
|
||||
self.render ()
|
||||
self.render()
|
||||
|
||||
def render (self):
|
||||
self._win.erase ()
|
||||
def render(self):
|
||||
self._win.erase()
|
||||
w = self._win.width
|
||||
h = self._win.height
|
||||
for i in range (min (h, len (self._events))):
|
||||
self._win.write (self._events[i] + "\n")
|
||||
for i in range(min(h, len(self._events))):
|
||||
self._win.write(self._events[i] + "\n")
|
||||
|
||||
|
||||
gdb.register_window_type("events", EventWindow)
|
||||
|
||||
@@ -19,6 +19,7 @@ import gdb
|
||||
|
||||
the_window = None
|
||||
|
||||
|
||||
class TestWindow:
|
||||
def __init__(self, win):
|
||||
global the_window
|
||||
@@ -38,14 +39,17 @@ class TestWindow:
|
||||
def remove_title(self):
|
||||
del self.win.title
|
||||
|
||||
|
||||
gdb.register_window_type("test", TestWindow)
|
||||
|
||||
# Call REMOVE_TITLE on the global window object.
|
||||
def delete_window_title ():
|
||||
the_window.remove_title ()
|
||||
def delete_window_title():
|
||||
the_window.remove_title()
|
||||
|
||||
|
||||
# A TUI window "constructor" that always fails.
|
||||
def failwin(win):
|
||||
raise RuntimeError("Whoops")
|
||||
|
||||
|
||||
gdb.register_window_type("fail", failwin)
|
||||
|
||||
@@ -38,11 +38,12 @@ import os
|
||||
if len(sys.argv) > 1:
|
||||
fmt = sys.argv[1]
|
||||
else:
|
||||
fmt = '[%b %d %H:%M:%S]'
|
||||
fmt = "[%b %d %H:%M:%S]"
|
||||
|
||||
mypid = os.getpid()
|
||||
|
||||
for line in fileinput.input('-'):
|
||||
sys.stdout.write("{} [{}] {}".format(datetime.datetime.now().strftime(fmt),
|
||||
mypid, line))
|
||||
for line in fileinput.input("-"):
|
||||
sys.stdout.write(
|
||||
"{} [{}] {}".format(datetime.datetime.now().strftime(fmt), mypid, line)
|
||||
)
|
||||
sys.stdout.flush()
|
||||
|
||||
Reference in New Issue
Block a user