forked from Imagelibrary/binutils-gdb
Compare commits
1 Commits
users/jema
...
users/sima
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c45c0c0fa |
@@ -39,7 +39,7 @@ to those that gdb produces.
|
|||||||
Finally, check that all strings are canonicalized identically.
|
Finally, check that all strings are canonicalized identically.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'saugustine@google.com (Sterling Augustine)'
|
__author__ = "saugustine@google.com (Sterling Augustine)"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -49,24 +49,25 @@ OBJCOPY = None
|
|||||||
READELF = None
|
READELF = None
|
||||||
GDB = None
|
GDB = None
|
||||||
|
|
||||||
|
|
||||||
def get_pub_info(filename, readelf_option):
|
def get_pub_info(filename, readelf_option):
|
||||||
"""Parse and return all the pubnames or pubtypes produced by readelf with the
|
"""Parse and return all the pubnames or pubtypes produced by readelf with the
|
||||||
given option.
|
given option.
|
||||||
"""
|
"""
|
||||||
readelf = subprocess.Popen([READELF, '--debug-dump=' + readelf_option,
|
readelf = subprocess.Popen(
|
||||||
filename], stdout=subprocess.PIPE)
|
[READELF, "--debug-dump=" + readelf_option, filename], stdout=subprocess.PIPE
|
||||||
|
)
|
||||||
pubnames = []
|
pubnames = []
|
||||||
|
|
||||||
in_list = False;
|
in_list = False
|
||||||
for line in readelf.stdout:
|
for line in readelf.stdout:
|
||||||
fields = line.split(None, 1)
|
fields = line.split(None, 1)
|
||||||
if (len(fields) == 2 and fields[0] == 'Offset'
|
if len(fields) == 2 and fields[0] == "Offset" and fields[1].strip() == "Name":
|
||||||
and fields[1].strip() == 'Name'):
|
|
||||||
in_list = True
|
in_list = True
|
||||||
# Either a blank-line or a new Length field terminates the current section.
|
# Either a blank-line or a new Length field terminates the current section.
|
||||||
elif (len(fields) == 0 or fields[0] == 'Length:'):
|
elif len(fields) == 0 or fields[0] == "Length:":
|
||||||
in_list = False;
|
in_list = False
|
||||||
elif (in_list):
|
elif in_list:
|
||||||
pubnames.append(fields[1].strip())
|
pubnames.append(fields[1].strip())
|
||||||
|
|
||||||
readelf.wait()
|
readelf.wait()
|
||||||
@@ -75,18 +76,19 @@ def get_pub_info(filename, readelf_option):
|
|||||||
|
|
||||||
def get_gdb_index(filename):
|
def get_gdb_index(filename):
|
||||||
"""Use readelf to dump the gdb index and collect the types and names"""
|
"""Use readelf to dump the gdb index and collect the types and names"""
|
||||||
readelf = subprocess.Popen([READELF, '--debug-dump=gdb_index',
|
readelf = subprocess.Popen(
|
||||||
filename], stdout=subprocess.PIPE)
|
[READELF, "--debug-dump=gdb_index", filename], stdout=subprocess.PIPE
|
||||||
|
)
|
||||||
index_symbols = []
|
index_symbols = []
|
||||||
symbol_table_started = False
|
symbol_table_started = False
|
||||||
for line in readelf.stdout:
|
for line in readelf.stdout:
|
||||||
if (line == 'Symbol table:\n'):
|
if line == "Symbol table:\n":
|
||||||
symbol_table_started = True;
|
symbol_table_started = True
|
||||||
elif (symbol_table_started):
|
elif symbol_table_started:
|
||||||
# Readelf prints gdb-index lines formatted like so:
|
# Readelf prints gdb-index lines formatted like so:
|
||||||
# [ 4] two::c2<double>::c2: 0
|
# [ 4] two::c2<double>::c2: 0
|
||||||
# So take the string between the first close bracket and the last colon.
|
# So take the string between the first close bracket and the last colon.
|
||||||
index_symbols.append(line[line.find(']') + 2: line.rfind(':')])
|
index_symbols.append(line[line.find("]") + 2 : line.rfind(":")])
|
||||||
|
|
||||||
readelf.wait()
|
readelf.wait()
|
||||||
return index_symbols
|
return index_symbols
|
||||||
@@ -114,7 +116,7 @@ def CheckSets(list0, list1, name0, name1):
|
|||||||
for element in difference1:
|
for element in difference1:
|
||||||
print " " + element
|
print " " + element
|
||||||
|
|
||||||
if (len(difference0) != 0 or len(difference1) != 0):
|
if len(difference0) != 0 or len(difference1) != 0:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
print name0 + " and " + name1 + " are identical."
|
print name0 + " and " + name1 + " are identical."
|
||||||
@@ -125,26 +127,26 @@ def find_executables():
|
|||||||
"""Find the copies of readelf, objcopy and gdb to use."""
|
"""Find the copies of readelf, objcopy and gdb to use."""
|
||||||
# Executable finding logic follows cc-with-index.sh
|
# Executable finding logic follows cc-with-index.sh
|
||||||
global READELF
|
global READELF
|
||||||
READELF = os.getenv('READELF')
|
READELF = os.getenv("READELF")
|
||||||
if READELF is None:
|
if READELF is None:
|
||||||
READELF = 'readelf'
|
READELF = "readelf"
|
||||||
global OBJCOPY
|
global OBJCOPY
|
||||||
OBJCOPY = os.getenv('OBJCOPY')
|
OBJCOPY = os.getenv("OBJCOPY")
|
||||||
if OBJCOPY is None:
|
if OBJCOPY is None:
|
||||||
OBJCOPY = 'objcopy'
|
OBJCOPY = "objcopy"
|
||||||
|
|
||||||
global GDB
|
global GDB
|
||||||
GDB = os.getenv('GDB')
|
GDB = os.getenv("GDB")
|
||||||
if (GDB is None):
|
if GDB is None:
|
||||||
if os.path.isfile('./gdb') and os.access('./gdb', os.X_OK):
|
if os.path.isfile("./gdb") and os.access("./gdb", os.X_OK):
|
||||||
GDB = './gdb'
|
GDB = "./gdb"
|
||||||
elif os.path.isfile('../gdb') and os.access('../gdb', os.X_OK):
|
elif os.path.isfile("../gdb") and os.access("../gdb", os.X_OK):
|
||||||
GDB = '../gdb'
|
GDB = "../gdb"
|
||||||
elif os.path.isfile('../../gdb') and os.access('../../gdb', os.X_OK):
|
elif os.path.isfile("../../gdb") and os.access("../../gdb", os.X_OK):
|
||||||
GDB = '../../gdb'
|
GDB = "../../gdb"
|
||||||
else:
|
else:
|
||||||
# Punt and use the gdb in the path.
|
# Punt and use the gdb in the path.
|
||||||
GDB = 'gdb'
|
GDB = "gdb"
|
||||||
|
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
@@ -153,7 +155,7 @@ def main(argv):
|
|||||||
print "Usage: test_pubnames_and_indexes.py <filename>"
|
print "Usage: test_pubnames_and_indexes.py <filename>"
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
find_executables();
|
find_executables()
|
||||||
|
|
||||||
# Get the index produced by Gold--It should have been built into the binary.
|
# Get the index produced by Gold--It should have been built into the binary.
|
||||||
gold_index = get_gdb_index(argv[1])
|
gold_index = get_gdb_index(argv[1])
|
||||||
@@ -163,18 +165,33 @@ def main(argv):
|
|||||||
pubs_list = pubs_list + get_pub_info(argv[1], "pubtypes")
|
pubs_list = pubs_list + get_pub_info(argv[1], "pubtypes")
|
||||||
|
|
||||||
# Generate a .gdb_index with gdb
|
# Generate a .gdb_index with gdb
|
||||||
gdb_index_file = argv[1] + '.gdb-generated-index'
|
gdb_index_file = argv[1] + ".gdb-generated-index"
|
||||||
subprocess.check_call([OBJCOPY, '--remove-section', '.gdb_index',
|
subprocess.check_call(
|
||||||
argv[1], gdb_index_file])
|
[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]),
|
subprocess.check_call(
|
||||||
'-ex', 'quit'])
|
[
|
||||||
subprocess.check_call([OBJCOPY, '--add-section',
|
GDB,
|
||||||
'.gdb_index=' + gdb_index_file + '.gdb-index',
|
"-batch",
|
||||||
gdb_index_file])
|
"-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)
|
gdb_index = get_gdb_index(gdb_index_file)
|
||||||
os.remove(gdb_index_file)
|
os.remove(gdb_index_file)
|
||||||
os.remove(gdb_index_file + '.gdb-index')
|
os.remove(gdb_index_file + ".gdb-index")
|
||||||
|
|
||||||
failed = False
|
failed = False
|
||||||
gdb_index.sort()
|
gdb_index.sort()
|
||||||
@@ -203,5 +220,5 @@ def main(argv):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
main(sys.argv)
|
main(sys.argv)
|
||||||
|
|||||||
285
gdb/copyright.py
285
gdb/copyright.py
@@ -47,23 +47,32 @@ def get_update_list():
|
|||||||
"""
|
"""
|
||||||
result = []
|
result = []
|
||||||
for gdb_dir in (
|
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 root, dirs, files in os.walk(gdb_dir, topdown=True):
|
||||||
for dirname in dirs:
|
for dirname in dirs:
|
||||||
reldirname = "%s/%s" % (root, dirname)
|
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 EXCLUDE_LIST
|
||||||
or reldirname in NOT_FSF_LIST
|
or reldirname in NOT_FSF_LIST
|
||||||
or reldirname in BY_HAND):
|
or reldirname in BY_HAND
|
||||||
|
):
|
||||||
# Prune this directory from our search list.
|
# Prune this directory from our search list.
|
||||||
dirs.remove(dirname)
|
dirs.remove(dirname)
|
||||||
for filename in files:
|
for filename in files:
|
||||||
relpath = "%s/%s" % (root, filename)
|
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 EXCLUDE_LIST
|
||||||
or relpath in NOT_FSF_LIST
|
or relpath in NOT_FSF_LIST
|
||||||
or relpath in BY_HAND):
|
or relpath in BY_HAND
|
||||||
|
):
|
||||||
# Ignore this file.
|
# Ignore this file.
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -80,15 +89,18 @@ def update_files(update_list):
|
|||||||
# all years should be collapsed to one single year interval,
|
# all years should be collapsed to one single year interval,
|
||||||
# even if there are "holes" in the list of years found in the
|
# 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]).
|
# 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.
|
# 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
|
update_cmd += update_list
|
||||||
|
|
||||||
p = subprocess.Popen(update_cmd, stdout=subprocess.PIPE,
|
p = subprocess.Popen(
|
||||||
|
update_cmd,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT,
|
||||||
encoding=locale.getpreferredencoding())
|
encoding=locale.getpreferredencoding(),
|
||||||
|
)
|
||||||
update_out = p.communicate()[0]
|
update_out = p.communicate()[0]
|
||||||
|
|
||||||
# Process the output. Typically, a lot of files do not have
|
# 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.
|
# short of looking at each file and seeing which notice is appropriate.
|
||||||
# Too much work! (~4,000 files listed as of 2012-01-03).
|
# Too much work! (~4,000 files listed as of 2012-01-03).
|
||||||
update_out = update_out.splitlines(keepends=False)
|
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)
|
warning_len = len(warning_string)
|
||||||
|
|
||||||
for line in update_out:
|
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
|
# 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,
|
# for a pattern that should be the same regardless of encoding,
|
||||||
# so that should be good enough.
|
# so that should be good enough.
|
||||||
fd = open(filename, 'rb')
|
fd = open(filename, "rb")
|
||||||
|
|
||||||
lineno = 1
|
lineno = 1
|
||||||
for line in fd:
|
for line in fd:
|
||||||
if b'Copyright' in line:
|
if b"Copyright" in line:
|
||||||
return True
|
return True
|
||||||
lineno += 1
|
lineno += 1
|
||||||
if lineno > 50:
|
if lineno > 50:
|
||||||
@@ -146,36 +158,41 @@ def may_have_copyright_notice(filename):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def main ():
|
def main():
|
||||||
"""The main subprogram."""
|
"""The main subprogram."""
|
||||||
root_dir = os.path.dirname(os.getcwd())
|
root_dir = os.path.dirname(os.getcwd())
|
||||||
os.chdir(root_dir)
|
os.chdir(root_dir)
|
||||||
|
|
||||||
if not (os.path.isdir('gdb') and
|
if not (
|
||||||
os.path.isfile("gnulib/import/extra/update-copyright")):
|
os.path.isdir("gdb") and os.path.isfile("gnulib/import/extra/update-copyright")
|
||||||
|
):
|
||||||
print("Error: This script must be called from the gdb directory.")
|
print("Error: This script must be called from the gdb directory.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
update_list = get_update_list()
|
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...
|
# Remind the user that some files need to be updated by HAND...
|
||||||
|
|
||||||
if MULTIPLE_COPYRIGHT_HEADERS:
|
if MULTIPLE_COPYRIGHT_HEADERS:
|
||||||
print()
|
print()
|
||||||
print("\033[31m"
|
print(
|
||||||
|
"\033[31m"
|
||||||
"REMINDER: Multiple copyright headers must be updated by hand:"
|
"REMINDER: Multiple copyright headers must be updated by hand:"
|
||||||
"\033[0m")
|
"\033[0m"
|
||||||
|
)
|
||||||
for filename in MULTIPLE_COPYRIGHT_HEADERS:
|
for filename in MULTIPLE_COPYRIGHT_HEADERS:
|
||||||
print(" ", filename)
|
print(" ", filename)
|
||||||
|
|
||||||
if BY_HAND:
|
if BY_HAND:
|
||||||
print()
|
print()
|
||||||
print("\033[31mREMINDER: The following files must be updated by hand." \
|
print(
|
||||||
"\033[0m")
|
"\033[31mREMINDER: The following files must be updated by hand." "\033[0m"
|
||||||
|
)
|
||||||
for filename in BY_HAND:
|
for filename in BY_HAND:
|
||||||
print(" ", filename)
|
print(" ", filename)
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
#
|
#
|
||||||
# Some constants, placed at the end because they take up a lot of room.
|
# 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.
|
# Filenames are relative to the root directory.
|
||||||
EXCLUDE_LIST = (
|
EXCLUDE_LIST = (
|
||||||
'gdb/nat/glibc_thread_db.h',
|
"gdb/nat/glibc_thread_db.h",
|
||||||
'gdb/CONTRIBUTE',
|
"gdb/CONTRIBUTE",
|
||||||
'gnulib/import',
|
"gnulib/import",
|
||||||
'gnulib/config.in',
|
"gnulib/config.in",
|
||||||
'gnulib/Makefile.in',
|
"gnulib/Makefile.in",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Files which should not be modified, either because they are
|
# 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.
|
# Eg: We want all files named COPYING to be left untouched.
|
||||||
|
|
||||||
EXCLUDE_ALL_LIST = (
|
EXCLUDE_ALL_LIST = (
|
||||||
"COPYING", "COPYING.LIB", "CVS", "configure", "copying.c",
|
"COPYING",
|
||||||
"fdl.texi", "gpl.texi", "aclocal.m4",
|
"COPYING.LIB",
|
||||||
|
"CVS",
|
||||||
|
"configure",
|
||||||
|
"copying.c",
|
||||||
|
"fdl.texi",
|
||||||
|
"gpl.texi",
|
||||||
|
"aclocal.m4",
|
||||||
)
|
)
|
||||||
|
|
||||||
# The list of files to update by hand.
|
# The list of files to update by hand.
|
||||||
@@ -230,66 +253,166 @@ NOT_FSF_LIST = (
|
|||||||
"gdb/exc_request.defs",
|
"gdb/exc_request.defs",
|
||||||
"gdb/gdbtk",
|
"gdb/gdbtk",
|
||||||
"gdb/testsuite/gdb.gdbtk/",
|
"gdb/testsuite/gdb.gdbtk/",
|
||||||
"sim/arm/armemu.h", "sim/arm/armos.c", "sim/arm/gdbhost.c",
|
"sim/arm/armemu.h",
|
||||||
"sim/arm/dbg_hif.h", "sim/arm/dbg_conf.h", "sim/arm/communicate.h",
|
"sim/arm/armos.c",
|
||||||
"sim/arm/armos.h", "sim/arm/armcopro.c", "sim/arm/armemu.c",
|
"sim/arm/gdbhost.c",
|
||||||
"sim/arm/kid.c", "sim/arm/thumbemu.c", "sim/arm/armdefs.h",
|
"sim/arm/dbg_hif.h",
|
||||||
"sim/arm/armopts.h", "sim/arm/dbg_cp.h", "sim/arm/dbg_rdi.h",
|
"sim/arm/dbg_conf.h",
|
||||||
"sim/arm/parent.c", "sim/arm/armsupp.c", "sim/arm/armrdi.c",
|
"sim/arm/communicate.h",
|
||||||
"sim/arm/bag.c", "sim/arm/armvirt.c", "sim/arm/main.c", "sim/arm/bag.h",
|
"sim/arm/armos.h",
|
||||||
"sim/arm/communicate.c", "sim/arm/gdbhost.h", "sim/arm/armfpe.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/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/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",
|
"sim/moxie/moxie-gdb.dts",
|
||||||
# Not a single file in sim/ppc/ appears to be copyright FSF :-(.
|
# 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/filter.h",
|
||||||
"sim/ppc/hw_sem.c", "sim/ppc/hw_disk.c", "sim/ppc/idecode_branch.h",
|
"sim/ppc/gen-support.h",
|
||||||
"sim/ppc/sim-endian.h", "sim/ppc/table.c", "sim/ppc/hw_core.c",
|
"sim/ppc/ld-insn.h",
|
||||||
"sim/ppc/gen-support.c", "sim/ppc/gen-semantics.h", "sim/ppc/cpu.h",
|
"sim/ppc/hw_sem.c",
|
||||||
"sim/ppc/sim_callbacks.h", "sim/ppc/RUN", "sim/ppc/Makefile.in",
|
"sim/ppc/hw_disk.c",
|
||||||
"sim/ppc/emul_chirp.c", "sim/ppc/hw_nvram.c", "sim/ppc/dc-test.01",
|
"sim/ppc/idecode_branch.h",
|
||||||
"sim/ppc/hw_phb.c", "sim/ppc/hw_eeprom.c", "sim/ppc/bits.h",
|
"sim/ppc/sim-endian.h",
|
||||||
"sim/ppc/hw_vm.c", "sim/ppc/cap.h", "sim/ppc/os_emul.h",
|
"sim/ppc/table.c",
|
||||||
"sim/ppc/options.h", "sim/ppc/gen-idecode.c", "sim/ppc/filter.c",
|
"sim/ppc/hw_core.c",
|
||||||
"sim/ppc/corefile-n.h", "sim/ppc/std-config.h", "sim/ppc/ld-decode.h",
|
"sim/ppc/gen-support.c",
|
||||||
"sim/ppc/filter_filename.h", "sim/ppc/hw_shm.c",
|
"sim/ppc/gen-semantics.h",
|
||||||
"sim/ppc/pk_disklabel.c", "sim/ppc/dc-simple", "sim/ppc/misc.h",
|
"sim/ppc/cpu.h",
|
||||||
"sim/ppc/device_table.h", "sim/ppc/ld-insn.c", "sim/ppc/inline.c",
|
"sim/ppc/sim_callbacks.h",
|
||||||
"sim/ppc/emul_bugapi.h", "sim/ppc/hw_cpu.h", "sim/ppc/debug.h",
|
"sim/ppc/RUN",
|
||||||
"sim/ppc/hw_ide.c", "sim/ppc/debug.c", "sim/ppc/gen-itable.h",
|
"sim/ppc/Makefile.in",
|
||||||
"sim/ppc/interrupts.c", "sim/ppc/hw_glue.c", "sim/ppc/emul_unix.c",
|
"sim/ppc/emul_chirp.c",
|
||||||
"sim/ppc/sim_calls.c", "sim/ppc/dc-complex", "sim/ppc/ld-cache.c",
|
"sim/ppc/hw_nvram.c",
|
||||||
"sim/ppc/registers.h", "sim/ppc/dc-test.02", "sim/ppc/options.c",
|
"sim/ppc/dc-test.01",
|
||||||
"sim/ppc/igen.h", "sim/ppc/registers.c", "sim/ppc/device.h",
|
"sim/ppc/hw_phb.c",
|
||||||
"sim/ppc/emul_chirp.h", "sim/ppc/hw_register.c", "sim/ppc/hw_init.c",
|
"sim/ppc/hw_eeprom.c",
|
||||||
"sim/ppc/sim-endian-n.h", "sim/ppc/filter_filename.c",
|
"sim/ppc/bits.h",
|
||||||
"sim/ppc/bits.c", "sim/ppc/idecode_fields.h", "sim/ppc/hw_memory.c",
|
"sim/ppc/hw_vm.c",
|
||||||
"sim/ppc/misc.c", "sim/ppc/double.c", "sim/ppc/psim.h",
|
"sim/ppc/cap.h",
|
||||||
"sim/ppc/hw_trace.c", "sim/ppc/emul_netbsd.h", "sim/ppc/psim.c",
|
"sim/ppc/os_emul.h",
|
||||||
"sim/ppc/ppc-instructions", "sim/ppc/tree.h", "sim/ppc/README",
|
"sim/ppc/options.h",
|
||||||
"sim/ppc/gen-icache.h", "sim/ppc/gen-model.h", "sim/ppc/ld-cache.h",
|
"sim/ppc/gen-idecode.c",
|
||||||
"sim/ppc/mon.c", "sim/ppc/corefile.h", "sim/ppc/vm.c",
|
"sim/ppc/filter.c",
|
||||||
"sim/ppc/INSTALL", "sim/ppc/gen-model.c", "sim/ppc/hw_cpu.c",
|
"sim/ppc/corefile-n.h",
|
||||||
"sim/ppc/corefile.c", "sim/ppc/hw_opic.c", "sim/ppc/gen-icache.c",
|
"sim/ppc/std-config.h",
|
||||||
"sim/ppc/events.h", "sim/ppc/os_emul.c", "sim/ppc/emul_generic.c",
|
"sim/ppc/ld-decode.h",
|
||||||
"sim/ppc/main.c", "sim/ppc/hw_com.c", "sim/ppc/gen-semantics.c",
|
"sim/ppc/filter_filename.h",
|
||||||
"sim/ppc/emul_bugapi.c", "sim/ppc/device.c", "sim/ppc/emul_generic.h",
|
"sim/ppc/hw_shm.c",
|
||||||
"sim/ppc/tree.c", "sim/ppc/mon.h", "sim/ppc/interrupts.h",
|
"sim/ppc/pk_disklabel.c",
|
||||||
"sim/ppc/cap.c", "sim/ppc/cpu.c", "sim/ppc/hw_phb.h",
|
"sim/ppc/dc-simple",
|
||||||
"sim/ppc/device_table.c", "sim/ppc/lf.c", "sim/ppc/lf.c",
|
"sim/ppc/misc.h",
|
||||||
"sim/ppc/dc-stupid", "sim/ppc/hw_pal.c", "sim/ppc/ppc-spr-table",
|
"sim/ppc/device_table.h",
|
||||||
"sim/ppc/emul_unix.h", "sim/ppc/words.h", "sim/ppc/basics.h",
|
"sim/ppc/ld-insn.c",
|
||||||
"sim/ppc/hw_htab.c", "sim/ppc/lf.h", "sim/ppc/ld-decode.c",
|
"sim/ppc/inline.c",
|
||||||
"sim/ppc/sim-endian.c", "sim/ppc/gen-itable.c",
|
"sim/ppc/emul_bugapi.h",
|
||||||
"sim/ppc/idecode_expression.h", "sim/ppc/table.h", "sim/ppc/dgen.c",
|
"sim/ppc/hw_cpu.h",
|
||||||
"sim/ppc/events.c", "sim/ppc/gen-idecode.h", "sim/ppc/emul_netbsd.c",
|
"sim/ppc/debug.h",
|
||||||
"sim/ppc/igen.c", "sim/ppc/vm_n.h", "sim/ppc/vm.h",
|
"sim/ppc/hw_ide.c",
|
||||||
"sim/ppc/hw_iobus.c", "sim/ppc/inline.h",
|
"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",
|
"sim/testsuite/sim/mips/mips32-dsp2.s",
|
||||||
)
|
)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ try:
|
|||||||
except NameError:
|
except NameError:
|
||||||
basestring = str
|
basestring = str
|
||||||
|
|
||||||
|
|
||||||
class FrameDecorator(object):
|
class FrameDecorator(object):
|
||||||
"""Basic implementation of a Frame Decorator"""
|
"""Basic implementation of a Frame Decorator"""
|
||||||
|
|
||||||
@@ -66,9 +67,12 @@ class FrameDecorator(object):
|
|||||||
limited."""
|
limited."""
|
||||||
sal = frame.find_sal()
|
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.DUMMY_FRAME
|
||||||
or frame.type() == gdb.SIGTRAMP_FRAME):
|
or frame.type() == gdb.SIGTRAMP_FRAME
|
||||||
|
):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -83,7 +87,7 @@ class FrameDecorator(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def function(self):
|
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
|
the function of the frame. First determine if this is a
|
||||||
special frame. If not, try to determine filename from GDB's
|
special frame. If not, try to determine filename from GDB's
|
||||||
frame internal function API. Finally, if a name cannot be
|
frame internal function API. Finally, if a name cannot be
|
||||||
@@ -120,7 +124,7 @@ class FrameDecorator(object):
|
|||||||
return str(func)
|
return str(func)
|
||||||
|
|
||||||
def address(self):
|
def address(self):
|
||||||
""" Return the address of the frame's pc"""
|
"""Return the address of the frame's pc"""
|
||||||
|
|
||||||
if hasattr(self._base, "address"):
|
if hasattr(self._base, "address"):
|
||||||
return self._base.address()
|
return self._base.address()
|
||||||
@@ -129,7 +133,7 @@ class FrameDecorator(object):
|
|||||||
return frame.pc()
|
return frame.pc()
|
||||||
|
|
||||||
def filename(self):
|
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
|
and returning the appropriate library name is this is a shared
|
||||||
library."""
|
library."""
|
||||||
|
|
||||||
@@ -145,7 +149,7 @@ class FrameDecorator(object):
|
|||||||
return sal.symtab.filename
|
return sal.symtab.filename
|
||||||
|
|
||||||
def frame_args(self):
|
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
|
any. The iterable object contains objects conforming with the
|
||||||
Symbol/Value interface. If there are no frame arguments, or
|
Symbol/Value interface. If there are no frame arguments, or
|
||||||
if this frame is deemed to be a special case, return None."""
|
if this frame is deemed to be a special case, return None."""
|
||||||
@@ -161,7 +165,7 @@ class FrameDecorator(object):
|
|||||||
return args.fetch_frame_args()
|
return args.fetch_frame_args()
|
||||||
|
|
||||||
def frame_locals(self):
|
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
|
any. The iterable object contains objects conforming with the
|
||||||
Symbol/Value interface. If there are no frame locals, or if
|
Symbol/Value interface. If there are no frame locals, or if
|
||||||
this frame is deemed to be a special case, return None."""
|
this frame is deemed to be a special case, return None."""
|
||||||
@@ -177,7 +181,7 @@ class FrameDecorator(object):
|
|||||||
return args.fetch_frame_locals()
|
return args.fetch_frame_locals()
|
||||||
|
|
||||||
def line(self):
|
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
|
pc. If symbol table/line information does not exist, or if
|
||||||
this frame is deemed to be a special case, return None"""
|
this frame is deemed to be a special case, return None"""
|
||||||
|
|
||||||
@@ -189,13 +193,13 @@ class FrameDecorator(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
sal = frame.find_sal()
|
sal = frame.find_sal()
|
||||||
if (sal):
|
if sal:
|
||||||
return sal.line
|
return sal.line
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def inferior_frame(self):
|
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
|
# If 'base' is a frame decorator, we want to call its inferior
|
||||||
# frame method. If '_base' is a gdb.Frame, just return that.
|
# 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.inferior_frame()
|
||||||
return self._base
|
return self._base
|
||||||
|
|
||||||
|
|
||||||
class SymValueWrapper(object):
|
class SymValueWrapper(object):
|
||||||
"""A container class conforming to the Symbol/Value interface
|
"""A container class conforming to the Symbol/Value interface
|
||||||
which holds frame locals or frame arguments."""
|
which holds frame locals or frame arguments."""
|
||||||
|
|
||||||
def __init__(self, symbol, value):
|
def __init__(self, symbol, value):
|
||||||
self.sym = symbol
|
self.sym = symbol
|
||||||
self.val = value
|
self.val = value
|
||||||
|
|
||||||
def value(self):
|
def value(self):
|
||||||
""" Return the value associated with this symbol, or None"""
|
"""Return the value associated with this symbol, or None"""
|
||||||
return self.val
|
return self.val
|
||||||
|
|
||||||
def symbol(self):
|
def symbol(self):
|
||||||
""" Return the symbol, or Python text, associated with this
|
"""Return the symbol, or Python text, associated with this
|
||||||
symbol, or None"""
|
symbol, or None"""
|
||||||
return self.sym
|
return self.sym
|
||||||
|
|
||||||
|
|
||||||
class FrameVars(object):
|
class FrameVars(object):
|
||||||
|
|
||||||
"""Utility class to fetch and store frame local variables, or
|
"""Utility class to fetch and store frame local variables, or
|
||||||
@@ -233,11 +240,11 @@ class FrameVars(object):
|
|||||||
gdb.SYMBOL_LOC_REF_ARG: True,
|
gdb.SYMBOL_LOC_REF_ARG: True,
|
||||||
gdb.SYMBOL_LOC_LOCAL: True,
|
gdb.SYMBOL_LOC_LOCAL: True,
|
||||||
gdb.SYMBOL_LOC_REGPARM_ADDR: True,
|
gdb.SYMBOL_LOC_REGPARM_ADDR: True,
|
||||||
gdb.SYMBOL_LOC_COMPUTED: True
|
gdb.SYMBOL_LOC_COMPUTED: True,
|
||||||
}
|
}
|
||||||
|
|
||||||
def fetch_b(self, sym):
|
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
|
type whether it should be included in the iterator. Not all
|
||||||
symbols are fetched, and only symbols that return
|
symbols are fetched, and only symbols that return
|
||||||
True from this method should be fetched."""
|
True from this method should be fetched."""
|
||||||
@@ -268,7 +275,7 @@ class FrameVars(object):
|
|||||||
break
|
break
|
||||||
for sym in block:
|
for sym in block:
|
||||||
if sym.is_argument:
|
if sym.is_argument:
|
||||||
continue;
|
continue
|
||||||
if self.fetch_b(sym):
|
if self.fetch_b(sym):
|
||||||
lvars.append(SymValueWrapper(sym, None))
|
lvars.append(SymValueWrapper(sym, None))
|
||||||
|
|
||||||
@@ -296,7 +303,7 @@ class FrameVars(object):
|
|||||||
if block != None:
|
if block != None:
|
||||||
for sym in block:
|
for sym in block:
|
||||||
if not sym.is_argument:
|
if not sym.is_argument:
|
||||||
continue;
|
continue
|
||||||
args.append(SymValueWrapper(sym, None))
|
args.append(SymValueWrapper(sym, None))
|
||||||
|
|
||||||
return args
|
return args
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
import gdb
|
import gdb
|
||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
|
|
||||||
class FrameIterator(object):
|
class FrameIterator(object):
|
||||||
"""A gdb.Frame iterator. Iterates over gdb.Frames or objects that
|
"""A gdb.Frame iterator. Iterates over gdb.Frames or objects that
|
||||||
conform to that interface."""
|
conform to that interface."""
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ elif sys.version_info[0] > 2:
|
|||||||
|
|
||||||
from _gdb import *
|
from _gdb import *
|
||||||
|
|
||||||
class _GdbFile (object):
|
|
||||||
|
class _GdbFile(object):
|
||||||
# These two are needed in Python 3
|
# These two are needed in Python 3
|
||||||
encoding = "UTF-8"
|
encoding = "UTF-8"
|
||||||
errors = "strict"
|
errors = "strict"
|
||||||
@@ -45,16 +46,20 @@ class _GdbFile (object):
|
|||||||
def flush(self):
|
def flush(self):
|
||||||
flush()
|
flush()
|
||||||
|
|
||||||
class _GdbOutputFile (_GdbFile):
|
|
||||||
|
class _GdbOutputFile(_GdbFile):
|
||||||
def write(self, s):
|
def write(self, s):
|
||||||
write(s, stream=STDOUT)
|
write(s, stream=STDOUT)
|
||||||
|
|
||||||
|
|
||||||
sys.stdout = _GdbOutputFile()
|
sys.stdout = _GdbOutputFile()
|
||||||
|
|
||||||
class _GdbOutputErrorFile (_GdbFile):
|
|
||||||
|
class _GdbOutputErrorFile(_GdbFile):
|
||||||
def write(self, s):
|
def write(self, s):
|
||||||
write(s, stream=STDERR)
|
write(s, stream=STDERR)
|
||||||
|
|
||||||
|
|
||||||
sys.stderr = _GdbOutputErrorFile()
|
sys.stderr = _GdbOutputErrorFile()
|
||||||
|
|
||||||
# Default prompt hook does nothing.
|
# Default prompt hook does nothing.
|
||||||
@@ -62,7 +67,7 @@ prompt_hook = None
|
|||||||
|
|
||||||
# Ensure that sys.argv is set to something.
|
# Ensure that sys.argv is set to something.
|
||||||
# We do not use PySys_SetArgvEx because it did not appear until 2.6.6.
|
# We do not use PySys_SetArgvEx because it did not appear until 2.6.6.
|
||||||
sys.argv = ['']
|
sys.argv = [""]
|
||||||
|
|
||||||
# Initial pretty printers.
|
# Initial pretty printers.
|
||||||
pretty_printers = []
|
pretty_printers = []
|
||||||
@@ -76,6 +81,7 @@ frame_filters = {}
|
|||||||
# Initial frame unwinders.
|
# Initial frame unwinders.
|
||||||
frame_unwinders = []
|
frame_unwinders = []
|
||||||
|
|
||||||
|
|
||||||
def _execute_unwinders(pending_frame):
|
def _execute_unwinders(pending_frame):
|
||||||
"""Internal function called from GDB to execute all unwinders.
|
"""Internal function called from GDB to execute all unwinders.
|
||||||
|
|
||||||
@@ -108,6 +114,7 @@ def _execute_unwinders(pending_frame):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _execute_file(filepath):
|
def _execute_file(filepath):
|
||||||
"""This function is used to replace Python 2's PyRun_SimpleFile.
|
"""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
|
"Furthermore, any functions and classes defined by the executed code are
|
||||||
not guaranteed to work correctly after a runpy function has returned."
|
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 = False
|
||||||
# Set file (if not set) so that the imported file can use it (e.g. to
|
# 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.
|
# access file-relative paths). This matches what PyRun_SimpleFile does.
|
||||||
if not hasattr(globals, '__file__'):
|
if not hasattr(globals, "__file__"):
|
||||||
globals['__file__'] = filepath
|
globals["__file__"] = filepath
|
||||||
set_file = True
|
set_file = True
|
||||||
try:
|
try:
|
||||||
with open(filepath, 'rb') as file:
|
with open(filepath, "rb") as file:
|
||||||
# We pass globals also as locals to match what Python does
|
# We pass globals also as locals to match what Python does
|
||||||
# in PyRun_SimpleFile.
|
# in PyRun_SimpleFile.
|
||||||
compiled = compile(file.read(), filepath, 'exec')
|
compiled = compile(file.read(), filepath, "exec")
|
||||||
exec(compiled, globals, globals)
|
exec(compiled, globals, globals)
|
||||||
finally:
|
finally:
|
||||||
if set_file:
|
if set_file:
|
||||||
del globals['__file__']
|
del globals["__file__"]
|
||||||
|
|
||||||
|
|
||||||
# Convenience variable to GDB's python directory
|
# Convenience variable to GDB's python directory
|
||||||
@@ -142,27 +149,24 @@ PYTHONDIR = os.path.dirname(os.path.dirname(__file__))
|
|||||||
|
|
||||||
# Packages to auto-load.
|
# Packages to auto-load.
|
||||||
|
|
||||||
packages = [
|
packages = ["function", "command", "printer"]
|
||||||
'function',
|
|
||||||
'command',
|
|
||||||
'printer'
|
|
||||||
]
|
|
||||||
|
|
||||||
# pkgutil.iter_modules is not available prior to Python 2.6. Instead,
|
# pkgutil.iter_modules is not available prior to Python 2.6. Instead,
|
||||||
# manually iterate the list, collating the Python files in each module
|
# manually iterate the list, collating the Python files in each module
|
||||||
# path. Construct the module name, and import.
|
# path. Construct the module name, and import.
|
||||||
|
|
||||||
|
|
||||||
def _auto_load_packages():
|
def _auto_load_packages():
|
||||||
for package in packages:
|
for package in packages:
|
||||||
location = os.path.join(os.path.dirname(__file__), package)
|
location = os.path.join(os.path.dirname(__file__), package)
|
||||||
if os.path.exists(location):
|
if os.path.exists(location):
|
||||||
py_files = filter(lambda x: x.endswith('.py')
|
py_files = filter(
|
||||||
and x != '__init__.py',
|
lambda x: x.endswith(".py") and x != "__init__.py", os.listdir(location)
|
||||||
os.listdir(location))
|
)
|
||||||
|
|
||||||
for py_file in py_files:
|
for py_file in py_files:
|
||||||
# Construct from foo.py, gdb.module.foo
|
# 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:
|
try:
|
||||||
if modname in sys.modules:
|
if modname in sys.modules:
|
||||||
# reload modules with duplicate names
|
# reload modules with duplicate names
|
||||||
@@ -170,10 +174,12 @@ def _auto_load_packages():
|
|||||||
else:
|
else:
|
||||||
__import__(modname)
|
__import__(modname)
|
||||||
except:
|
except:
|
||||||
sys.stderr.write (traceback.format_exc() + "\n")
|
sys.stderr.write(traceback.format_exc() + "\n")
|
||||||
|
|
||||||
|
|
||||||
_auto_load_packages()
|
_auto_load_packages()
|
||||||
|
|
||||||
|
|
||||||
def GdbSetPythonDirectory(dir):
|
def GdbSetPythonDirectory(dir):
|
||||||
"""Update sys.path, reload gdb and auto-load packages."""
|
"""Update sys.path, reload gdb and auto-load packages."""
|
||||||
global PYTHONDIR
|
global PYTHONDIR
|
||||||
@@ -191,30 +197,37 @@ def GdbSetPythonDirectory(dir):
|
|||||||
reload(__import__(__name__))
|
reload(__import__(__name__))
|
||||||
_auto_load_packages()
|
_auto_load_packages()
|
||||||
|
|
||||||
|
|
||||||
def current_progspace():
|
def current_progspace():
|
||||||
"Return the current Progspace."
|
"Return the current Progspace."
|
||||||
return selected_inferior().progspace
|
return selected_inferior().progspace
|
||||||
|
|
||||||
|
|
||||||
def objfiles():
|
def objfiles():
|
||||||
"Return a sequence of the current program space's objfiles."
|
"Return a sequence of the current program space's objfiles."
|
||||||
return current_progspace().objfiles()
|
return current_progspace().objfiles()
|
||||||
|
|
||||||
def solib_name (addr):
|
|
||||||
|
def solib_name(addr):
|
||||||
"""solib_name (Long) -> String.\n\
|
"""solib_name (Long) -> String.\n\
|
||||||
Return the name of the shared library holding a given address, or None."""
|
Return the name of the shared library holding a given address, or None."""
|
||||||
return current_progspace().solib_name(addr)
|
return current_progspace().solib_name(addr)
|
||||||
|
|
||||||
|
|
||||||
def block_for_pc(pc):
|
def block_for_pc(pc):
|
||||||
"Return the block containing the given pc value, or None."
|
"Return the block containing the given pc value, or None."
|
||||||
return current_progspace().block_for_pc(pc)
|
return current_progspace().block_for_pc(pc)
|
||||||
|
|
||||||
|
|
||||||
def find_pc_line(pc):
|
def find_pc_line(pc):
|
||||||
"""find_pc_line (pc) -> Symtab_and_line.
|
"""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)
|
return current_progspace().find_pc_line(pc)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from pygments import formatters, lexers, highlight
|
from pygments import formatters, lexers, highlight
|
||||||
|
|
||||||
def colorize(filename, contents):
|
def colorize(filename, contents):
|
||||||
# Don't want any errors.
|
# Don't want any errors.
|
||||||
try:
|
try:
|
||||||
@@ -223,6 +236,9 @@ try:
|
|||||||
return highlight(contents, lexer, formatter)
|
return highlight(contents, lexer, formatter)
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
except:
|
except:
|
||||||
|
|
||||||
def colorize(filename, contents):
|
def colorize(filename, contents):
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -12,5 +12,3 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,11 +23,12 @@ if sys.version_info[0] > 2:
|
|||||||
# Python 3 renamed raw_input to input
|
# Python 3 renamed raw_input to input
|
||||||
raw_input = input
|
raw_input = input
|
||||||
|
|
||||||
|
|
||||||
class Explorer(object):
|
class Explorer(object):
|
||||||
"""Internal class which invokes other explorers."""
|
"""Internal class which invokes other explorers."""
|
||||||
|
|
||||||
# This map is filled by the Explorer.init_env() function
|
# This map is filled by the Explorer.init_env() function
|
||||||
type_code_to_explorer_map = { }
|
type_code_to_explorer_map = {}
|
||||||
|
|
||||||
_SCALAR_TYPE_LIST = (
|
_SCALAR_TYPE_LIST = (
|
||||||
gdb.TYPE_CODE_CHAR,
|
gdb.TYPE_CODE_CHAR,
|
||||||
@@ -43,14 +44,18 @@ class Explorer(object):
|
|||||||
length = len(expr)
|
length = len(expr)
|
||||||
guard = False
|
guard = False
|
||||||
|
|
||||||
if expr[0] == '(' and expr[length-1] == ')':
|
if expr[0] == "(" and expr[length - 1] == ")":
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
i = 0
|
i = 0
|
||||||
while i < length:
|
while i < length:
|
||||||
c = expr[i]
|
c = expr[i]
|
||||||
if (c == '_' or ('a' <= c and c <= 'z') or
|
if (
|
||||||
('A' <= c and c <= 'Z') or ('0' <= c and c <= '9')):
|
c == "_"
|
||||||
|
or ("a" <= c and c <= "z")
|
||||||
|
or ("A" <= c and c <= "Z")
|
||||||
|
or ("0" <= c and c <= "9")
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
guard = True
|
guard = True
|
||||||
@@ -85,8 +90,7 @@ class Explorer(object):
|
|||||||
while explorer_class.explore_expr(expr, value, is_child):
|
while explorer_class.explore_expr(expr, value, is_child):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
print ("Explorer for type '%s' not yet available.\n" %
|
print("Explorer for type '%s' not yet available.\n" % str(value.type))
|
||||||
str(value.type))
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def explore_type(name, datatype, is_child):
|
def explore_type(name, datatype, is_child):
|
||||||
@@ -111,8 +115,7 @@ class Explorer(object):
|
|||||||
while explorer_class.explore_type(name, datatype, is_child):
|
while explorer_class.explore_type(name, datatype, is_child):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
print ("Explorer for type '%s' not yet available.\n" %
|
print("Explorer for type '%s' not yet available.\n" % str(datatype))
|
||||||
str(datatype))
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def init_env():
|
def init_env():
|
||||||
@@ -122,19 +125,19 @@ class Explorer(object):
|
|||||||
explorations.
|
explorations.
|
||||||
"""
|
"""
|
||||||
Explorer.type_code_to_explorer_map = {
|
Explorer.type_code_to_explorer_map = {
|
||||||
gdb.TYPE_CODE_CHAR : ScalarExplorer,
|
gdb.TYPE_CODE_CHAR: ScalarExplorer,
|
||||||
gdb.TYPE_CODE_INT : ScalarExplorer,
|
gdb.TYPE_CODE_INT: ScalarExplorer,
|
||||||
gdb.TYPE_CODE_BOOL : ScalarExplorer,
|
gdb.TYPE_CODE_BOOL: ScalarExplorer,
|
||||||
gdb.TYPE_CODE_FLT : ScalarExplorer,
|
gdb.TYPE_CODE_FLT: ScalarExplorer,
|
||||||
gdb.TYPE_CODE_VOID : ScalarExplorer,
|
gdb.TYPE_CODE_VOID: ScalarExplorer,
|
||||||
gdb.TYPE_CODE_ENUM : ScalarExplorer,
|
gdb.TYPE_CODE_ENUM: ScalarExplorer,
|
||||||
gdb.TYPE_CODE_STRUCT : CompoundExplorer,
|
gdb.TYPE_CODE_STRUCT: CompoundExplorer,
|
||||||
gdb.TYPE_CODE_UNION : CompoundExplorer,
|
gdb.TYPE_CODE_UNION: CompoundExplorer,
|
||||||
gdb.TYPE_CODE_PTR : PointerExplorer,
|
gdb.TYPE_CODE_PTR: PointerExplorer,
|
||||||
gdb.TYPE_CODE_REF : ReferenceExplorer,
|
gdb.TYPE_CODE_REF: ReferenceExplorer,
|
||||||
gdb.TYPE_CODE_RVALUE_REF : ReferenceExplorer,
|
gdb.TYPE_CODE_RVALUE_REF: ReferenceExplorer,
|
||||||
gdb.TYPE_CODE_TYPEDEF : TypedefExplorer,
|
gdb.TYPE_CODE_TYPEDEF: TypedefExplorer,
|
||||||
gdb.TYPE_CODE_ARRAY : ArrayExplorer
|
gdb.TYPE_CODE_ARRAY: ArrayExplorer,
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -161,7 +164,7 @@ class Explorer(object):
|
|||||||
"""A utility function which prints that the current exploration session
|
"""A utility function which prints that the current exploration session
|
||||||
is returning to the parent value. Useful when exploring values.
|
is returning to the parent value. Useful when exploring values.
|
||||||
"""
|
"""
|
||||||
print ("\nReturning to parent value...\n")
|
print("\nReturning to parent value...\n")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def return_to_parent_value_prompt():
|
def return_to_parent_value_prompt():
|
||||||
@@ -176,7 +179,7 @@ class Explorer(object):
|
|||||||
"""A utility function which prints that the current exploration session
|
"""A utility function which prints that the current exploration session
|
||||||
is returning to the enclosing type. Useful when exploring types.
|
is returning to the enclosing type. Useful when exploring types.
|
||||||
"""
|
"""
|
||||||
print ("\nReturning to enclosing type...\n")
|
print("\nReturning to enclosing type...\n")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def return_to_enclosing_type_prompt():
|
def return_to_enclosing_type_prompt():
|
||||||
@@ -196,9 +199,8 @@ class ScalarExplorer(object):
|
|||||||
See Explorer.explore_expr and Explorer.is_scalar_type for more
|
See Explorer.explore_expr and Explorer.is_scalar_type for more
|
||||||
information.
|
information.
|
||||||
"""
|
"""
|
||||||
print ("'%s' is a scalar value of type '%s'." %
|
print("'%s' is a scalar value of type '%s'." % (expr, value.type))
|
||||||
(expr, value.type))
|
print("%s = %s" % (expr, str(value)))
|
||||||
print ("%s = %s" % (expr, str(value)))
|
|
||||||
|
|
||||||
if is_child:
|
if is_child:
|
||||||
Explorer.return_to_parent_value_prompt()
|
Explorer.return_to_parent_value_prompt()
|
||||||
@@ -214,16 +216,14 @@ class ScalarExplorer(object):
|
|||||||
"""
|
"""
|
||||||
if datatype.code == gdb.TYPE_CODE_ENUM:
|
if datatype.code == gdb.TYPE_CODE_ENUM:
|
||||||
if is_child:
|
if is_child:
|
||||||
print ("%s is of an enumerated type '%s'." %
|
print("%s is of an enumerated type '%s'." % (name, str(datatype)))
|
||||||
(name, str(datatype)))
|
|
||||||
else:
|
else:
|
||||||
print ("'%s' is an enumerated type." % name)
|
print("'%s' is an enumerated type." % name)
|
||||||
else:
|
else:
|
||||||
if is_child:
|
if is_child:
|
||||||
print ("%s is of a scalar type '%s'." %
|
print("%s is of a scalar type '%s'." % (name, str(datatype)))
|
||||||
(name, str(datatype)))
|
|
||||||
else:
|
else:
|
||||||
print ("'%s' is a scalar type." % name)
|
print("'%s' is a scalar type." % name)
|
||||||
|
|
||||||
if is_child:
|
if is_child:
|
||||||
Explorer.return_to_enclosing_type_prompt()
|
Explorer.return_to_enclosing_type_prompt()
|
||||||
@@ -240,33 +240,41 @@ class PointerExplorer(object):
|
|||||||
"""Function to explore pointer values.
|
"""Function to explore pointer values.
|
||||||
See Explorer.explore_expr for more information.
|
See Explorer.explore_expr for more information.
|
||||||
"""
|
"""
|
||||||
print ("'%s' is a pointer to a value of type '%s'" %
|
print(
|
||||||
(expr, str(value.type.target())))
|
"'%s' is a pointer to a value of type '%s'"
|
||||||
option = raw_input("Continue exploring it as a pointer to a single "
|
% (expr, str(value.type.target()))
|
||||||
"value [y/n]: ")
|
)
|
||||||
|
option = raw_input(
|
||||||
|
"Continue exploring it as a pointer to a single " "value [y/n]: "
|
||||||
|
)
|
||||||
if option == "y":
|
if option == "y":
|
||||||
deref_value = None
|
deref_value = None
|
||||||
try:
|
try:
|
||||||
deref_value = value.dereference()
|
deref_value = value.dereference()
|
||||||
str(deref_value)
|
str(deref_value)
|
||||||
except gdb.MemoryError:
|
except gdb.MemoryError:
|
||||||
print ("'%s' a pointer pointing to an invalid memory "
|
print(
|
||||||
"location." % expr)
|
"'%s' a pointer pointing to an invalid memory " "location." % expr
|
||||||
|
)
|
||||||
if is_child:
|
if is_child:
|
||||||
Explorer.return_to_parent_value_prompt()
|
Explorer.return_to_parent_value_prompt()
|
||||||
return False
|
return False
|
||||||
Explorer.explore_expr("*%s" % Explorer.guard_expr(expr),
|
Explorer.explore_expr(
|
||||||
deref_value, is_child)
|
"*%s" % Explorer.guard_expr(expr), deref_value, is_child
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
option = raw_input("Continue exploring it as a pointer to an "
|
option = raw_input("Continue exploring it as a pointer to an " "array [y/n]: ")
|
||||||
"array [y/n]: ")
|
|
||||||
if option == "y":
|
if option == "y":
|
||||||
while True:
|
while True:
|
||||||
index = 0
|
index = 0
|
||||||
try:
|
try:
|
||||||
index = int(raw_input("Enter the index of the element you "
|
index = int(
|
||||||
"want to explore in '%s': " % expr))
|
raw_input(
|
||||||
|
"Enter the index of the element you "
|
||||||
|
"want to explore in '%s': " % expr
|
||||||
|
)
|
||||||
|
)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
break
|
break
|
||||||
element_expr = "%s[%d]" % (Explorer.guard_expr(expr), index)
|
element_expr = "%s[%d]" % (Explorer.guard_expr(expr), index)
|
||||||
@@ -274,7 +282,7 @@ class PointerExplorer(object):
|
|||||||
try:
|
try:
|
||||||
str(element)
|
str(element)
|
||||||
except gdb.MemoryError:
|
except gdb.MemoryError:
|
||||||
print ("Cannot read value at index %d." % index)
|
print("Cannot read value at index %d." % index)
|
||||||
continue
|
continue
|
||||||
Explorer.explore_expr(element_expr, element, True)
|
Explorer.explore_expr(element_expr, element, True)
|
||||||
return False
|
return False
|
||||||
@@ -289,12 +297,9 @@ class PointerExplorer(object):
|
|||||||
See Explorer.explore_type for more information.
|
See Explorer.explore_type for more information.
|
||||||
"""
|
"""
|
||||||
target_type = datatype.target()
|
target_type = datatype.target()
|
||||||
print ("\n%s is a pointer to a value of type '%s'." %
|
print("\n%s is a pointer to a value of type '%s'." % (name, str(target_type)))
|
||||||
(name, str(target_type)))
|
|
||||||
|
|
||||||
Explorer.explore_type("the pointee type of %s" % name,
|
Explorer.explore_type("the pointee type of %s" % name, target_type, is_child)
|
||||||
target_type,
|
|
||||||
is_child)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@@ -319,6 +324,7 @@ class ReferenceExplorer(object):
|
|||||||
Explorer.explore_type(name, target_type, is_child)
|
Explorer.explore_type(name, target_type, is_child)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class ArrayExplorer(object):
|
class ArrayExplorer(object):
|
||||||
"""Internal class used to explore arrays."""
|
"""Internal class used to explore arrays."""
|
||||||
|
|
||||||
@@ -328,11 +334,15 @@ class ArrayExplorer(object):
|
|||||||
See Explorer.explore_expr for more information.
|
See Explorer.explore_expr for more information.
|
||||||
"""
|
"""
|
||||||
target_type = value.type.target()
|
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
|
index = 0
|
||||||
try:
|
try:
|
||||||
index = int(raw_input("Enter the index of the element you want to "
|
index = int(
|
||||||
"explore in '%s': " % expr))
|
raw_input(
|
||||||
|
"Enter the index of the element you want to "
|
||||||
|
"explore in '%s': " % expr
|
||||||
|
)
|
||||||
|
)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
if is_child:
|
if is_child:
|
||||||
Explorer.return_to_parent_value()
|
Explorer.return_to_parent_value()
|
||||||
@@ -343,12 +353,13 @@ class ArrayExplorer(object):
|
|||||||
element = value[index]
|
element = value[index]
|
||||||
str(element)
|
str(element)
|
||||||
except gdb.MemoryError:
|
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... ")
|
raw_input("Press enter to continue... ")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
Explorer.explore_expr("%s[%d]" % (Explorer.guard_expr(expr), index),
|
Explorer.explore_expr(
|
||||||
element, True)
|
"%s[%d]" % (Explorer.guard_expr(expr), index), element, True
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -357,10 +368,9 @@ class ArrayExplorer(object):
|
|||||||
See Explorer.explore_type for more information.
|
See Explorer.explore_type for more information.
|
||||||
"""
|
"""
|
||||||
target_type = datatype.target()
|
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,
|
Explorer.explore_type("the array element of %s" % name, target_type, is_child)
|
||||||
is_child)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@@ -369,19 +379,18 @@ class CompoundExplorer(object):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _print_fields(print_list):
|
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
|
max_field_name_length = 0
|
||||||
for pair in print_list:
|
for pair in print_list:
|
||||||
if max_field_name_length < len(pair[0]):
|
if max_field_name_length < len(pair[0]):
|
||||||
max_field_name_length = len(pair[0])
|
max_field_name_length = len(pair[0])
|
||||||
|
|
||||||
for pair in print_list:
|
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
|
@staticmethod
|
||||||
def _get_real_field_count(fields):
|
def _get_real_field_count(fields):
|
||||||
real_field_count = 0;
|
real_field_count = 0
|
||||||
for field in fields:
|
for field in fields:
|
||||||
if not field.artificial:
|
if not field.artificial:
|
||||||
real_field_count = real_field_count + 1
|
real_field_count = real_field_count + 1
|
||||||
@@ -403,19 +412,23 @@ class CompoundExplorer(object):
|
|||||||
type_desc = "union"
|
type_desc = "union"
|
||||||
|
|
||||||
if CompoundExplorer._get_real_field_count(fields) == 0:
|
if CompoundExplorer._get_real_field_count(fields) == 0:
|
||||||
print ("The value of '%s' is a %s of type '%s' with no fields." %
|
print(
|
||||||
(expr, type_desc, str(value.type)))
|
"The value of '%s' is a %s of type '%s' with no fields."
|
||||||
|
% (expr, type_desc, str(value.type))
|
||||||
|
)
|
||||||
if is_child:
|
if is_child:
|
||||||
Explorer.return_to_parent_value_prompt()
|
Explorer.return_to_parent_value_prompt()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
print ("The value of '%s' is a %s of type '%s' with the following "
|
print(
|
||||||
"fields:\n" % (expr, type_desc, str(value.type)))
|
"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
|
has_explorable_fields = False
|
||||||
choice_to_compound_field_map = { }
|
choice_to_compound_field_map = {}
|
||||||
current_choice = 0
|
current_choice = 0
|
||||||
print_list = [ ]
|
print_list = []
|
||||||
for field in fields:
|
for field in fields:
|
||||||
if field.artificial:
|
if field.artificial:
|
||||||
continue
|
continue
|
||||||
@@ -426,39 +439,48 @@ class CompoundExplorer(object):
|
|||||||
field_value = value[field.name]
|
field_value = value[field.name]
|
||||||
literal_value = ""
|
literal_value = ""
|
||||||
if type_code == gdb.TYPE_CODE_UNION:
|
if type_code == gdb.TYPE_CODE_UNION:
|
||||||
literal_value = ("<Enter %d to explore this field of type "
|
literal_value = "<Enter %d to explore this field of type " "'%s'>" % (
|
||||||
"'%s'>" % (current_choice, str(field.type)))
|
current_choice,
|
||||||
|
str(field.type),
|
||||||
|
)
|
||||||
has_explorable_fields = True
|
has_explorable_fields = True
|
||||||
else:
|
else:
|
||||||
if Explorer.is_scalar_type(field.type):
|
if Explorer.is_scalar_type(field.type):
|
||||||
literal_value = ("%s .. (Value of type '%s')" %
|
literal_value = "%s .. (Value of type '%s')" % (
|
||||||
(str(field_value), str(field.type)))
|
str(field_value),
|
||||||
|
str(field.type),
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
if field.is_base_class:
|
if field.is_base_class:
|
||||||
field_desc = "base class"
|
field_desc = "base class"
|
||||||
else:
|
else:
|
||||||
field_desc = "field"
|
field_desc = "field"
|
||||||
literal_value = ("<Enter %d to explore this %s of type "
|
literal_value = "<Enter %d to explore this %s of type " "'%s'>" % (
|
||||||
"'%s'>" %
|
current_choice,
|
||||||
(current_choice, field_desc,
|
field_desc,
|
||||||
str(field.type)))
|
str(field.type),
|
||||||
|
)
|
||||||
has_explorable_fields = True
|
has_explorable_fields = True
|
||||||
|
|
||||||
choice_to_compound_field_map[str(current_choice)] = (
|
choice_to_compound_field_map[str(current_choice)] = (
|
||||||
field_full_name, field_value)
|
field_full_name,
|
||||||
|
field_value,
|
||||||
|
)
|
||||||
current_choice = current_choice + 1
|
current_choice = current_choice + 1
|
||||||
|
|
||||||
print_list.append((field.name, literal_value))
|
print_list.append((field.name, literal_value))
|
||||||
|
|
||||||
CompoundExplorer._print_fields(print_list)
|
CompoundExplorer._print_fields(print_list)
|
||||||
print ("")
|
print("")
|
||||||
|
|
||||||
if has_explorable_fields:
|
if has_explorable_fields:
|
||||||
choice = raw_input("Enter the field number of choice: ")
|
choice = raw_input("Enter the field number of choice: ")
|
||||||
if choice in choice_to_compound_field_map:
|
if choice in choice_to_compound_field_map:
|
||||||
Explorer.explore_expr(choice_to_compound_field_map[choice][0],
|
Explorer.explore_expr(
|
||||||
|
choice_to_compound_field_map[choice][0],
|
||||||
choice_to_compound_field_map[choice][1],
|
choice_to_compound_field_map[choice][1],
|
||||||
True)
|
True,
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
if is_child:
|
if is_child:
|
||||||
@@ -484,26 +506,27 @@ class CompoundExplorer(object):
|
|||||||
fields = datatype.fields()
|
fields = datatype.fields()
|
||||||
if CompoundExplorer._get_real_field_count(fields) == 0:
|
if CompoundExplorer._get_real_field_count(fields) == 0:
|
||||||
if is_child:
|
if is_child:
|
||||||
print ("%s is a %s of type '%s' with no fields." %
|
print(
|
||||||
(name, type_desc, str(datatype)))
|
"%s is a %s of type '%s' with no fields."
|
||||||
|
% (name, type_desc, str(datatype))
|
||||||
|
)
|
||||||
Explorer.return_to_enclosing_type_prompt()
|
Explorer.return_to_enclosing_type_prompt()
|
||||||
else:
|
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
|
return False
|
||||||
|
|
||||||
if is_child:
|
if is_child:
|
||||||
print ("%s is a %s of type '%s' "
|
print(
|
||||||
"with the following fields:\n" %
|
"%s is a %s of type '%s' "
|
||||||
(name, type_desc, str(datatype)))
|
"with the following fields:\n" % (name, type_desc, str(datatype))
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print ("'%s' is a %s with the following "
|
print("'%s' is a %s with the following " "fields:\n" % (name, type_desc))
|
||||||
"fields:\n" %
|
|
||||||
(name, type_desc))
|
|
||||||
|
|
||||||
has_explorable_fields = False
|
has_explorable_fields = False
|
||||||
current_choice = 0
|
current_choice = 0
|
||||||
choice_to_compound_field_map = { }
|
choice_to_compound_field_map = {}
|
||||||
print_list = [ ]
|
print_list = []
|
||||||
for field in fields:
|
for field in fields:
|
||||||
if field.artificial:
|
if field.artificial:
|
||||||
continue
|
continue
|
||||||
@@ -511,31 +534,40 @@ class CompoundExplorer(object):
|
|||||||
field_desc = "base class"
|
field_desc = "base class"
|
||||||
else:
|
else:
|
||||||
field_desc = "field"
|
field_desc = "field"
|
||||||
rhs = ("<Enter %d to explore this %s of type '%s'>" %
|
rhs = "<Enter %d to explore this %s of type '%s'>" % (
|
||||||
(current_choice, field_desc, str(field.type)))
|
current_choice,
|
||||||
|
field_desc,
|
||||||
|
str(field.type),
|
||||||
|
)
|
||||||
print_list.append((field.name, rhs))
|
print_list.append((field.name, rhs))
|
||||||
choice_to_compound_field_map[str(current_choice)] = (
|
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
|
current_choice = current_choice + 1
|
||||||
|
|
||||||
CompoundExplorer._print_fields(print_list)
|
CompoundExplorer._print_fields(print_list)
|
||||||
print ("")
|
print("")
|
||||||
|
|
||||||
if len(choice_to_compound_field_map) > 0:
|
if len(choice_to_compound_field_map) > 0:
|
||||||
choice = raw_input("Enter the field number of choice: ")
|
choice = raw_input("Enter the field number of choice: ")
|
||||||
if choice in choice_to_compound_field_map:
|
if choice in choice_to_compound_field_map:
|
||||||
if is_child:
|
if is_child:
|
||||||
new_name = ("%s '%s' of %s" %
|
new_name = "%s '%s' of %s" % (
|
||||||
(choice_to_compound_field_map[choice][2],
|
choice_to_compound_field_map[choice][2],
|
||||||
choice_to_compound_field_map[choice][0],
|
choice_to_compound_field_map[choice][0],
|
||||||
name))
|
name,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
new_name = ("%s '%s' of '%s'" %
|
new_name = "%s '%s' of '%s'" % (
|
||||||
(choice_to_compound_field_map[choice][2],
|
choice_to_compound_field_map[choice][2],
|
||||||
choice_to_compound_field_map[choice][0],
|
choice_to_compound_field_map[choice][0],
|
||||||
name))
|
name,
|
||||||
Explorer.explore_type(new_name,
|
)
|
||||||
choice_to_compound_field_map[choice][1], True)
|
Explorer.explore_type(
|
||||||
|
new_name, choice_to_compound_field_map[choice][1], True
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
if is_child:
|
if is_child:
|
||||||
@@ -556,9 +588,11 @@ class TypedefExplorer(object):
|
|||||||
See Explorer.explore_expr for more information.
|
See Explorer.explore_expr for more information.
|
||||||
"""
|
"""
|
||||||
actual_type = value.type.strip_typedefs()
|
actual_type = value.type.strip_typedefs()
|
||||||
print ("The value of '%s' is of type '%s' "
|
print(
|
||||||
"which is a typedef of type '%s'" %
|
"The value of '%s' is of type '%s' "
|
||||||
(expr, str(value.type), str(actual_type)))
|
"which is a typedef of type '%s'"
|
||||||
|
% (expr, str(value.type), str(actual_type))
|
||||||
|
)
|
||||||
|
|
||||||
Explorer.explore_expr(expr, value.cast(actual_type), is_child)
|
Explorer.explore_expr(expr, value.cast(actual_type), is_child)
|
||||||
return False
|
return False
|
||||||
@@ -570,11 +604,11 @@ class TypedefExplorer(object):
|
|||||||
"""
|
"""
|
||||||
actual_type = datatype.strip_typedefs()
|
actual_type = datatype.strip_typedefs()
|
||||||
if is_child:
|
if is_child:
|
||||||
print ("The type of %s is a typedef of type '%s'." %
|
print(
|
||||||
(name, str(actual_type)))
|
"The type of %s is a typedef of type '%s'." % (name, str(actual_type))
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print ("The type '%s' is a typedef of type '%s'." %
|
print("The type '%s' is a typedef of type '%s'." % (name, str(actual_type)))
|
||||||
(name, str(actual_type)))
|
|
||||||
|
|
||||||
Explorer.explore_type(name, actual_type, is_child)
|
Explorer.explore_type(name, actual_type, is_child)
|
||||||
return False
|
return False
|
||||||
@@ -599,8 +633,7 @@ class ExploreUtils(object):
|
|||||||
gdb.GdbError if adequate arguments are not passed.
|
gdb.GdbError if adequate arguments are not passed.
|
||||||
"""
|
"""
|
||||||
if len(arg_str) < 1:
|
if len(arg_str) < 1:
|
||||||
raise gdb.GdbError("ERROR: '%s' requires an argument."
|
raise gdb.GdbError("ERROR: '%s' requires an argument." % name)
|
||||||
% name)
|
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
@@ -649,16 +682,16 @@ class ExploreUtils(object):
|
|||||||
class ExploreCommand(gdb.Command):
|
class ExploreCommand(gdb.Command):
|
||||||
"""Explore a value or a type valid in the current context.
|
"""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.
|
- ARG is either a valid expression or a type name.
|
||||||
- At any stage of exploration, hit the return key (instead of a
|
- At any stage of exploration, hit the return key (instead of a
|
||||||
choice, if any) to return to the enclosing type or value."""
|
choice, if any) to return to the enclosing type or value."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(ExploreCommand, self).__init__(name = "explore",
|
super(ExploreCommand, self).__init__(
|
||||||
command_class = gdb.COMMAND_DATA,
|
name="explore", command_class=gdb.COMMAND_DATA, prefix=True
|
||||||
prefix = True)
|
)
|
||||||
|
|
||||||
def invoke(self, arg_str, from_tty):
|
def invoke(self, arg_str, from_tty):
|
||||||
if ExploreUtils.check_args("explore", arg_str) == False:
|
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.
|
# If it is neither a value nor a type, raise an error.
|
||||||
raise gdb.GdbError(
|
raise gdb.GdbError(
|
||||||
("'%s' neither evaluates to a value nor is a type "
|
(
|
||||||
"in the current context." %
|
"'%s' neither evaluates to a value nor is a type "
|
||||||
arg_str))
|
"in the current context." % arg_str
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ExploreValueCommand(gdb.Command):
|
class ExploreValueCommand(gdb.Command):
|
||||||
"""Explore value of an expression valid in the current context.
|
"""Explore value of an expression valid in the current context.
|
||||||
|
|
||||||
Usage: explore value ARG
|
Usage: explore value ARG
|
||||||
|
|
||||||
- ARG is a valid expression.
|
- ARG is a valid expression.
|
||||||
- At any stage of exploration, hit the return key (instead of a
|
- At any stage of exploration, hit the return key (instead of a
|
||||||
choice, if any) to return to the enclosing value."""
|
choice, if any) to return to the enclosing value."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(ExploreValueCommand, self).__init__(
|
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):
|
def invoke(self, arg_str, from_tty):
|
||||||
if ExploreUtils.check_args("explore value", arg_str) == False:
|
if ExploreUtils.check_args("explore value", arg_str) == False:
|
||||||
@@ -703,9 +739,11 @@ choice, if any) to return to the enclosing value."""
|
|||||||
value = ExploreUtils.get_value_from_str(arg_str)
|
value = ExploreUtils.get_value_from_str(arg_str)
|
||||||
if value is None:
|
if value is None:
|
||||||
raise gdb.GdbError(
|
raise gdb.GdbError(
|
||||||
(" '%s' does not evaluate to a value in the current "
|
(
|
||||||
"context." %
|
" '%s' does not evaluate to a value in the current "
|
||||||
arg_str))
|
"context." % arg_str
|
||||||
|
)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
Explorer.explore_expr(arg_str, value, False)
|
Explorer.explore_expr(arg_str, value, False)
|
||||||
@@ -714,15 +752,16 @@ choice, if any) to return to the enclosing value."""
|
|||||||
class ExploreTypeCommand(gdb.Command):
|
class ExploreTypeCommand(gdb.Command):
|
||||||
"""Explore a type or the type of an expression.
|
"""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.
|
- ARG is a valid expression or a type name.
|
||||||
- At any stage of exploration, hit the return key (instead of a
|
- At any stage of exploration, hit the return key (instead of a
|
||||||
choice, if any) to return to the enclosing type."""
|
choice, if any) to return to the enclosing type."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(ExploreTypeCommand, self).__init__(
|
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):
|
def invoke(self, arg_str, from_tty):
|
||||||
if ExploreUtils.check_args("explore type", arg_str) == False:
|
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)
|
value = ExploreUtils.get_value_from_str(arg_str)
|
||||||
if value is not None:
|
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)
|
Explorer.explore_type(str(value.type), value.type, False)
|
||||||
return
|
return
|
||||||
|
|
||||||
raise gdb.GdbError(("'%s' is not a type or value in the current "
|
raise gdb.GdbError(
|
||||||
"context." % arg_str))
|
("'%s' is not a type or value in the current " "context." % arg_str)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
Explorer.init_env()
|
Explorer.init_env()
|
||||||
|
|||||||
@@ -29,24 +29,28 @@ class SetFilterPrefixCmd(gdb.Command):
|
|||||||
"""Prefix command for 'set' frame-filter related operations."""
|
"""Prefix command for 'set' frame-filter related operations."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(SetFilterPrefixCmd, self).__init__("set frame-filter",
|
super(SetFilterPrefixCmd, self).__init__(
|
||||||
gdb.COMMAND_OBSCURE,
|
"set frame-filter", gdb.COMMAND_OBSCURE, gdb.COMPLETE_NONE, True
|
||||||
gdb.COMPLETE_NONE, True)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ShowFilterPrefixCmd(gdb.Command):
|
class ShowFilterPrefixCmd(gdb.Command):
|
||||||
"""Prefix command for 'show' frame-filter related operations."""
|
"""Prefix command for 'show' frame-filter related operations."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(ShowFilterPrefixCmd, self).__init__("show frame-filter",
|
super(ShowFilterPrefixCmd, self).__init__(
|
||||||
gdb.COMMAND_OBSCURE,
|
"show frame-filter", gdb.COMMAND_OBSCURE, gdb.COMPLETE_NONE, True
|
||||||
gdb.COMPLETE_NONE, True)
|
)
|
||||||
|
|
||||||
|
|
||||||
class InfoFrameFilter(gdb.Command):
|
class InfoFrameFilter(gdb.Command):
|
||||||
"""List all registered Python frame-filters.
|
"""List all registered Python frame-filters.
|
||||||
|
|
||||||
Usage: info frame-filters"""
|
Usage: info frame-filters"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(InfoFrameFilter, self).__init__("info frame-filter",
|
super(InfoFrameFilter, self).__init__("info frame-filter", gdb.COMMAND_DATA)
|
||||||
gdb.COMMAND_DATA)
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def enabled_string(state):
|
def enabled_string(state):
|
||||||
"""Return "Yes" if filter is enabled, otherwise "No"."""
|
"""Return "Yes" if filter is enabled, otherwise "No"."""
|
||||||
@@ -56,9 +60,11 @@ Usage: info frame-filters"""
|
|||||||
return "No"
|
return "No"
|
||||||
|
|
||||||
def print_list(self, title, frame_filters, blank_line):
|
def print_list(self, title, frame_filters, blank_line):
|
||||||
sorted_frame_filters = sorted(frame_filters.items(),
|
sorted_frame_filters = sorted(
|
||||||
|
frame_filters.items(),
|
||||||
key=lambda i: gdb.frames.get_priority(i[1]),
|
key=lambda i: gdb.frames.get_priority(i[1]),
|
||||||
reverse=True)
|
reverse=True,
|
||||||
|
)
|
||||||
|
|
||||||
if len(sorted_frame_filters) == 0:
|
if len(sorted_frame_filters) == 0:
|
||||||
return 0
|
return 0
|
||||||
@@ -68,14 +74,14 @@ Usage: info frame-filters"""
|
|||||||
for frame_filter in sorted_frame_filters:
|
for frame_filter in sorted_frame_filters:
|
||||||
name = frame_filter[0]
|
name = frame_filter[0]
|
||||||
try:
|
try:
|
||||||
priority = '{:<8}'.format(
|
priority = "{:<8}".format(str(gdb.frames.get_priority(frame_filter[1])))
|
||||||
str(gdb.frames.get_priority(frame_filter[1])))
|
enabled = "{:<7}".format(
|
||||||
enabled = '{:<7}'.format(
|
self.enabled_string(gdb.frames.get_enabled(frame_filter[1]))
|
||||||
self.enabled_string(gdb.frames.get_enabled(frame_filter[1])))
|
)
|
||||||
print(" %s %s %s" % (priority, enabled, name))
|
print(" %s %s %s" % (priority, enabled, name))
|
||||||
except Exception:
|
except Exception:
|
||||||
e = sys.exc_info()[1]
|
e = sys.exc_info()[1]
|
||||||
print(" Error printing filter '"+name+"': "+str(e))
|
print(" Error printing filter '" + name + "': " + str(e))
|
||||||
if blank_line:
|
if blank_line:
|
||||||
print("")
|
print("")
|
||||||
return 1
|
return 1
|
||||||
@@ -84,20 +90,26 @@ Usage: info frame-filters"""
|
|||||||
any_printed = self.print_list("global frame-filters:", gdb.frame_filters, True)
|
any_printed = self.print_list("global frame-filters:", gdb.frame_filters, True)
|
||||||
|
|
||||||
cp = gdb.current_progspace()
|
cp = gdb.current_progspace()
|
||||||
any_printed += self.print_list("progspace %s frame-filters:" % cp.filename,
|
any_printed += self.print_list(
|
||||||
cp.frame_filters, True)
|
"progspace %s frame-filters:" % cp.filename, cp.frame_filters, True
|
||||||
|
)
|
||||||
|
|
||||||
for objfile in gdb.objfiles():
|
for objfile in gdb.objfiles():
|
||||||
any_printed += self.print_list("objfile %s frame-filters:" % objfile.filename,
|
any_printed += self.print_list(
|
||||||
objfile.frame_filters, False)
|
"objfile %s frame-filters:" % objfile.filename,
|
||||||
|
objfile.frame_filters,
|
||||||
|
False,
|
||||||
|
)
|
||||||
|
|
||||||
if any_printed == 0:
|
if any_printed == 0:
|
||||||
print ("No frame filters.")
|
print("No frame filters.")
|
||||||
|
|
||||||
|
|
||||||
# Internal enable/disable functions.
|
# Internal enable/disable functions.
|
||||||
|
|
||||||
|
|
||||||
def _enable_parse_arg(cmd_name, arg):
|
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.
|
enable/disable and return a tuple of arguments.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@@ -109,19 +121,21 @@ def _enable_parse_arg(cmd_name, arg):
|
|||||||
the dictionary in the case of "all".
|
the dictionary in the case of "all".
|
||||||
"""
|
"""
|
||||||
|
|
||||||
argv = gdb.string_to_argv(arg);
|
argv = gdb.string_to_argv(arg)
|
||||||
argc = len(argv)
|
argc = len(argv)
|
||||||
if argc == 0:
|
if argc == 0:
|
||||||
raise gdb.GdbError(cmd_name + " requires an argument")
|
raise gdb.GdbError(cmd_name + " requires an argument")
|
||||||
if argv[0] == "all":
|
if argv[0] == "all":
|
||||||
if argc > 1:
|
if argc > 1:
|
||||||
raise gdb.GdbError(cmd_name + ": with 'all' " \
|
raise gdb.GdbError(
|
||||||
"you may not specify a filter.")
|
cmd_name + ": with 'all' " "you may not specify a filter."
|
||||||
|
)
|
||||||
elif argc != 2:
|
elif argc != 2:
|
||||||
raise gdb.GdbError(cmd_name + " takes exactly two arguments.")
|
raise gdb.GdbError(cmd_name + " takes exactly two arguments.")
|
||||||
|
|
||||||
return argv
|
return argv
|
||||||
|
|
||||||
|
|
||||||
def _do_enable_frame_filter(command_tuple, flag):
|
def _do_enable_frame_filter(command_tuple, flag):
|
||||||
"""Worker for enabling/disabling frame_filters.
|
"""Worker for enabling/disabling frame_filters.
|
||||||
|
|
||||||
@@ -148,6 +162,7 @@ def _do_enable_frame_filter(command_tuple, flag):
|
|||||||
|
|
||||||
gdb.frames.set_enabled(ff, flag)
|
gdb.frames.set_enabled(ff, flag)
|
||||||
|
|
||||||
|
|
||||||
def _complete_frame_filter_list(text, word, all_flag):
|
def _complete_frame_filter_list(text, word, all_flag):
|
||||||
"""Worker for frame filter dictionary name completion.
|
"""Worker for frame filter dictionary name completion.
|
||||||
|
|
||||||
@@ -171,20 +186,21 @@ def _complete_frame_filter_list(text, word, all_flag):
|
|||||||
# If the user just asked for completions with no completion
|
# If the user just asked for completions with no completion
|
||||||
# hints, just return all the frame filter dictionaries we know
|
# hints, just return all the frame filter dictionaries we know
|
||||||
# about.
|
# about.
|
||||||
if (text == ""):
|
if text == "":
|
||||||
return filter_locations
|
return filter_locations
|
||||||
|
|
||||||
# Otherwise filter on what we know.
|
# 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 we only have one completion, complete it and return it.
|
||||||
if len(flist) == 1:
|
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
|
# Otherwise, return an empty list, or a list of frame filter
|
||||||
# dictionaries that the previous filter operation returned.
|
# dictionaries that the previous filter operation returned.
|
||||||
return flist
|
return flist
|
||||||
|
|
||||||
|
|
||||||
def _complete_frame_filter_name(word, printer_dict):
|
def _complete_frame_filter_name(word, printer_dict):
|
||||||
"""Worker for frame filter name completion.
|
"""Worker for frame filter name completion.
|
||||||
|
|
||||||
@@ -201,29 +217,31 @@ def _complete_frame_filter_name(word, printer_dict):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
printer_keys = printer_dict.keys()
|
printer_keys = printer_dict.keys()
|
||||||
if (word == ""):
|
if word == "":
|
||||||
return printer_keys
|
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
|
return flist
|
||||||
|
|
||||||
|
|
||||||
class EnableFrameFilter(gdb.Command):
|
class EnableFrameFilter(gdb.Command):
|
||||||
"""GDB command to enable the specified frame-filter.
|
"""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
|
DICTIONARY is the name of the frame filter dictionary on which to
|
||||||
operate. If dictionary is set to "all", perform operations on all
|
operate. If dictionary is set to "all", perform operations on all
|
||||||
dictionaries. Named dictionaries are: "global" for the global
|
dictionaries. Named dictionaries are: "global" for the global
|
||||||
frame filter dictionary, "progspace" for the program space's frame
|
frame filter dictionary, "progspace" for the program space's frame
|
||||||
filter dictionary. If either all, or the two named dictionaries
|
filter dictionary. If either all, or the two named dictionaries
|
||||||
are not specified, the dictionary name is assumed to be the name
|
are not specified, the dictionary name is assumed to be the name
|
||||||
of an "objfile" -- a shared library or an executable.
|
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):
|
def __init__(self):
|
||||||
super(EnableFrameFilter, self).__init__("enable frame-filter",
|
super(EnableFrameFilter, self).__init__("enable frame-filter", gdb.COMMAND_DATA)
|
||||||
gdb.COMMAND_DATA)
|
|
||||||
def complete(self, text, word):
|
def complete(self, text, word):
|
||||||
"""Completion function for both frame filter dictionary, and
|
"""Completion function for both frame filter dictionary, and
|
||||||
frame filter name."""
|
frame filter name."""
|
||||||
@@ -241,20 +259,22 @@ NAME matches the name of the frame-filter to operate on."""
|
|||||||
class DisableFrameFilter(gdb.Command):
|
class DisableFrameFilter(gdb.Command):
|
||||||
"""GDB command to disable the specified frame-filter.
|
"""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
|
DICTIONARY is the name of the frame filter dictionary on which to
|
||||||
operate. If dictionary is set to "all", perform operations on all
|
operate. If dictionary is set to "all", perform operations on all
|
||||||
dictionaries. Named dictionaries are: "global" for the global
|
dictionaries. Named dictionaries are: "global" for the global
|
||||||
frame filter dictionary, "progspace" for the program space's frame
|
frame filter dictionary, "progspace" for the program space's frame
|
||||||
filter dictionary. If either all, or the two named dictionaries
|
filter dictionary. If either all, or the two named dictionaries
|
||||||
are not specified, the dictionary name is assumed to be the name
|
are not specified, the dictionary name is assumed to be the name
|
||||||
of an "objfile" -- a shared library or an executable.
|
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):
|
def __init__(self):
|
||||||
super(DisableFrameFilter, self).__init__("disable frame-filter",
|
super(DisableFrameFilter, self).__init__(
|
||||||
gdb.COMMAND_DATA)
|
"disable frame-filter", gdb.COMMAND_DATA
|
||||||
|
)
|
||||||
|
|
||||||
def complete(self, text, word):
|
def complete(self, text, word):
|
||||||
"""Completion function for both frame filter dictionary, and
|
"""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)
|
command_tuple = _enable_parse_arg("disable frame-filter", arg)
|
||||||
_do_enable_frame_filter(command_tuple, False)
|
_do_enable_frame_filter(command_tuple, False)
|
||||||
|
|
||||||
|
|
||||||
class SetFrameFilterPriority(gdb.Command):
|
class SetFrameFilterPriority(gdb.Command):
|
||||||
"""GDB command to set the priority of the specified frame-filter.
|
"""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
|
DICTIONARY is the name of the frame filter dictionary on which to
|
||||||
operate. Named dictionaries are: "global" for the global frame
|
operate. Named dictionaries are: "global" for the global frame
|
||||||
filter dictionary, "progspace" for the program space's framefilter
|
filter dictionary, "progspace" for the program space's framefilter
|
||||||
dictionary. If either of these two are not specified, the
|
dictionary. If either of these two are not specified, the
|
||||||
dictionary name is assumed to be the name of an "objfile" -- a
|
dictionary name is assumed to be the name of an "objfile" -- a
|
||||||
shared library or an executable.
|
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
|
PRIORITY is the an integer to assign the new priority to the frame
|
||||||
filter."""
|
filter."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(SetFrameFilterPriority, self).__init__("set frame-filter " \
|
super(SetFrameFilterPriority, self).__init__(
|
||||||
"priority",
|
"set frame-filter " "priority", gdb.COMMAND_DATA
|
||||||
gdb.COMMAND_DATA)
|
)
|
||||||
|
|
||||||
def _parse_pri_arg(self, arg):
|
def _parse_pri_arg(self, arg):
|
||||||
"""Internal worker to parse a priority from a tuple.
|
"""Internal worker to parse a priority from a tuple.
|
||||||
@@ -305,11 +326,10 @@ filter."""
|
|||||||
gdb.GdbError: An error parsing the arguments.
|
gdb.GdbError: An error parsing the arguments.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
argv = gdb.string_to_argv(arg);
|
argv = gdb.string_to_argv(arg)
|
||||||
argc = len(argv)
|
argc = len(argv)
|
||||||
if argc != 3:
|
if argc != 3:
|
||||||
print("set frame-filter priority " \
|
print("set frame-filter priority " "takes exactly three arguments.")
|
||||||
"takes exactly three arguments.")
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return argv
|
return argv
|
||||||
@@ -355,24 +375,25 @@ filter."""
|
|||||||
if command_tuple != None:
|
if command_tuple != None:
|
||||||
self._set_filter_priority(command_tuple)
|
self._set_filter_priority(command_tuple)
|
||||||
|
|
||||||
|
|
||||||
class ShowFrameFilterPriority(gdb.Command):
|
class ShowFrameFilterPriority(gdb.Command):
|
||||||
"""GDB command to show the priority of the specified frame-filter.
|
"""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
|
DICTIONARY is the name of the frame filter dictionary on which to
|
||||||
operate. Named dictionaries are: "global" for the global frame
|
operate. Named dictionaries are: "global" for the global frame
|
||||||
filter dictionary, "progspace" for the program space's framefilter
|
filter dictionary, "progspace" for the program space's framefilter
|
||||||
dictionary. If either of these two are not specified, the
|
dictionary. If either of these two are not specified, the
|
||||||
dictionary name is assumed to be the name of an "objfile" -- a
|
dictionary name is assumed to be the name of an "objfile" -- a
|
||||||
shared library or an executable.
|
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):
|
def __init__(self):
|
||||||
super(ShowFrameFilterPriority, self).__init__("show frame-filter " \
|
super(ShowFrameFilterPriority, self).__init__(
|
||||||
"priority",
|
"show frame-filter " "priority", gdb.COMMAND_DATA
|
||||||
gdb.COMMAND_DATA)
|
)
|
||||||
|
|
||||||
def _parse_pri_arg(self, arg):
|
def _parse_pri_arg(self, arg):
|
||||||
"""Internal worker to parse a dictionary and name from a
|
"""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.
|
gdb.GdbError: An error parsing the arguments.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
argv = gdb.string_to_argv(arg);
|
argv = gdb.string_to_argv(arg)
|
||||||
argc = len(argv)
|
argc = len(argv)
|
||||||
if argc != 2:
|
if argc != 2:
|
||||||
print("show frame-filter priority " \
|
print("show frame-filter priority " "takes exactly two arguments.")
|
||||||
"takes exactly two arguments.")
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return argv
|
return argv
|
||||||
@@ -438,13 +458,20 @@ NAME matches the name of the frame-filter to operate on."""
|
|||||||
filter_name = command_tuple[1]
|
filter_name = command_tuple[1]
|
||||||
list_name = command_tuple[0]
|
list_name = command_tuple[0]
|
||||||
try:
|
try:
|
||||||
priority = self.get_filter_priority(list_name, filter_name);
|
priority = self.get_filter_priority(list_name, filter_name)
|
||||||
except Exception:
|
except Exception:
|
||||||
e = sys.exc_info()[1]
|
e = sys.exc_info()[1]
|
||||||
print("Error printing filter priority for '"+name+"':"+str(e))
|
print("Error printing filter priority for '" + name + "':" + str(e))
|
||||||
else:
|
else:
|
||||||
print("Priority of filter '" + filter_name + "' in list '" \
|
print(
|
||||||
+ list_name + "' is: " + str(priority))
|
"Priority of filter '"
|
||||||
|
+ filter_name
|
||||||
|
+ "' in list '"
|
||||||
|
+ list_name
|
||||||
|
+ "' is: "
|
||||||
|
+ str(priority)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Register commands
|
# Register commands
|
||||||
SetFilterPrefixCmd()
|
SetFilterPrefixCmd()
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ def parse_printer_regexps(arg):
|
|||||||
SyntaxError: an error processing ARG
|
SyntaxError: an error processing ARG
|
||||||
"""
|
"""
|
||||||
|
|
||||||
argv = gdb.string_to_argv(arg);
|
argv = gdb.string_to_argv(arg)
|
||||||
argc = len(argv)
|
argc = len(argv)
|
||||||
object_regexp = "" # match everything
|
object_regexp = "" # match everything
|
||||||
name_regexp = "" # match everything
|
name_regexp = "" # match everything
|
||||||
@@ -60,7 +60,7 @@ def parse_printer_regexps(arg):
|
|||||||
except SyntaxError:
|
except SyntaxError:
|
||||||
raise SyntaxError("invalid object regexp: %s" % object_regexp)
|
raise SyntaxError("invalid object regexp: %s" % object_regexp)
|
||||||
try:
|
try:
|
||||||
name_re = re.compile (name_regexp)
|
name_re = re.compile(name_regexp)
|
||||||
except SyntaxError:
|
except SyntaxError:
|
||||||
raise SyntaxError("invalid name regexp: %s" % name_regexp)
|
raise SyntaxError("invalid name regexp: %s" % name_regexp)
|
||||||
if subname_regexp is not None:
|
if subname_regexp is not None:
|
||||||
@@ -70,7 +70,7 @@ def parse_printer_regexps(arg):
|
|||||||
raise SyntaxError("invalid subname regexp: %s" % subname_regexp)
|
raise SyntaxError("invalid subname regexp: %s" % subname_regexp)
|
||||||
else:
|
else:
|
||||||
subname_re = None
|
subname_re = None
|
||||||
return(object_re, name_re, subname_re)
|
return (object_re, name_re, subname_re)
|
||||||
|
|
||||||
|
|
||||||
def printer_enabled_p(printer):
|
def printer_enabled_p(printer):
|
||||||
@@ -84,19 +84,18 @@ def printer_enabled_p(printer):
|
|||||||
class InfoPrettyPrinter(gdb.Command):
|
class InfoPrettyPrinter(gdb.Command):
|
||||||
"""GDB command to list all registered pretty-printers.
|
"""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.
|
OBJECT-REGEXP is a regular expression matching the objects to list.
|
||||||
Objects are "global", the program space's file, and the objfiles within
|
Objects are "global", the program space's file, and the objfiles within
|
||||||
that program space.
|
that program space.
|
||||||
|
|
||||||
NAME-REGEXP matches the name of the pretty-printer.
|
NAME-REGEXP matches the name of the pretty-printer.
|
||||||
Individual printers in a collection are named as
|
Individual printers in a collection are named as
|
||||||
printer-name;subprinter-name."""
|
printer-name;subprinter-name."""
|
||||||
|
|
||||||
def __init__ (self):
|
def __init__(self):
|
||||||
super(InfoPrettyPrinter, self).__init__("info pretty-printer",
|
super(InfoPrettyPrinter, self).__init__("info pretty-printer", gdb.COMMAND_DATA)
|
||||||
gdb.COMMAND_DATA)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def enabled_string(printer):
|
def enabled_string(printer):
|
||||||
@@ -123,44 +122,62 @@ printer-name;subprinter-name."""
|
|||||||
"""Print a list of pretty-printers."""
|
"""Print a list of pretty-printers."""
|
||||||
# A potential enhancement is to provide an option to list printers in
|
# A potential enhancement is to provide an option to list printers in
|
||||||
# "lookup order" (i.e. unsorted).
|
# "lookup order" (i.e. unsorted).
|
||||||
sorted_pretty_printers = sorted (copy.copy(pretty_printers),
|
sorted_pretty_printers = sorted(
|
||||||
key = self.printer_name)
|
copy.copy(pretty_printers), key=self.printer_name
|
||||||
|
)
|
||||||
for printer in sorted_pretty_printers:
|
for printer in sorted_pretty_printers:
|
||||||
name = self.printer_name(printer)
|
name = self.printer_name(printer)
|
||||||
enabled = self.enabled_string(printer)
|
enabled = self.enabled_string(printer)
|
||||||
if name_re.match(name):
|
if name_re.match(name):
|
||||||
print (" %s%s" % (name, enabled))
|
print(" %s%s" % (name, enabled))
|
||||||
if (hasattr(printer, "subprinters") and
|
if hasattr(printer, "subprinters") and printer.subprinters is not None:
|
||||||
printer.subprinters is not None):
|
sorted_subprinters = sorted(
|
||||||
sorted_subprinters = sorted (copy.copy(printer.subprinters),
|
copy.copy(printer.subprinters), key=self.printer_name
|
||||||
key = self.printer_name)
|
)
|
||||||
for subprinter in sorted_subprinters:
|
for subprinter in sorted_subprinters:
|
||||||
if (not subname_re or
|
if not subname_re or subname_re.match(subprinter.name):
|
||||||
subname_re.match(subprinter.name)):
|
print(
|
||||||
print (" %s%s" %
|
" %s%s"
|
||||||
(subprinter.name,
|
% (subprinter.name, self.enabled_string(subprinter))
|
||||||
self.enabled_string(subprinter)))
|
)
|
||||||
|
|
||||||
def invoke1(self, title, printer_list,
|
def invoke1(
|
||||||
obj_name_to_match, object_re, name_re, subname_re):
|
self, title, printer_list, obj_name_to_match, object_re, name_re, subname_re
|
||||||
|
):
|
||||||
"""Subroutine of invoke to simplify it."""
|
"""Subroutine of invoke to simplify it."""
|
||||||
if printer_list and object_re.match(obj_name_to_match):
|
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)
|
self.list_pretty_printers(printer_list, name_re, subname_re)
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
"""GDB calls this to perform the command."""
|
"""GDB calls this to perform the command."""
|
||||||
(object_re, name_re, subname_re) = parse_printer_regexps(arg)
|
(object_re, name_re, subname_re) = parse_printer_regexps(arg)
|
||||||
self.invoke1("global pretty-printers:", gdb.pretty_printers,
|
self.invoke1(
|
||||||
"global", object_re, name_re, subname_re)
|
"global pretty-printers:",
|
||||||
|
gdb.pretty_printers,
|
||||||
|
"global",
|
||||||
|
object_re,
|
||||||
|
name_re,
|
||||||
|
subname_re,
|
||||||
|
)
|
||||||
cp = gdb.current_progspace()
|
cp = gdb.current_progspace()
|
||||||
self.invoke1("progspace %s pretty-printers:" % cp.filename,
|
self.invoke1(
|
||||||
cp.pretty_printers, "progspace",
|
"progspace %s pretty-printers:" % cp.filename,
|
||||||
object_re, name_re, subname_re)
|
cp.pretty_printers,
|
||||||
|
"progspace",
|
||||||
|
object_re,
|
||||||
|
name_re,
|
||||||
|
subname_re,
|
||||||
|
)
|
||||||
for objfile in gdb.objfiles():
|
for objfile in gdb.objfiles():
|
||||||
self.invoke1("objfile %s pretty-printers:" % objfile.filename,
|
self.invoke1(
|
||||||
objfile.pretty_printers, objfile.filename,
|
"objfile %s pretty-printers:" % objfile.filename,
|
||||||
object_re, name_re, subname_re)
|
objfile.pretty_printers,
|
||||||
|
objfile.filename,
|
||||||
|
object_re,
|
||||||
|
name_re,
|
||||||
|
subname_re,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def count_enabled_printers(pretty_printers):
|
def count_enabled_printers(pretty_printers):
|
||||||
@@ -168,8 +185,7 @@ def count_enabled_printers(pretty_printers):
|
|||||||
enabled = 0
|
enabled = 0
|
||||||
total = 0
|
total = 0
|
||||||
for printer in pretty_printers:
|
for printer in pretty_printers:
|
||||||
if (hasattr(printer, "subprinters")
|
if hasattr(printer, "subprinters") and printer.subprinters is not None:
|
||||||
and printer.subprinters is not None):
|
|
||||||
if printer_enabled_p(printer):
|
if printer_enabled_p(printer):
|
||||||
for subprinter in printer.subprinters:
|
for subprinter in printer.subprinters:
|
||||||
if printer_enabled_p(subprinter):
|
if printer_enabled_p(subprinter):
|
||||||
@@ -191,7 +207,9 @@ def count_all_enabled_printers():
|
|||||||
(t_enabled, t_total) = count_enabled_printers(gdb.pretty_printers)
|
(t_enabled, t_total) = count_enabled_printers(gdb.pretty_printers)
|
||||||
enabled_count += t_enabled
|
enabled_count += t_enabled
|
||||||
total_count += t_total
|
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
|
enabled_count += t_enabled
|
||||||
total_count += t_total
|
total_count += t_total
|
||||||
for objfile in gdb.objfiles():
|
for objfile in gdb.objfiles():
|
||||||
@@ -214,10 +232,10 @@ def show_pretty_printer_enabled_summary():
|
|||||||
We count subprinters individually.
|
We count subprinters individually.
|
||||||
"""
|
"""
|
||||||
(enabled_count, total_count) = count_all_enabled_printers()
|
(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.
|
"""Worker for enabling/disabling pretty-printers.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@@ -233,10 +251,13 @@ def do_enable_pretty_printer_1 (pretty_printers, name_re, subname_re, flag):
|
|||||||
"""
|
"""
|
||||||
total = 0
|
total = 0
|
||||||
for printer in pretty_printers:
|
for printer in pretty_printers:
|
||||||
if (hasattr(printer, "name") and name_re.match(printer.name) or
|
if (
|
||||||
hasattr(printer, "__name__") and name_re.match(printer.__name__)):
|
hasattr(printer, "name")
|
||||||
if (hasattr(printer, "subprinters") and
|
and name_re.match(printer.name)
|
||||||
printer.subprinters is not None):
|
or hasattr(printer, "__name__")
|
||||||
|
and name_re.match(printer.__name__)
|
||||||
|
):
|
||||||
|
if hasattr(printer, "subprinters") and printer.subprinters is not None:
|
||||||
if not subname_re:
|
if not subname_re:
|
||||||
# Only record printers that change state.
|
# Only record printers that change state.
|
||||||
if printer_enabled_p(printer) != flag:
|
if printer_enabled_p(printer) != flag:
|
||||||
@@ -252,8 +273,10 @@ def do_enable_pretty_printer_1 (pretty_printers, name_re, subname_re, flag):
|
|||||||
for subprinter in printer.subprinters:
|
for subprinter in printer.subprinters:
|
||||||
if subname_re.match(subprinter.name):
|
if subname_re.match(subprinter.name):
|
||||||
# Only record printers that change state.
|
# Only record printers that change state.
|
||||||
if (printer_enabled_p(printer) and
|
if (
|
||||||
printer_enabled_p(subprinter) != flag):
|
printer_enabled_p(printer)
|
||||||
|
and printer_enabled_p(subprinter) != flag
|
||||||
|
):
|
||||||
total += 1
|
total += 1
|
||||||
subprinter.enabled = flag
|
subprinter.enabled = flag
|
||||||
else:
|
else:
|
||||||
@@ -275,28 +298,31 @@ def do_enable_pretty_printer_1 (pretty_printers, name_re, subname_re, flag):
|
|||||||
return total
|
return total
|
||||||
|
|
||||||
|
|
||||||
def do_enable_pretty_printer (arg, flag):
|
def do_enable_pretty_printer(arg, flag):
|
||||||
"""Internal worker for enabling/disabling pretty-printers."""
|
"""Internal worker for enabling/disabling pretty-printers."""
|
||||||
(object_re, name_re, subname_re) = parse_printer_regexps(arg)
|
(object_re, name_re, subname_re) = parse_printer_regexps(arg)
|
||||||
|
|
||||||
total = 0
|
total = 0
|
||||||
if object_re.match("global"):
|
if object_re.match("global"):
|
||||||
total += do_enable_pretty_printer_1(gdb.pretty_printers,
|
total += do_enable_pretty_printer_1(
|
||||||
name_re, subname_re, flag)
|
gdb.pretty_printers, name_re, subname_re, flag
|
||||||
|
)
|
||||||
cp = gdb.current_progspace()
|
cp = gdb.current_progspace()
|
||||||
if object_re.match("progspace"):
|
if object_re.match("progspace"):
|
||||||
total += do_enable_pretty_printer_1(cp.pretty_printers,
|
total += do_enable_pretty_printer_1(
|
||||||
name_re, subname_re, flag)
|
cp.pretty_printers, name_re, subname_re, flag
|
||||||
|
)
|
||||||
for objfile in gdb.objfiles():
|
for objfile in gdb.objfiles():
|
||||||
if object_re.match(objfile.filename):
|
if object_re.match(objfile.filename):
|
||||||
total += do_enable_pretty_printer_1(objfile.pretty_printers,
|
total += do_enable_pretty_printer_1(
|
||||||
name_re, subname_re, flag)
|
objfile.pretty_printers, name_re, subname_re, flag
|
||||||
|
)
|
||||||
|
|
||||||
if flag:
|
if flag:
|
||||||
state = "enabled"
|
state = "enabled"
|
||||||
else:
|
else:
|
||||||
state = "disabled"
|
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.
|
# Print the total list of printers currently enabled/disabled.
|
||||||
# This is to further assist the user in determining whether the result
|
# 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.
|
# 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.
|
"""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.
|
OBJECT-REGEXP is a regular expression matching the objects to examine.
|
||||||
Objects are "global", the program space's file, and the objfiles within
|
Objects are "global", the program space's file, and the objfiles within
|
||||||
that program space.
|
that program space.
|
||||||
|
|
||||||
NAME-REGEXP matches the name of the pretty-printer.
|
NAME-REGEXP matches the name of the pretty-printer.
|
||||||
Individual printers in a collection are named as
|
Individual printers in a collection are named as
|
||||||
printer-name;subprinter-name."""
|
printer-name;subprinter-name."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(EnablePrettyPrinter, self).__init__("enable pretty-printer",
|
super(EnablePrettyPrinter, self).__init__(
|
||||||
gdb.COMMAND_DATA)
|
"enable pretty-printer", gdb.COMMAND_DATA
|
||||||
|
)
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
"""GDB calls this to perform the command."""
|
"""GDB calls this to perform the command."""
|
||||||
do_enable_pretty_printer(arg, True)
|
do_enable_pretty_printer(arg, True)
|
||||||
|
|
||||||
|
|
||||||
class DisablePrettyPrinter (gdb.Command):
|
class DisablePrettyPrinter(gdb.Command):
|
||||||
"""GDB command to disable the specified pretty-printer.
|
"""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.
|
OBJECT-REGEXP is a regular expression matching the objects to examine.
|
||||||
Objects are "global", the program space's file, and the objfiles within
|
Objects are "global", the program space's file, and the objfiles within
|
||||||
that program space.
|
that program space.
|
||||||
|
|
||||||
NAME-REGEXP matches the name of the pretty-printer.
|
NAME-REGEXP matches the name of the pretty-printer.
|
||||||
Individual printers in a collection are named as
|
Individual printers in a collection are named as
|
||||||
printer-name;subprinter-name."""
|
printer-name;subprinter-name."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(DisablePrettyPrinter, self).__init__("disable pretty-printer",
|
super(DisablePrettyPrinter, self).__init__(
|
||||||
gdb.COMMAND_DATA)
|
"disable pretty-printer", gdb.COMMAND_DATA
|
||||||
|
)
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
"""GDB calls this to perform the command."""
|
"""GDB calls this to perform the command."""
|
||||||
@@ -362,4 +391,5 @@ def register_pretty_printer_commands():
|
|||||||
EnablePrettyPrinter()
|
EnablePrettyPrinter()
|
||||||
DisablePrettyPrinter()
|
DisablePrettyPrinter()
|
||||||
|
|
||||||
|
|
||||||
register_pretty_printer_commands()
|
register_pretty_printer_commands()
|
||||||
|
|||||||
@@ -19,17 +19,18 @@
|
|||||||
import gdb
|
import gdb
|
||||||
import gdb.prompt
|
import gdb.prompt
|
||||||
|
|
||||||
|
|
||||||
class _ExtendedPrompt(gdb.Parameter):
|
class _ExtendedPrompt(gdb.Parameter):
|
||||||
|
|
||||||
"""Set the extended prompt.
|
"""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
|
# Add the prompt library's dynamically generated help to the
|
||||||
# __doc__ string.
|
# __doc__ string.
|
||||||
__doc__ = __doc__ + gdb.prompt.prompt_help()
|
__doc__ = __doc__ + gdb.prompt.prompt_help()
|
||||||
@@ -38,19 +39,19 @@ The currently defined substitutions are:
|
|||||||
show_doc = "Show the extended prompt."
|
show_doc = "Show the extended prompt."
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_ExtendedPrompt, self).__init__("extended-prompt",
|
super(_ExtendedPrompt, self).__init__(
|
||||||
gdb.COMMAND_SUPPORT,
|
"extended-prompt", gdb.COMMAND_SUPPORT, gdb.PARAM_STRING_NOESCAPE
|
||||||
gdb.PARAM_STRING_NOESCAPE)
|
)
|
||||||
self.value = ''
|
self.value = ""
|
||||||
self.hook_set = False
|
self.hook_set = False
|
||||||
|
|
||||||
def get_show_string (self, pvalue):
|
def get_show_string(self, pvalue):
|
||||||
if self.value:
|
if self.value:
|
||||||
return "The extended prompt is: " + self.value
|
return "The extended prompt is: " + self.value
|
||||||
else:
|
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:
|
if self.hook_set == False:
|
||||||
gdb.prompt_hook = self.before_prompt_hook
|
gdb.prompt_hook = self.before_prompt_hook
|
||||||
self.hook_set = True
|
self.hook_set = True
|
||||||
@@ -62,4 +63,5 @@ The currently defined substitutions are:
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
_ExtendedPrompt()
|
_ExtendedPrompt()
|
||||||
|
|||||||
@@ -19,44 +19,44 @@ import gdb
|
|||||||
|
|
||||||
"""GDB commands for working with type-printers."""
|
"""GDB commands for working with type-printers."""
|
||||||
|
|
||||||
|
|
||||||
class InfoTypePrinter(gdb.Command):
|
class InfoTypePrinter(gdb.Command):
|
||||||
"""GDB command to list all registered type-printers.
|
"""GDB command to list all registered type-printers.
|
||||||
|
|
||||||
Usage: info type-printers"""
|
Usage: info type-printers"""
|
||||||
|
|
||||||
def __init__ (self):
|
def __init__(self):
|
||||||
super(InfoTypePrinter, self).__init__("info type-printers",
|
super(InfoTypePrinter, self).__init__("info type-printers", gdb.COMMAND_DATA)
|
||||||
gdb.COMMAND_DATA)
|
|
||||||
|
|
||||||
def list_type_printers(self, type_printers):
|
def list_type_printers(self, type_printers):
|
||||||
"""Print a list of type printers."""
|
"""Print a list of type printers."""
|
||||||
# A potential enhancement is to provide an option to list printers in
|
# A potential enhancement is to provide an option to list printers in
|
||||||
# "lookup order" (i.e. unsorted).
|
# "lookup order" (i.e. unsorted).
|
||||||
sorted_type_printers = sorted (copy.copy(type_printers),
|
sorted_type_printers = sorted(copy.copy(type_printers), key=lambda x: x.name)
|
||||||
key = lambda x: x.name)
|
|
||||||
for printer in sorted_type_printers:
|
for printer in sorted_type_printers:
|
||||||
if printer.enabled:
|
if printer.enabled:
|
||||||
enabled = ''
|
enabled = ""
|
||||||
else:
|
else:
|
||||||
enabled = " [disabled]"
|
enabled = " [disabled]"
|
||||||
print (" %s%s" % (printer.name, enabled))
|
print(" %s%s" % (printer.name, enabled))
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
"""GDB calls this to perform the command."""
|
"""GDB calls this to perform the command."""
|
||||||
sep = ''
|
sep = ""
|
||||||
for objfile in gdb.objfiles():
|
for objfile in gdb.objfiles():
|
||||||
if objfile.type_printers:
|
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)
|
self.list_type_printers(objfile.type_printers)
|
||||||
sep = '\n'
|
sep = "\n"
|
||||||
if gdb.current_progspace().type_printers:
|
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)
|
self.list_type_printers(gdb.current_progspace().type_printers)
|
||||||
sep = '\n'
|
sep = "\n"
|
||||||
if gdb.type_printers:
|
if gdb.type_printers:
|
||||||
print ("%sGlobal type printers:" % sep)
|
print("%sGlobal type printers:" % sep)
|
||||||
self.list_type_printers(gdb.type_printers)
|
self.list_type_printers(gdb.type_printers)
|
||||||
|
|
||||||
|
|
||||||
class _EnableOrDisableCommand(gdb.Command):
|
class _EnableOrDisableCommand(gdb.Command):
|
||||||
def __init__(self, setting, name):
|
def __init__(self, setting, name):
|
||||||
super(_EnableOrDisableCommand, self).__init__(name, gdb.COMMAND_DATA)
|
super(_EnableOrDisableCommand, self).__init__(name, gdb.COMMAND_DATA)
|
||||||
@@ -82,7 +82,7 @@ class _EnableOrDisableCommand(gdb.Command):
|
|||||||
if self.set_some(name, gdb.type_printers):
|
if self.set_some(name, gdb.type_printers):
|
||||||
ok = True
|
ok = True
|
||||||
if not ok:
|
if not ok:
|
||||||
print ("No type printer named '%s'" % name)
|
print("No type printer named '%s'" % name)
|
||||||
|
|
||||||
def add_some(self, result, word, printers):
|
def add_some(self, result, word, printers):
|
||||||
for p in printers:
|
for p in printers:
|
||||||
@@ -97,26 +97,29 @@ class _EnableOrDisableCommand(gdb.Command):
|
|||||||
self.add_some(result, word, gdb.type_printers)
|
self.add_some(result, word, gdb.type_printers)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class EnableTypePrinter(_EnableOrDisableCommand):
|
class EnableTypePrinter(_EnableOrDisableCommand):
|
||||||
"""GDB command to enable the specified type printer.
|
"""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):
|
def __init__(self):
|
||||||
super(EnableTypePrinter, self).__init__(True, "enable type-printer")
|
super(EnableTypePrinter, self).__init__(True, "enable type-printer")
|
||||||
|
|
||||||
|
|
||||||
class DisableTypePrinter(_EnableOrDisableCommand):
|
class DisableTypePrinter(_EnableOrDisableCommand):
|
||||||
"""GDB command to disable the specified type-printer.
|
"""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):
|
def __init__(self):
|
||||||
super(DisableTypePrinter, self).__init__(False, "disable type-printer")
|
super(DisableTypePrinter, self).__init__(False, "disable type-printer")
|
||||||
|
|
||||||
|
|
||||||
InfoTypePrinter()
|
InfoTypePrinter()
|
||||||
EnableTypePrinter()
|
EnableTypePrinter()
|
||||||
DisableTypePrinter()
|
DisableTypePrinter()
|
||||||
|
|||||||
@@ -49,28 +49,29 @@ def parse_unwinder_command_args(arg):
|
|||||||
locus_regexp = argv[0]
|
locus_regexp = argv[0]
|
||||||
if argc >= 2:
|
if argc >= 2:
|
||||||
name_regexp = argv[1]
|
name_regexp = argv[1]
|
||||||
return (validate_regexp(locus_regexp, "locus"),
|
return (
|
||||||
validate_regexp(name_regexp, "unwinder"))
|
validate_regexp(locus_regexp, "locus"),
|
||||||
|
validate_regexp(name_regexp, "unwinder"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class InfoUnwinder(gdb.Command):
|
class InfoUnwinder(gdb.Command):
|
||||||
"""GDB command to list unwinders.
|
"""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
|
LOCUS-REGEXP is a regular expression matching the location of the
|
||||||
unwinder. If it is omitted, all registered unwinders from all
|
unwinder. If it is omitted, all registered unwinders from all
|
||||||
loci are listed. A locus can be 'global', 'progspace' to list
|
loci are listed. A locus can be 'global', 'progspace' to list
|
||||||
the unwinders from the current progspace, or a regular expression
|
the unwinders from the current progspace, or a regular expression
|
||||||
matching filenames of objfiles.
|
matching filenames of objfiles.
|
||||||
|
|
||||||
NAME-REGEXP is a regular expression to filter unwinder names. If
|
NAME-REGEXP is a regular expression to filter unwinder names. If
|
||||||
this omitted for a specified locus, then all registered unwinders
|
this omitted for a specified locus, then all registered unwinders
|
||||||
in the locus are listed."""
|
in the locus are listed."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(InfoUnwinder, self).__init__("info unwinder",
|
super(InfoUnwinder, self).__init__("info unwinder", gdb.COMMAND_STACK)
|
||||||
gdb.COMMAND_STACK)
|
|
||||||
|
|
||||||
def list_unwinders(self, title, unwinders, name_re):
|
def list_unwinders(self, title, unwinders, name_re):
|
||||||
"""Lists the unwinders whose name matches regexp.
|
"""Lists the unwinders whose name matches regexp.
|
||||||
@@ -85,22 +86,25 @@ in the locus are listed."""
|
|||||||
print(title)
|
print(title)
|
||||||
for unwinder in unwinders:
|
for unwinder in unwinders:
|
||||||
if name_re.match(unwinder.name):
|
if name_re.match(unwinder.name):
|
||||||
print(" %s%s" % (unwinder.name,
|
print(
|
||||||
"" if unwinder.enabled else " [disabled]"))
|
" %s%s"
|
||||||
|
% (unwinder.name, "" if unwinder.enabled else " [disabled]")
|
||||||
|
)
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
locus_re, name_re = parse_unwinder_command_args(arg)
|
locus_re, name_re = parse_unwinder_command_args(arg)
|
||||||
if locus_re.match("global"):
|
if locus_re.match("global"):
|
||||||
self.list_unwinders("Global:", gdb.frame_unwinders,
|
self.list_unwinders("Global:", gdb.frame_unwinders, name_re)
|
||||||
name_re)
|
|
||||||
if locus_re.match("progspace"):
|
if locus_re.match("progspace"):
|
||||||
cp = gdb.current_progspace()
|
cp = gdb.current_progspace()
|
||||||
self.list_unwinders("Progspace %s:" % cp.filename,
|
self.list_unwinders(
|
||||||
cp.frame_unwinders, name_re)
|
"Progspace %s:" % cp.filename, cp.frame_unwinders, name_re
|
||||||
|
)
|
||||||
for objfile in gdb.objfiles():
|
for objfile in gdb.objfiles():
|
||||||
if locus_re.match(objfile.filename):
|
if locus_re.match(objfile.filename):
|
||||||
self.list_unwinders("Objfile %s:" % objfile.filename,
|
self.list_unwinders(
|
||||||
objfile.frame_unwinders, name_re)
|
"Objfile %s:" % objfile.filename, objfile.frame_unwinders, name_re
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def do_enable_unwinder1(unwinders, name_re, flag):
|
def do_enable_unwinder1(unwinders, name_re, flag):
|
||||||
@@ -129,34 +133,35 @@ def do_enable_unwinder(arg, flag):
|
|||||||
if locus_re.match("global"):
|
if locus_re.match("global"):
|
||||||
total += do_enable_unwinder1(gdb.frame_unwinders, name_re, flag)
|
total += do_enable_unwinder1(gdb.frame_unwinders, name_re, flag)
|
||||||
if locus_re.match("progspace"):
|
if locus_re.match("progspace"):
|
||||||
total += do_enable_unwinder1(gdb.current_progspace().frame_unwinders,
|
total += do_enable_unwinder1(
|
||||||
name_re, flag)
|
gdb.current_progspace().frame_unwinders, name_re, flag
|
||||||
|
)
|
||||||
for objfile in gdb.objfiles():
|
for objfile in gdb.objfiles():
|
||||||
if locus_re.match(objfile.filename):
|
if locus_re.match(objfile.filename):
|
||||||
total += do_enable_unwinder1(objfile.frame_unwinders, name_re,
|
total += do_enable_unwinder1(objfile.frame_unwinders, name_re, flag)
|
||||||
flag)
|
|
||||||
if total > 0:
|
if total > 0:
|
||||||
gdb.invalidate_cached_frames()
|
gdb.invalidate_cached_frames()
|
||||||
print("%d unwinder%s %s" % (total, "" if total == 1 else "s",
|
print(
|
||||||
"enabled" if flag else "disabled"))
|
"%d unwinder%s %s"
|
||||||
|
% (total, "" if total == 1 else "s", "enabled" if flag else "disabled")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EnableUnwinder(gdb.Command):
|
class EnableUnwinder(gdb.Command):
|
||||||
"""GDB command to enable unwinders.
|
"""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
|
LOCUS-REGEXP is a regular expression specifying the unwinders to
|
||||||
enable. It can 'global', 'progspace', or the name of an objfile
|
enable. It can 'global', 'progspace', or the name of an objfile
|
||||||
within that progspace.
|
within that progspace.
|
||||||
|
|
||||||
NAME_REGEXP is a regular expression to filter unwinder names. If
|
NAME_REGEXP is a regular expression to filter unwinder names. If
|
||||||
this omitted for a specified locus, then all registered unwinders
|
this omitted for a specified locus, then all registered unwinders
|
||||||
in the locus are affected."""
|
in the locus are affected."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(EnableUnwinder, self).__init__("enable unwinder",
|
super(EnableUnwinder, self).__init__("enable unwinder", gdb.COMMAND_STACK)
|
||||||
gdb.COMMAND_STACK)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
"""GDB calls this to perform the command."""
|
"""GDB calls this to perform the command."""
|
||||||
@@ -166,19 +171,18 @@ in the locus are affected."""
|
|||||||
class DisableUnwinder(gdb.Command):
|
class DisableUnwinder(gdb.Command):
|
||||||
"""GDB command to disable the specified unwinder.
|
"""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
|
LOCUS-REGEXP is a regular expression specifying the unwinders to
|
||||||
disable. It can 'global', 'progspace', or the name of an objfile
|
disable. It can 'global', 'progspace', or the name of an objfile
|
||||||
within that progspace.
|
within that progspace.
|
||||||
|
|
||||||
NAME_REGEXP is a regular expression to filter unwinder names. If
|
NAME_REGEXP is a regular expression to filter unwinder names. If
|
||||||
this omitted for a specified locus, then all registered unwinders
|
this omitted for a specified locus, then all registered unwinders
|
||||||
in the locus are affected."""
|
in the locus are affected."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(DisableUnwinder, self).__init__("disable unwinder",
|
super(DisableUnwinder, self).__init__("disable unwinder", gdb.COMMAND_STACK)
|
||||||
gdb.COMMAND_STACK)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
"""GDB calls this to perform the command."""
|
"""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)
|
name_re = validate_xm_regexp("xmethod name", xm_name_regexp)
|
||||||
else:
|
else:
|
||||||
name_re = None
|
name_re = None
|
||||||
return (validate_xm_regexp("locus", locus_regexp),
|
return (
|
||||||
|
validate_xm_regexp("locus", locus_regexp),
|
||||||
validate_xm_regexp("matcher name", matcher_name_regexp),
|
validate_xm_regexp("matcher name", matcher_name_regexp),
|
||||||
name_re)
|
name_re,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_global_method_matchers(locus_re, matcher_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'.
|
key in the dict will be 'global'.
|
||||||
"""
|
"""
|
||||||
locus_str = "global"
|
locus_str = "global"
|
||||||
xm_dict = { locus_str: [] }
|
xm_dict = {locus_str: []}
|
||||||
if locus_re.match("global"):
|
if locus_re.match("global"):
|
||||||
xm_dict[locus_str].extend(
|
xm_dict[locus_str].extend([m for m in gdb.xmethods if matcher_re.match(m.name)])
|
||||||
[m for m in gdb.xmethods if matcher_re.match(m.name)])
|
|
||||||
return xm_dict
|
return xm_dict
|
||||||
|
|
||||||
|
|
||||||
@@ -102,7 +103,7 @@ def get_method_matchers_in_loci(loci, locus_re, matcher_re):
|
|||||||
xm_dict = {}
|
xm_dict = {}
|
||||||
for locus in loci:
|
for locus in loci:
|
||||||
if isinstance(locus, gdb.Progspace):
|
if isinstance(locus, gdb.Progspace):
|
||||||
if not locus_re.match('progspace'):
|
if not locus_re.match("progspace"):
|
||||||
continue
|
continue
|
||||||
locus_type = "progspace"
|
locus_type = "progspace"
|
||||||
else:
|
else:
|
||||||
@@ -110,13 +111,13 @@ def get_method_matchers_in_loci(loci, locus_re, matcher_re):
|
|||||||
continue
|
continue
|
||||||
locus_type = "objfile"
|
locus_type = "objfile"
|
||||||
locus_str = "%s %s" % (locus_type, locus.filename)
|
locus_str = "%s %s" % (locus_type, locus.filename)
|
||||||
xm_dict[locus_str] = [
|
xm_dict[locus_str] = [m for m in locus.xmethods if matcher_re.match(m.name)]
|
||||||
m for m in locus.xmethods if matcher_re.match(m.name)]
|
|
||||||
return xm_dict
|
return xm_dict
|
||||||
|
|
||||||
|
|
||||||
def print_xm_info(xm_dict, name_re):
|
def print_xm_info(xm_dict, name_re):
|
||||||
"""Print a dictionary of xmethods."""
|
"""Print a dictionary of xmethods."""
|
||||||
|
|
||||||
def get_status_string(m):
|
def get_status_string(m):
|
||||||
if not m.enabled:
|
if not m.enabled:
|
||||||
return " [disabled]"
|
return " [disabled]"
|
||||||
@@ -128,14 +129,14 @@ def print_xm_info(xm_dict, name_re):
|
|||||||
for locus_str in xm_dict:
|
for locus_str in xm_dict:
|
||||||
if not xm_dict[locus_str]:
|
if not xm_dict[locus_str]:
|
||||||
continue
|
continue
|
||||||
print ("Xmethods in %s:" % locus_str)
|
print("Xmethods in %s:" % locus_str)
|
||||||
for matcher in xm_dict[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:
|
if not matcher.methods:
|
||||||
continue
|
continue
|
||||||
for m in matcher.methods:
|
for m in matcher.methods:
|
||||||
if name_re is None or name_re.match(m.name):
|
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):
|
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.
|
argument string passed to the commands.
|
||||||
"""
|
"""
|
||||||
locus_re, matcher_re, name_re = parse_xm_command_args(arg)
|
locus_re, matcher_re, name_re = parse_xm_command_args(arg)
|
||||||
set_xm_status1(get_global_method_matchers(locus_re, matcher_re), name_re,
|
set_xm_status1(get_global_method_matchers(locus_re, matcher_re), name_re, status)
|
||||||
status)
|
|
||||||
set_xm_status1(
|
set_xm_status1(
|
||||||
get_method_matchers_in_loci(
|
get_method_matchers_in_loci([gdb.current_progspace()], locus_re, matcher_re),
|
||||||
[gdb.current_progspace()], locus_re, matcher_re),
|
|
||||||
name_re,
|
name_re,
|
||||||
status)
|
status,
|
||||||
|
)
|
||||||
set_xm_status1(
|
set_xm_status1(
|
||||||
get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re),
|
get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re),
|
||||||
name_re,
|
name_re,
|
||||||
status)
|
status,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class InfoXMethod(gdb.Command):
|
class InfoXMethod(gdb.Command):
|
||||||
"""GDB command to list registered xmethod matchers.
|
"""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
|
LOCUS-REGEXP is a regular expression matching the location of the
|
||||||
xmethod matchers. If it is omitted, all registered xmethod matchers
|
xmethod matchers. If it is omitted, all registered xmethod matchers
|
||||||
from all loci are listed. A locus could be 'global', a regular expression
|
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 the current program space's filename, or a regular expression
|
||||||
matching filenames of objfiles. Locus could be 'progspace' to specify that
|
matching filenames of objfiles. Locus could be 'progspace' to specify that
|
||||||
only xmethods from the current progspace should be listed.
|
only xmethods from the current progspace should be listed.
|
||||||
|
|
||||||
NAME-REGEXP is a regular expression matching the names of xmethod
|
NAME-REGEXP is a regular expression matching the names of xmethod
|
||||||
matchers. If this omitted for a specified locus, then all registered
|
matchers. If this omitted for a specified locus, then all registered
|
||||||
xmethods in the locus are listed. To list only a certain xmethods
|
xmethods in the locus are listed. To list only a certain xmethods
|
||||||
managed by a single matcher, the name regexp can be specified as
|
managed by a single matcher, the name regexp can be specified as
|
||||||
matcher-name-regexp;xmethod-name-regexp."""
|
matcher-name-regexp;xmethod-name-regexp."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(InfoXMethod, self).__init__("info xmethod",
|
super(InfoXMethod, self).__init__("info xmethod", gdb.COMMAND_DATA)
|
||||||
gdb.COMMAND_DATA)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
locus_re, matcher_re, name_re = parse_xm_command_args(arg)
|
locus_re, matcher_re, name_re = parse_xm_command_args(arg)
|
||||||
print_xm_info(get_global_method_matchers(locus_re, matcher_re),
|
print_xm_info(get_global_method_matchers(locus_re, matcher_re), name_re)
|
||||||
name_re)
|
|
||||||
print_xm_info(
|
print_xm_info(
|
||||||
get_method_matchers_in_loci(
|
get_method_matchers_in_loci(
|
||||||
[gdb.current_progspace()], locus_re, matcher_re),
|
[gdb.current_progspace()], locus_re, matcher_re
|
||||||
name_re)
|
),
|
||||||
|
name_re,
|
||||||
|
)
|
||||||
print_xm_info(
|
print_xm_info(
|
||||||
get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re),
|
get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re), name_re
|
||||||
name_re)
|
)
|
||||||
|
|
||||||
|
|
||||||
class EnableXMethod(gdb.Command):
|
class EnableXMethod(gdb.Command):
|
||||||
"""GDB command to enable a specified (group of) xmethod(s).
|
"""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
|
LOCUS-REGEXP is a regular expression matching the location of the
|
||||||
xmethod matchers. If it is omitted, all registered xmethods matchers
|
xmethod matchers. If it is omitted, all registered xmethods matchers
|
||||||
from all loci are enabled. A locus could be 'global', a regular expression
|
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 the current program space's filename, or a regular expression
|
||||||
matching filenames of objfiles. Locus could be 'progspace' to specify that
|
matching filenames of objfiles. Locus could be 'progspace' to specify that
|
||||||
only xmethods from the current progspace should be enabled.
|
only xmethods from the current progspace should be enabled.
|
||||||
|
|
||||||
NAME-REGEXP is a regular expression matching the names of xmethods
|
NAME-REGEXP is a regular expression matching the names of xmethods
|
||||||
within a given locus. If this omitted for a specified locus, then all
|
within a given locus. If this omitted for a specified locus, then all
|
||||||
registered xmethod matchers in the locus are enabled. To enable only
|
registered xmethod matchers in the locus are enabled. To enable only
|
||||||
a certain xmethods managed by a single matcher, the name regexp can be
|
a certain xmethods managed by a single matcher, the name regexp can be
|
||||||
specified as matcher-name-regexp;xmethod-name-regexp."""
|
specified as matcher-name-regexp;xmethod-name-regexp."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(EnableXMethod, self).__init__("enable xmethod",
|
super(EnableXMethod, self).__init__("enable xmethod", gdb.COMMAND_DATA)
|
||||||
gdb.COMMAND_DATA)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
set_xm_status(arg, True)
|
set_xm_status(arg, True)
|
||||||
@@ -238,24 +238,23 @@ specified as matcher-name-regexp;xmethod-name-regexp."""
|
|||||||
class DisableXMethod(gdb.Command):
|
class DisableXMethod(gdb.Command):
|
||||||
"""GDB command to disable a specified (group of) xmethod(s).
|
"""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
|
LOCUS-REGEXP is a regular expression matching the location of the
|
||||||
xmethod matchers. If it is omitted, all registered xmethod matchers
|
xmethod matchers. If it is omitted, all registered xmethod matchers
|
||||||
from all loci are disabled. A locus could be 'global', a regular
|
from all loci are disabled. A locus could be 'global', a regular
|
||||||
expression matching the current program space's filename, or a regular
|
expression matching the current program space's filename, or a regular
|
||||||
expression filenames of objfiles. Locus could be 'progspace' to specify
|
expression filenames of objfiles. Locus could be 'progspace' to specify
|
||||||
that only xmethods from the current progspace should be disabled.
|
that only xmethods from the current progspace should be disabled.
|
||||||
|
|
||||||
NAME-REGEXP is a regular expression matching the names of xmethods
|
NAME-REGEXP is a regular expression matching the names of xmethods
|
||||||
within a given locus. If this omitted for a specified locus, then all
|
within a given locus. If this omitted for a specified locus, then all
|
||||||
registered xmethod matchers in the locus are disabled. To disable
|
registered xmethod matchers in the locus are disabled. To disable
|
||||||
only a certain xmethods managed by a single matcher, the name regexp
|
only a certain xmethods managed by a single matcher, the name regexp
|
||||||
can be specified as matcher-name-regexp;xmethod-name-regexp."""
|
can be specified as matcher-name-regexp;xmethod-name-regexp."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(DisableXMethod, self).__init__("disable xmethod",
|
super(DisableXMethod, self).__init__("disable xmethod", gdb.COMMAND_DATA)
|
||||||
gdb.COMMAND_DATA)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
set_xm_status(arg, False)
|
set_xm_status(arg, False)
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ from gdb.FrameDecorator import FrameDecorator
|
|||||||
import itertools
|
import itertools
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
|
|
||||||
def get_priority(filter_item):
|
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
|
from a frame filter object. This is a fail free function as it is
|
||||||
used in sorting and filtering. If a badly implemented frame
|
used in sorting and filtering. If a badly implemented frame
|
||||||
filter does not implement the priority attribute, return zero
|
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.
|
# (incorrectly) set a priority, set it to zero.
|
||||||
return getattr(filter_item, "priority", 0)
|
return getattr(filter_item, "priority", 0)
|
||||||
|
|
||||||
|
|
||||||
def set_priority(filter_item, priority):
|
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:
|
Arguments:
|
||||||
filter_item: An object conforming to the frame filter
|
filter_item: An object conforming to the frame filter
|
||||||
@@ -53,8 +55,9 @@ def set_priority(filter_item, priority):
|
|||||||
|
|
||||||
filter_item.priority = priority
|
filter_item.priority = priority
|
||||||
|
|
||||||
|
|
||||||
def get_enabled(filter_item):
|
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
|
from a frame filter object. This is a fail free function as it is
|
||||||
used in sorting and filtering. If a badly implemented frame
|
used in sorting and filtering. If a badly implemented frame
|
||||||
filter does not implement the enabled attribute, return False
|
filter does not implement the enabled attribute, return False
|
||||||
@@ -75,8 +78,9 @@ def get_enabled(filter_item):
|
|||||||
# enabled to False.
|
# enabled to False.
|
||||||
return getattr(filter_item, "enabled", False)
|
return getattr(filter_item, "enabled", False)
|
||||||
|
|
||||||
|
|
||||||
def set_enabled(filter_item, state):
|
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.
|
state.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@@ -87,8 +91,9 @@ def set_enabled(filter_item, state):
|
|||||||
|
|
||||||
filter_item.enabled = state
|
filter_item.enabled = state
|
||||||
|
|
||||||
|
|
||||||
def return_list(name):
|
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
|
dictionary, depending on the name supplied as an argument. If the
|
||||||
name is not "all", "global" or "progspace", it is assumed to name
|
name is not "all", "global" or "progspace", it is assumed to name
|
||||||
an object-file.
|
an object-file.
|
||||||
@@ -132,8 +137,9 @@ def return_list(name):
|
|||||||
msg = "Cannot find frame-filter dictionary for '" + name + "'"
|
msg = "Cannot find frame-filter dictionary for '" + name + "'"
|
||||||
raise gdb.GdbError(msg)
|
raise gdb.GdbError(msg)
|
||||||
|
|
||||||
|
|
||||||
def _sort_list():
|
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
|
lists, prune any filters with the state set to "disabled", and
|
||||||
sort the list on the frame-filter's "priority" attribute.
|
sort the list on the frame-filter's "priority" attribute.
|
||||||
|
|
||||||
@@ -143,16 +149,15 @@ def _sort_list():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
all_filters = return_list("all")
|
all_filters = return_list("all")
|
||||||
sorted_frame_filters = sorted(all_filters, key = get_priority,
|
sorted_frame_filters = sorted(all_filters, key=get_priority, reverse=True)
|
||||||
reverse = True)
|
|
||||||
|
|
||||||
sorted_frame_filters = filter(get_enabled,
|
sorted_frame_filters = filter(get_enabled, sorted_frame_filters)
|
||||||
sorted_frame_filters)
|
|
||||||
|
|
||||||
return sorted_frame_filters
|
return sorted_frame_filters
|
||||||
|
|
||||||
|
|
||||||
def execute_frame_filters(frame, frame_low, frame_high):
|
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.
|
of frame filters. Each filter is executed in priority order.
|
||||||
After the execution completes, slice the iterator to frame_low -
|
After the execution completes, slice the iterator to frame_low -
|
||||||
frame_high range.
|
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
|
# Apply a basic frame decorator to all gdb.Frames. This unifies
|
||||||
# the interface. Python 3.x moved the itertools.imap
|
# the interface. Python 3.x moved the itertools.imap
|
||||||
# functionality to map(), so check if it is available.
|
# functionality to map(), so check if it is available.
|
||||||
if hasattr(itertools,"imap"):
|
if hasattr(itertools, "imap"):
|
||||||
frame_iterator = itertools.imap(FrameDecorator, frame_iterator)
|
frame_iterator = itertools.imap(FrameDecorator, frame_iterator)
|
||||||
else:
|
else:
|
||||||
frame_iterator = map(FrameDecorator, frame_iterator)
|
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:
|
for frame_item in frame_iterator:
|
||||||
if count >= slice_length:
|
if count >= slice_length:
|
||||||
sliced.popleft();
|
sliced.popleft()
|
||||||
count = count + 1
|
count = count + 1
|
||||||
sliced.append(frame_item)
|
sliced.append(frame_item)
|
||||||
|
|
||||||
@@ -221,7 +226,7 @@ def execute_frame_filters(frame, frame_low, frame_high):
|
|||||||
else:
|
else:
|
||||||
# As frames start from 0, add one to frame_high so islice
|
# As frames start from 0, add one to frame_high so islice
|
||||||
# correctly finds the end
|
# correctly finds the end
|
||||||
frame_high = frame_high + 1;
|
frame_high = frame_high + 1
|
||||||
|
|
||||||
sliced = itertools.islice(frame_iterator, frame_low, frame_high)
|
sliced = itertools.islice(frame_iterator, frame_low, frame_high)
|
||||||
|
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ import gdb
|
|||||||
class _AsString(gdb.Function):
|
class _AsString(gdb.Function):
|
||||||
"""Return the string representation of a value.
|
"""Return the string representation of a value.
|
||||||
|
|
||||||
Usage: $_as_string (VALUE)
|
Usage: $_as_string (VALUE)
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
VALUE: any value
|
VALUE: any value
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The string representation of the value."""
|
The string representation of the value."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -34,4 +34,5 @@ Returns:
|
|||||||
def invoke(self, val):
|
def invoke(self, val):
|
||||||
return str(val)
|
return str(val)
|
||||||
|
|
||||||
|
|
||||||
_AsString()
|
_AsString()
|
||||||
|
|||||||
@@ -17,12 +17,13 @@
|
|||||||
import gdb
|
import gdb
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
class CallerIs(gdb.Function):
|
class CallerIs(gdb.Function):
|
||||||
"""Check the calling function's name.
|
"""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.
|
||||||
|
|
||||||
@@ -31,13 +32,13 @@ Arguments:
|
|||||||
the stack from that point then the result is False.
|
the stack from that point then the result is False.
|
||||||
The default is 1.
|
The default is 1.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if the function's name at the specified frame is equal to NAME."""
|
True if the function's name at the specified frame is equal to NAME."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(CallerIs, self).__init__("_caller_is")
|
super(CallerIs, self).__init__("_caller_is")
|
||||||
|
|
||||||
def invoke(self, name, nframes = 1):
|
def invoke(self, name, nframes=1):
|
||||||
if nframes < 0:
|
if nframes < 0:
|
||||||
raise ValueError("nframes must be >= 0")
|
raise ValueError("nframes must be >= 0")
|
||||||
frame = gdb.selected_frame()
|
frame = gdb.selected_frame()
|
||||||
@@ -48,12 +49,13 @@ Returns:
|
|||||||
nframes = nframes - 1
|
nframes = nframes - 1
|
||||||
return frame.name() == name.string()
|
return frame.name() == name.string()
|
||||||
|
|
||||||
|
|
||||||
class CallerMatches(gdb.Function):
|
class CallerMatches(gdb.Function):
|
||||||
"""Compare the calling function's name with a regexp.
|
"""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.
|
||||||
|
|
||||||
@@ -62,13 +64,13 @@ Arguments:
|
|||||||
the stack from that point then the result is False.
|
the stack from that point then the result is False.
|
||||||
The default is 1.
|
The default is 1.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if the function's name at the specified frame matches REGEX."""
|
True if the function's name at the specified frame matches REGEX."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(CallerMatches, self).__init__("_caller_matches")
|
super(CallerMatches, self).__init__("_caller_matches")
|
||||||
|
|
||||||
def invoke(self, name, nframes = 1):
|
def invoke(self, name, nframes=1):
|
||||||
if nframes < 0:
|
if nframes < 0:
|
||||||
raise ValueError("nframes must be >= 0")
|
raise ValueError("nframes must be >= 0")
|
||||||
frame = gdb.selected_frame()
|
frame = gdb.selected_frame()
|
||||||
@@ -79,12 +81,13 @@ Returns:
|
|||||||
nframes = nframes - 1
|
nframes = nframes - 1
|
||||||
return re.match(name.string(), frame.name()) is not None
|
return re.match(name.string(), frame.name()) is not None
|
||||||
|
|
||||||
|
|
||||||
class AnyCallerIs(gdb.Function):
|
class AnyCallerIs(gdb.Function):
|
||||||
"""Check all calling function's names.
|
"""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.
|
||||||
|
|
||||||
@@ -93,13 +96,13 @@ Arguments:
|
|||||||
the stack from that point then the result is False.
|
the stack from that point then the result is False.
|
||||||
The default is 1.
|
The default is 1.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if any function's name is equal to NAME."""
|
True if any function's name is equal to NAME."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(AnyCallerIs, self).__init__("_any_caller_is")
|
super(AnyCallerIs, self).__init__("_any_caller_is")
|
||||||
|
|
||||||
def invoke(self, name, nframes = 1):
|
def invoke(self, name, nframes=1):
|
||||||
if nframes < 0:
|
if nframes < 0:
|
||||||
raise ValueError("nframes must be >= 0")
|
raise ValueError("nframes must be >= 0")
|
||||||
frame = gdb.selected_frame()
|
frame = gdb.selected_frame()
|
||||||
@@ -112,12 +115,13 @@ Returns:
|
|||||||
nframes = nframes - 1
|
nframes = nframes - 1
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class AnyCallerMatches(gdb.Function):
|
class AnyCallerMatches(gdb.Function):
|
||||||
"""Compare all calling function's names with a regexp.
|
"""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.
|
||||||
|
|
||||||
@@ -126,13 +130,13 @@ Arguments:
|
|||||||
the stack from that point then the result is False.
|
the stack from that point then the result is False.
|
||||||
The default is 1.
|
The default is 1.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if any function's name matches REGEX."""
|
True if any function's name matches REGEX."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(AnyCallerMatches, self).__init__("_any_caller_matches")
|
super(AnyCallerMatches, self).__init__("_any_caller_matches")
|
||||||
|
|
||||||
def invoke(self, name, nframes = 1):
|
def invoke(self, name, nframes=1):
|
||||||
if nframes < 0:
|
if nframes < 0:
|
||||||
raise ValueError("nframes must be >= 0")
|
raise ValueError("nframes must be >= 0")
|
||||||
frame = gdb.selected_frame()
|
frame = gdb.selected_frame()
|
||||||
@@ -146,6 +150,7 @@ Returns:
|
|||||||
nframes = nframes - 1
|
nframes = nframes - 1
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
CallerIs()
|
CallerIs()
|
||||||
CallerMatches()
|
CallerMatches()
|
||||||
AnyCallerIs()
|
AnyCallerIs()
|
||||||
|
|||||||
@@ -23,10 +23,11 @@ import re
|
|||||||
class _MemEq(gdb.Function):
|
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:
|
Returns:
|
||||||
True if LEN bytes at A and B compare equally."""
|
True if LEN bytes at A and B compare equally."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_MemEq, self).__init__("_memeq")
|
super(_MemEq, self).__init__("_memeq")
|
||||||
|
|
||||||
@@ -46,10 +47,11 @@ Returns:
|
|||||||
class _StrLen(gdb.Function):
|
class _StrLen(gdb.Function):
|
||||||
"""$_strlen - compute string length.
|
"""$_strlen - compute string length.
|
||||||
|
|
||||||
Usage: $_strlen (A)
|
Usage: $_strlen (A)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Length of string A, assumed to be a string in the current language."""
|
Length of string A, assumed to be a string in the current language."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_StrLen, self).__init__("_strlen")
|
super(_StrLen, self).__init__("_strlen")
|
||||||
|
|
||||||
@@ -61,14 +63,15 @@ Returns:
|
|||||||
class _StrEq(gdb.Function):
|
class _StrEq(gdb.Function):
|
||||||
"""$_streq - check string equality.
|
"""$_streq - check string equality.
|
||||||
|
|
||||||
Usage: $_streq (A, B)
|
Usage: $_streq (A, B)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if A and B are identical strings in the current language.
|
True if A and B are identical strings in the current language.
|
||||||
|
|
||||||
Example (amd64-linux):
|
Example (amd64-linux):
|
||||||
catch syscall open
|
catch syscall open
|
||||||
cond $bpnum $_streq((char*) $rdi, "foo")"""
|
cond $bpnum $_streq((char*) $rdi, "foo")"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_StrEq, self).__init__("_streq")
|
super(_StrEq, self).__init__("_streq")
|
||||||
|
|
||||||
@@ -79,11 +82,12 @@ Example (amd64-linux):
|
|||||||
class _RegEx(gdb.Function):
|
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:
|
Returns:
|
||||||
True if string STRING (in the current language) matches the
|
True if string STRING (in the current language) matches the
|
||||||
regular expression REGEX."""
|
regular expression REGEX."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_RegEx, self).__init__("_regex")
|
super(_RegEx, self).__init__("_regex")
|
||||||
|
|
||||||
|
|||||||
@@ -23,21 +23,23 @@ if sys.version_info[0] > 2:
|
|||||||
basestring = str
|
basestring = str
|
||||||
long = int
|
long = int
|
||||||
|
|
||||||
|
|
||||||
class MpxBound128Printer:
|
class MpxBound128Printer:
|
||||||
"""Adds size field to a mpx __gdb_builtin_type_bound128 type."""
|
"""Adds size field to a mpx __gdb_builtin_type_bound128 type."""
|
||||||
|
|
||||||
def __init__ (self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string (self):
|
def to_string(self):
|
||||||
upper = self.val["ubound"]
|
upper = self.val["ubound"]
|
||||||
lower = self.val["lbound"]
|
lower = self.val["lbound"]
|
||||||
size = (long) ((upper) - (lower))
|
size = (long)((upper) - (lower))
|
||||||
if size > -1:
|
if size > -1:
|
||||||
size = 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
|
return result
|
||||||
|
|
||||||
gdb.printing.add_builtin_pretty_printer ('mpx_bound128',
|
|
||||||
'^builtin_type_bound128',
|
gdb.printing.add_builtin_pretty_printer(
|
||||||
MpxBound128Printer)
|
"mpx_bound128", "^builtin_type_bound128", MpxBound128Printer
|
||||||
|
)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ if sys.version_info[0] > 2:
|
|||||||
basestring = str
|
basestring = str
|
||||||
long = int
|
long = int
|
||||||
|
|
||||||
|
|
||||||
class PrettyPrinter(object):
|
class PrettyPrinter(object):
|
||||||
"""A basic pretty-printer.
|
"""A basic pretty-printer.
|
||||||
|
|
||||||
@@ -124,8 +125,9 @@ def register_pretty_printer(obj, printer, replace=False):
|
|||||||
obj = gdb
|
obj = gdb
|
||||||
else:
|
else:
|
||||||
if gdb.parameter("verbose"):
|
if gdb.parameter("verbose"):
|
||||||
gdb.write("Registering %s pretty-printer for %s ...\n" % (
|
gdb.write(
|
||||||
name, obj.filename))
|
"Registering %s pretty-printer for %s ...\n" % (name, obj.filename)
|
||||||
|
)
|
||||||
|
|
||||||
# Printers implemented as functions are old-style. In order to not risk
|
# Printers implemented as functions are old-style. In order to not risk
|
||||||
# breaking anything we do not check __name__ here.
|
# 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]
|
del obj.pretty_printers[i]
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("pretty-printer already registered: %s" %
|
raise RuntimeError(
|
||||||
printer.name)
|
"pretty-printer already registered: %s" % printer.name
|
||||||
|
)
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
obj.pretty_printers.insert(0, printer)
|
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
|
# cumbersome to make a regexp of a regexp). So now the name is a
|
||||||
# separate parameter.
|
# separate parameter.
|
||||||
|
|
||||||
self.subprinters.append(self.RegexpSubprinter(name, regexp,
|
self.subprinters.append(self.RegexpSubprinter(name, regexp, gen_printer))
|
||||||
gen_printer))
|
|
||||||
|
|
||||||
def __call__(self, val):
|
def __call__(self, val):
|
||||||
"""Lookup the pretty-printer for the provided value."""
|
"""Lookup the pretty-printer for the provided value."""
|
||||||
@@ -220,6 +222,7 @@ class RegexpCollectionPrettyPrinter(PrettyPrinter):
|
|||||||
# Cannot find a pretty printer. Return None.
|
# Cannot find a pretty printer. Return None.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# A helper class for printing enum types. This class is instantiated
|
# A helper class for printing enum types. This class is instantiated
|
||||||
# with a list of enumerators to print a particular Value.
|
# with a list of enumerators to print a particular Value.
|
||||||
class _EnumInstance:
|
class _EnumInstance:
|
||||||
@@ -238,9 +241,10 @@ class _EnumInstance:
|
|||||||
any_found = True
|
any_found = True
|
||||||
if not any_found or v != 0:
|
if not any_found or v != 0:
|
||||||
# Leftover value.
|
# 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))
|
return "0x%x [%s]" % (int(self.val), " | ".join(flag_list))
|
||||||
|
|
||||||
|
|
||||||
class FlagEnumerationPrinter(PrettyPrinter):
|
class FlagEnumerationPrinter(PrettyPrinter):
|
||||||
"""A pretty-printer which can be used to print a flag-style enumeration.
|
"""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
|
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))
|
self.enumerators.append((field.name, field.enumval))
|
||||||
# Sorting the enumerators by value usually does the right
|
# Sorting the enumerators by value usually does the right
|
||||||
# thing.
|
# thing.
|
||||||
self.enumerators.sort(key = lambda x: x[1])
|
self.enumerators.sort(key=lambda x: x[1])
|
||||||
|
|
||||||
if self.enabled:
|
if self.enabled:
|
||||||
return _EnumInstance(self.enumerators, val)
|
return _EnumInstance(self.enumerators, val)
|
||||||
@@ -281,5 +285,6 @@ register_pretty_printer(None, _builtin_pretty_printers)
|
|||||||
|
|
||||||
# Add a builtin pretty-printer.
|
# Add a builtin pretty-printer.
|
||||||
|
|
||||||
|
|
||||||
def add_builtin_pretty_printer(name, regexp, printer):
|
def add_builtin_pretty_printer(name, regexp, printer):
|
||||||
_builtin_pretty_printers.add_printer(name, regexp, printer)
|
_builtin_pretty_printers.add_printer(name, regexp, printer)
|
||||||
|
|||||||
@@ -19,10 +19,12 @@
|
|||||||
import gdb
|
import gdb
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
def _prompt_pwd(ignore):
|
def _prompt_pwd(ignore):
|
||||||
"The current working directory."
|
"The current working directory."
|
||||||
return os.getcwd()
|
return os.getcwd()
|
||||||
|
|
||||||
|
|
||||||
def _prompt_object_attr(func, what, attr, nattr):
|
def _prompt_object_attr(func, what, attr, nattr):
|
||||||
"""Internal worker for fetching GDB attributes."""
|
"""Internal worker for fetching GDB attributes."""
|
||||||
if attr is None:
|
if attr is None:
|
||||||
@@ -30,91 +32,104 @@ def _prompt_object_attr(func, what, attr, nattr):
|
|||||||
try:
|
try:
|
||||||
obj = func()
|
obj = func()
|
||||||
except gdb.error:
|
except gdb.error:
|
||||||
return '<no %s>' % what
|
return "<no %s>" % what
|
||||||
if hasattr(obj, attr):
|
if hasattr(obj, attr):
|
||||||
result = getattr(obj, attr)
|
result = getattr(obj, attr)
|
||||||
if callable(result):
|
if callable(result):
|
||||||
result = result()
|
result = result()
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
return '<no attribute %s on current %s>' % (attr, what)
|
return "<no attribute %s on current %s>" % (attr, what)
|
||||||
|
|
||||||
|
|
||||||
def _prompt_frame(attr):
|
def _prompt_frame(attr):
|
||||||
"The selected frame; an argument names a frame parameter."
|
"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):
|
def _prompt_thread(attr):
|
||||||
"The selected thread; an argument names a thread parameter."
|
"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):
|
def _prompt_version(attr):
|
||||||
"The version of GDB."
|
"The version of GDB."
|
||||||
return gdb.VERSION
|
return gdb.VERSION
|
||||||
|
|
||||||
|
|
||||||
def _prompt_esc(attr):
|
def _prompt_esc(attr):
|
||||||
"The ESC character."
|
"The ESC character."
|
||||||
return '\033'
|
return "\033"
|
||||||
|
|
||||||
|
|
||||||
def _prompt_bs(attr):
|
def _prompt_bs(attr):
|
||||||
"A backslash."
|
"A backslash."
|
||||||
return '\\'
|
return "\\"
|
||||||
|
|
||||||
|
|
||||||
def _prompt_n(attr):
|
def _prompt_n(attr):
|
||||||
"A newline."
|
"A newline."
|
||||||
return '\n'
|
return "\n"
|
||||||
|
|
||||||
|
|
||||||
def _prompt_r(attr):
|
def _prompt_r(attr):
|
||||||
"A carriage return."
|
"A carriage return."
|
||||||
return '\r'
|
return "\r"
|
||||||
|
|
||||||
|
|
||||||
def _prompt_param(attr):
|
def _prompt_param(attr):
|
||||||
"A parameter's value; the argument names the parameter."
|
"A parameter's value; the argument names the parameter."
|
||||||
return gdb.parameter(attr)
|
return gdb.parameter(attr)
|
||||||
|
|
||||||
|
|
||||||
def _prompt_noprint_begin(attr):
|
def _prompt_noprint_begin(attr):
|
||||||
"Begins a sequence of non-printing characters."
|
"Begins a sequence of non-printing characters."
|
||||||
return '\001'
|
return "\001"
|
||||||
|
|
||||||
|
|
||||||
def _prompt_noprint_end(attr):
|
def _prompt_noprint_end(attr):
|
||||||
"Ends a sequence of non-printing characters."
|
"Ends a sequence of non-printing characters."
|
||||||
return '\002'
|
return "\002"
|
||||||
|
|
||||||
|
|
||||||
prompt_substitutions = {
|
prompt_substitutions = {
|
||||||
'e': _prompt_esc,
|
"e": _prompt_esc,
|
||||||
'\\': _prompt_bs,
|
"\\": _prompt_bs,
|
||||||
'n': _prompt_n,
|
"n": _prompt_n,
|
||||||
'r': _prompt_r,
|
"r": _prompt_r,
|
||||||
'v': _prompt_version,
|
"v": _prompt_version,
|
||||||
'w': _prompt_pwd,
|
"w": _prompt_pwd,
|
||||||
'f': _prompt_frame,
|
"f": _prompt_frame,
|
||||||
't': _prompt_thread,
|
"t": _prompt_thread,
|
||||||
'p': _prompt_param,
|
"p": _prompt_param,
|
||||||
'[': _prompt_noprint_begin,
|
"[": _prompt_noprint_begin,
|
||||||
']': _prompt_noprint_end
|
"]": _prompt_noprint_end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def prompt_help():
|
def prompt_help():
|
||||||
"""Generate help dynamically from the __doc__ strings of attribute
|
"""Generate help dynamically from the __doc__ strings of attribute
|
||||||
functions."""
|
functions."""
|
||||||
|
|
||||||
result = ''
|
result = ""
|
||||||
keys = sorted (prompt_substitutions.keys())
|
keys = sorted(prompt_substitutions.keys())
|
||||||
for key in 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 += """
|
result += """
|
||||||
A substitution can be used in a simple form, like "\\f".
|
A substitution can be used in a simple form, like "\\f".
|
||||||
An argument can also be passed to it, like "\\f{name}".
|
An argument can also be passed to it, like "\\f{name}".
|
||||||
The meaning of the argument depends on the particular substitution."""
|
The meaning of the argument depends on the particular substitution."""
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def substitute_prompt(prompt):
|
def substitute_prompt(prompt):
|
||||||
"Perform substitutions on PROMPT."
|
"Perform substitutions on PROMPT."
|
||||||
|
|
||||||
result = ''
|
result = ""
|
||||||
plen = len(prompt)
|
plen = len(prompt)
|
||||||
i = 0
|
i = 0
|
||||||
while i < plen:
|
while i < plen:
|
||||||
if prompt[i] == '\\':
|
if prompt[i] == "\\":
|
||||||
i = i + 1
|
i = i + 1
|
||||||
if i >= plen:
|
if i >= plen:
|
||||||
break
|
break
|
||||||
@@ -123,12 +138,12 @@ def substitute_prompt(prompt):
|
|||||||
if cmdch in prompt_substitutions:
|
if cmdch in prompt_substitutions:
|
||||||
cmd = prompt_substitutions[cmdch]
|
cmd = prompt_substitutions[cmdch]
|
||||||
|
|
||||||
if i + 1 < plen and prompt[i + 1] == '{':
|
if i + 1 < plen and prompt[i + 1] == "{":
|
||||||
j = i + 1
|
j = i + 1
|
||||||
while j < plen and prompt[j] != '}':
|
while j < plen and prompt[j] != "}":
|
||||||
j = j + 1
|
j = j + 1
|
||||||
# Just ignore formatting errors.
|
# Just ignore formatting errors.
|
||||||
if j >= plen or prompt[j] != '}':
|
if j >= plen or prompt[j] != "}":
|
||||||
arg = None
|
arg = None
|
||||||
else:
|
else:
|
||||||
arg = prompt[i + 2 : j]
|
arg = prompt[i + 2 : j]
|
||||||
|
|||||||
@@ -30,11 +30,12 @@ def get_basic_type(type_):
|
|||||||
and typedefs/references converted to the underlying type.
|
and typedefs/references converted to the underlying type.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
while (type_.code == gdb.TYPE_CODE_REF or
|
while (
|
||||||
type_.code == gdb.TYPE_CODE_RVALUE_REF or
|
type_.code == gdb.TYPE_CODE_REF
|
||||||
type_.code == gdb.TYPE_CODE_TYPEDEF):
|
or type_.code == gdb.TYPE_CODE_RVALUE_REF
|
||||||
if (type_.code == gdb.TYPE_CODE_REF or
|
or type_.code == gdb.TYPE_CODE_TYPEDEF
|
||||||
type_.code == gdb.TYPE_CODE_RVALUE_REF):
|
):
|
||||||
|
if type_.code == gdb.TYPE_CODE_REF or type_.code == gdb.TYPE_CODE_RVALUE_REF:
|
||||||
type_ = type_.target()
|
type_ = type_.target()
|
||||||
else:
|
else:
|
||||||
type_ = type_.strip_typedefs()
|
type_ = type_.strip_typedefs()
|
||||||
@@ -57,8 +58,7 @@ def has_field(type_, field):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
type_ = get_basic_type(type_)
|
type_ = get_basic_type(type_)
|
||||||
if (type_.code != gdb.TYPE_CODE_STRUCT and
|
if type_.code != gdb.TYPE_CODE_STRUCT and type_.code != gdb.TYPE_CODE_UNION:
|
||||||
type_.code != gdb.TYPE_CODE_UNION):
|
|
||||||
raise TypeError("not a struct or union")
|
raise TypeError("not a struct or union")
|
||||||
for f in type_.fields():
|
for f in type_.fields():
|
||||||
if f.is_base_class:
|
if f.is_base_class:
|
||||||
@@ -93,7 +93,7 @@ def make_enum_dict(enum_type):
|
|||||||
return enum_dict
|
return enum_dict
|
||||||
|
|
||||||
|
|
||||||
def deep_items (type_):
|
def deep_items(type_):
|
||||||
"""Return an iterator that recursively traverses anonymous fields.
|
"""Return an iterator that recursively traverses anonymous fields.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@@ -105,13 +105,14 @@ def deep_items (type_):
|
|||||||
pairs of key, value, but for any anonymous struct or union
|
pairs of key, value, but for any anonymous struct or union
|
||||||
field that field is traversed recursively, depth-first.
|
field that field is traversed recursively, depth-first.
|
||||||
"""
|
"""
|
||||||
for k, v in type_.iteritems ():
|
for k, v in type_.iteritems():
|
||||||
if k:
|
if k:
|
||||||
yield k, v
|
yield k, v
|
||||||
else:
|
else:
|
||||||
for i in deep_items (v.type):
|
for i in deep_items(v.type):
|
||||||
yield i
|
yield i
|
||||||
|
|
||||||
|
|
||||||
class TypePrinter(object):
|
class TypePrinter(object):
|
||||||
"""The base class for type printers.
|
"""The base class for type printers.
|
||||||
|
|
||||||
@@ -134,6 +135,7 @@ class TypePrinter(object):
|
|||||||
def instantiate(self):
|
def instantiate(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# Helper function for computing the list of type recognizers.
|
# Helper function for computing the list of type recognizers.
|
||||||
def _get_some_type_recognizers(result, plist):
|
def _get_some_type_recognizers(result, plist):
|
||||||
for printer in plist:
|
for printer in plist:
|
||||||
@@ -143,6 +145,7 @@ def _get_some_type_recognizers(result, plist):
|
|||||||
result.append(inst)
|
result.append(inst)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_type_recognizers():
|
def get_type_recognizers():
|
||||||
"Return a list of the enabled type recognizers for the current context."
|
"Return a list of the enabled type recognizers for the current context."
|
||||||
result = []
|
result = []
|
||||||
@@ -157,6 +160,7 @@ def get_type_recognizers():
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def apply_type_recognizers(recognizers, type_obj):
|
def apply_type_recognizers(recognizers, type_obj):
|
||||||
"""Apply the given list of type recognizers to the type 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
|
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 result
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def register_type_printer(locus, printer):
|
def register_type_printer(locus, printer):
|
||||||
"""Register a type printer.
|
"""Register a type printer.
|
||||||
PRINTER is the type printer instance.
|
PRINTER is the type printer instance.
|
||||||
|
|||||||
@@ -77,8 +77,9 @@ def register_unwinder(locus, unwinder, replace=False):
|
|||||||
locus = gdb
|
locus = gdb
|
||||||
elif isinstance(locus, gdb.Objfile) or isinstance(locus, gdb.Progspace):
|
elif isinstance(locus, gdb.Objfile) or isinstance(locus, gdb.Progspace):
|
||||||
if gdb.parameter("verbose"):
|
if gdb.parameter("verbose"):
|
||||||
gdb.write("Registering %s unwinder for %s ...\n" %
|
gdb.write(
|
||||||
(unwinder.name, locus.filename))
|
"Registering %s unwinder for %s ...\n" % (unwinder.name, locus.filename)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise TypeError("locus should be gdb.Objfile or gdb.Progspace or None")
|
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:
|
if replace:
|
||||||
del locus.frame_unwinders[i]
|
del locus.frame_unwinders[i]
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Unwinder %s already exists." %
|
raise RuntimeError("Unwinder %s already exists." % unwinder.name)
|
||||||
unwinder.name)
|
|
||||||
i += 1
|
i += 1
|
||||||
locus.frame_unwinders.insert(0, unwinder)
|
locus.frame_unwinders.insert(0, unwinder)
|
||||||
gdb.invalidate_cached_frames()
|
gdb.invalidate_cached_frames()
|
||||||
|
|||||||
@@ -172,9 +172,9 @@ class SimpleXMethodMatcher(XMethodMatcher):
|
|||||||
def __call__(self, *args):
|
def __call__(self, *args):
|
||||||
return self._method_function(*args)
|
return self._method_function(*args)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
def __init__(self, name, class_matcher, method_matcher, method_function,
|
self, name, class_matcher, method_matcher, method_function, *arg_types
|
||||||
*arg_types):
|
):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
name: Name of the xmethod matcher.
|
name: Name of the xmethod matcher.
|
||||||
@@ -195,7 +195,8 @@ class SimpleXMethodMatcher(XMethodMatcher):
|
|||||||
XMethodMatcher.__init__(self, name)
|
XMethodMatcher.__init__(self, name)
|
||||||
assert callable(method_function), (
|
assert callable(method_function), (
|
||||||
"The 'method_function' argument to 'SimpleXMethodMatcher' "
|
"The 'method_function' argument to 'SimpleXMethodMatcher' "
|
||||||
"__init__ method should be a callable.")
|
"__init__ method should be a callable."
|
||||||
|
)
|
||||||
self._method_function = method_function
|
self._method_function = method_function
|
||||||
self._class_matcher = class_matcher
|
self._class_matcher = class_matcher
|
||||||
self._method_matcher = method_matcher
|
self._method_matcher = method_matcher
|
||||||
@@ -206,13 +207,15 @@ class SimpleXMethodMatcher(XMethodMatcher):
|
|||||||
mm = re.match(self._method_matcher, method_name)
|
mm = re.match(self._method_matcher, method_name)
|
||||||
if cm and mm:
|
if cm and mm:
|
||||||
return SimpleXMethodMatcher.SimpleXMethodWorker(
|
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
|
# A helper function for register_xmethod_matcher which returns an error
|
||||||
# object if MATCHER is not having the requisite attributes in the proper
|
# object if MATCHER is not having the requisite attributes in the proper
|
||||||
# format.
|
# format.
|
||||||
|
|
||||||
|
|
||||||
def _validate_xmethod_matcher(matcher):
|
def _validate_xmethod_matcher(matcher):
|
||||||
if not hasattr(matcher, "match"):
|
if not hasattr(matcher, "match"):
|
||||||
return TypeError("Xmethod matcher is missing method: match")
|
return TypeError("Xmethod matcher is missing method: match")
|
||||||
@@ -221,8 +224,7 @@ def _validate_xmethod_matcher(matcher):
|
|||||||
if not hasattr(matcher, "enabled"):
|
if not hasattr(matcher, "enabled"):
|
||||||
return TypeError("Xmethod matcher is missing attribute: enabled")
|
return TypeError("Xmethod matcher is missing attribute: enabled")
|
||||||
if not isinstance(matcher.name, basestring):
|
if not isinstance(matcher.name, basestring):
|
||||||
return TypeError("Attribute 'name' of xmethod matcher is not a "
|
return TypeError("Attribute 'name' of xmethod matcher is not a " "string")
|
||||||
"string")
|
|
||||||
if matcher.name.find(";") >= 0:
|
if matcher.name.find(";") >= 0:
|
||||||
return ValueError("Xmethod matcher name cannot contain ';' in it")
|
return ValueError("Xmethod matcher name cannot contain ';' in it")
|
||||||
|
|
||||||
@@ -232,6 +234,7 @@ def _validate_xmethod_matcher(matcher):
|
|||||||
# matcher in 'xmethods' sequence attribute of the LOCUS. If NAME is not
|
# matcher in 'xmethods' sequence attribute of the LOCUS. If NAME is not
|
||||||
# found in LOCUS, then -1 is returned.
|
# found in LOCUS, then -1 is returned.
|
||||||
|
|
||||||
|
|
||||||
def _lookup_xmethod_matcher(locus, name):
|
def _lookup_xmethod_matcher(locus, name):
|
||||||
for i in range(0, len(locus.xmethods)):
|
for i in range(0, len(locus.xmethods)):
|
||||||
if locus.xmethods[i].name == name:
|
if locus.xmethods[i].name == name:
|
||||||
@@ -268,8 +271,10 @@ def register_xmethod_matcher(locus, matcher, replace=False):
|
|||||||
if replace:
|
if replace:
|
||||||
del locus.xmethods[index]
|
del locus.xmethods[index]
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Xmethod matcher already registered with "
|
raise RuntimeError(
|
||||||
"%s: %s" % (locus_name, matcher.name))
|
"Xmethod matcher already registered with "
|
||||||
|
"%s: %s" % (locus_name, matcher.name)
|
||||||
|
)
|
||||||
if gdb.parameter("verbose"):
|
if gdb.parameter("verbose"):
|
||||||
gdb.write("Registering xmethod matcher '%s' with %s' ...\n")
|
gdb.write("Registering xmethod matcher '%s' with %s' ...\n")
|
||||||
locus.xmethods.insert(0, matcher)
|
locus.xmethods.insert(0, matcher)
|
||||||
|
|||||||
@@ -6,31 +6,34 @@ import os
|
|||||||
import getopt
|
import getopt
|
||||||
from distutils import sysconfig
|
from distutils import sysconfig
|
||||||
|
|
||||||
valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags',
|
valid_opts = ["prefix", "exec-prefix", "includes", "libs", "cflags", "ldflags", "help"]
|
||||||
'ldflags', 'help']
|
|
||||||
|
|
||||||
def exit_with_usage(code=1):
|
def exit_with_usage(code=1):
|
||||||
sys.stderr.write ("Usage: %s [%s]\n" % (sys.argv[0],
|
sys.stderr.write(
|
||||||
'|'.join('--'+opt for opt in valid_opts)))
|
"Usage: %s [%s]\n" % (sys.argv[0], "|".join("--" + opt for opt in valid_opts))
|
||||||
|
)
|
||||||
sys.exit(code)
|
sys.exit(code)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], '', valid_opts)
|
opts, args = getopt.getopt(sys.argv[1:], "", valid_opts)
|
||||||
except getopt.error:
|
except getopt.error:
|
||||||
exit_with_usage()
|
exit_with_usage()
|
||||||
|
|
||||||
if not opts:
|
if not opts:
|
||||||
exit_with_usage()
|
exit_with_usage()
|
||||||
|
|
||||||
pyver = sysconfig.get_config_var('VERSION')
|
pyver = sysconfig.get_config_var("VERSION")
|
||||||
getvar = sysconfig.get_config_var
|
getvar = sysconfig.get_config_var
|
||||||
abiflags = getattr (sys, "abiflags", "")
|
abiflags = getattr(sys, "abiflags", "")
|
||||||
|
|
||||||
opt_flags = [flag for (flag, val) in opts]
|
opt_flags = [flag for (flag, val) in opts]
|
||||||
|
|
||||||
if '--help' in opt_flags:
|
if "--help" in opt_flags:
|
||||||
exit_with_usage(code=0)
|
exit_with_usage(code=0)
|
||||||
|
|
||||||
|
|
||||||
def to_unix_path(path):
|
def to_unix_path(path):
|
||||||
"""On Windows, returns the given path with all backslashes
|
"""On Windows, returns the given path with all backslashes
|
||||||
converted into forward slashes. This is to help prevent problems
|
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.
|
On Unix systems, returns the path unchanged.
|
||||||
"""
|
"""
|
||||||
if os.name == 'nt':
|
if os.name == "nt":
|
||||||
path = path.replace('\\', '/')
|
path = path.replace("\\", "/")
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
for opt in opt_flags:
|
for opt in opt_flags:
|
||||||
if opt == '--prefix':
|
if opt == "--prefix":
|
||||||
print (to_unix_path(sysconfig.PREFIX))
|
print(to_unix_path(sysconfig.PREFIX))
|
||||||
|
|
||||||
elif opt == '--exec-prefix':
|
elif opt == "--exec-prefix":
|
||||||
print (to_unix_path(sysconfig.EXEC_PREFIX))
|
print(to_unix_path(sysconfig.EXEC_PREFIX))
|
||||||
|
|
||||||
elif opt in ('--includes', '--cflags'):
|
elif opt in ("--includes", "--cflags"):
|
||||||
flags = ['-I' + sysconfig.get_python_inc(),
|
flags = [
|
||||||
'-I' + sysconfig.get_python_inc(plat_specific=True)]
|
"-I" + sysconfig.get_python_inc(),
|
||||||
if opt == '--cflags':
|
"-I" + sysconfig.get_python_inc(plat_specific=True),
|
||||||
flags.extend(getvar('CFLAGS').split())
|
]
|
||||||
print (to_unix_path(' '.join(flags)))
|
if opt == "--cflags":
|
||||||
|
flags.extend(getvar("CFLAGS").split())
|
||||||
|
print(to_unix_path(" ".join(flags)))
|
||||||
|
|
||||||
elif opt in ('--libs', '--ldflags'):
|
elif opt in ("--libs", "--ldflags"):
|
||||||
libs = ['-lpython' + pyver + abiflags]
|
libs = ["-lpython" + pyver + abiflags]
|
||||||
if getvar('LIBS') is not None:
|
if getvar("LIBS") is not None:
|
||||||
libs.extend(getvar('LIBS').split())
|
libs.extend(getvar("LIBS").split())
|
||||||
if getvar('SYSLIBS') is not None:
|
if getvar("SYSLIBS") is not None:
|
||||||
libs.extend(getvar('SYSLIBS').split())
|
libs.extend(getvar("SYSLIBS").split())
|
||||||
# add the prefix/lib/pythonX.Y/config dir, but only if there is no
|
# add the prefix/lib/pythonX.Y/config dir, but only if there is no
|
||||||
# shared library in prefix/lib/.
|
# shared library in prefix/lib/.
|
||||||
if opt == '--ldflags':
|
if opt == "--ldflags":
|
||||||
if not getvar('Py_ENABLE_SHARED'):
|
if not getvar("Py_ENABLE_SHARED"):
|
||||||
if getvar('LIBPL') is not None:
|
if getvar("LIBPL") is not None:
|
||||||
libs.insert(0, '-L' + getvar('LIBPL'))
|
libs.insert(0, "-L" + getvar("LIBPL"))
|
||||||
elif os.name == 'nt':
|
elif os.name == "nt":
|
||||||
libs.insert(0, '-L' + sysconfig.PREFIX + '/libs')
|
libs.insert(0, "-L" + sysconfig.PREFIX + "/libs")
|
||||||
if getvar('LINKFORSHARED') is not None:
|
if getvar("LINKFORSHARED") is not None:
|
||||||
libs.extend(getvar('LINKFORSHARED').split())
|
libs.extend(getvar("LINKFORSHARED").split())
|
||||||
print (to_unix_path(' '.join(libs)))
|
print(to_unix_path(" ".join(libs)))
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ import time
|
|||||||
infname = sys.argv[1]
|
infname = sys.argv[1]
|
||||||
inf = file(infname)
|
inf = file(infname)
|
||||||
|
|
||||||
print("""\
|
print(
|
||||||
|
"""\
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!-- Copyright (C) 2009-%s Free Software Foundation, Inc.
|
<!-- Copyright (C) 2009-%s Free Software Foundation, Inc.
|
||||||
|
|
||||||
@@ -30,31 +31,33 @@ print("""\
|
|||||||
The file mentioned above belongs to the Linux Kernel.
|
The file mentioned above belongs to the Linux Kernel.
|
||||||
Some small hand-edits were made. -->
|
Some small hand-edits were made. -->
|
||||||
|
|
||||||
<syscalls_info>""" % (time.strftime("%Y"), infname))
|
<syscalls_info>"""
|
||||||
|
% (time.strftime("%Y"), infname)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def record(name, number, comment=None):
|
def record(name, number, comment=None):
|
||||||
#nm = 'name="%s"' % name
|
# nm = 'name="%s"' % name
|
||||||
#s = ' <syscall %-30s number="%d"/>' % (nm, number)
|
# s = ' <syscall %-30s number="%d"/>' % (nm, number)
|
||||||
s = ' <syscall name="%s" number="%d"/>' % (name, number)
|
s = ' <syscall name="%s" number="%d"/>' % (name, number)
|
||||||
if comment:
|
if comment:
|
||||||
s += ' <!-- %s -->' % comment
|
s += " <!-- %s -->" % comment
|
||||||
print(s)
|
print(s)
|
||||||
|
|
||||||
|
|
||||||
for line in inf:
|
for line in inf:
|
||||||
m = re.match(r'^#define __NR_(\w+)\s+\(__NR_SYSCALL_BASE\+\s*(\d+)\)',
|
m = re.match(r"^#define __NR_(\w+)\s+\(__NR_SYSCALL_BASE\+\s*(\d+)\)", line)
|
||||||
line)
|
|
||||||
if m:
|
if m:
|
||||||
record(m.group(1), int(m.group(2)))
|
record(m.group(1), int(m.group(2)))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
m = re.match(r'^\s+/\* (\d+) was sys_(\w+) \*/$', line)
|
m = re.match(r"^\s+/\* (\d+) was sys_(\w+) \*/$", line)
|
||||||
if m:
|
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+)\)',
|
m = re.match(r"^#define __ARM_NR_(\w+)\s+\(__ARM_NR_BASE\+\s*(\d+)\)", line)
|
||||||
line)
|
|
||||||
if m:
|
if m:
|
||||||
record('ARM_'+m.group(1), 0x0f0000+int(m.group(2)))
|
record("ARM_" + m.group(1), 0x0F0000 + int(m.group(2)))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
print('</syscalls_info>')
|
print("</syscalls_info>")
|
||||||
|
|||||||
@@ -79,9 +79,8 @@ def elinos_init():
|
|||||||
if elinos_env["project"] is None:
|
if elinos_env["project"] is None:
|
||||||
warn("Xenomai libraries may not be loaded")
|
warn("Xenomai libraries may not be loaded")
|
||||||
else:
|
else:
|
||||||
for dir in elinos_env['xenomai']:
|
for dir in elinos_env["xenomai"]:
|
||||||
solib_dirs += ["%s/%s"
|
solib_dirs += ["%s/%s" % (dir, "xenomai-build/usr/realtime/lib")]
|
||||||
% (dir, "xenomai-build/usr/realtime/lib")]
|
|
||||||
|
|
||||||
if len(solib_dirs) != 0:
|
if len(solib_dirs) != 0:
|
||||||
gdb.execute("set solib-search-path %s" % ":".join(solib_dirs))
|
gdb.execute("set solib-search-path %s" % ":".join(solib_dirs))
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
if 'ENV_PREFIX' in os.environ:
|
if "ENV_PREFIX" in os.environ:
|
||||||
gdb.execute('set sysroot %s' % os.environ['ENV_PREFIX'])
|
gdb.execute("set sysroot %s" % os.environ["ENV_PREFIX"])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print "warning: ENV_PREFIX environment variable missing."
|
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
|
# The relatioships between various states of the same tests that
|
||||||
# should be ignored. For example, if the same test PASSes on a
|
# should be ignored. For example, if the same test PASSes on a
|
||||||
# testcase run but KFAILs on another, this test should be considered
|
# testcase run but KFAILs on another, this test should be considered
|
||||||
# racy because a known-failure is... known.
|
# 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
|
# We are interested in lines that start with '.?(PASS|FAIL)'. In
|
||||||
# other words, we don't process errors (maybe we should).
|
# 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
|
"""Parse a single LINE from a sumfile, and store the results in the
|
||||||
dictionary referenced by DIC."""
|
dictionary referenced by DIC."""
|
||||||
global sum_matcher
|
global sum_matcher
|
||||||
|
|
||||||
line = line.rstrip ()
|
line = line.rstrip()
|
||||||
m = re.match (sum_matcher, line)
|
m = re.match(sum_matcher, line)
|
||||||
if m:
|
if m:
|
||||||
result = m.group (1)
|
result = m.group(1)
|
||||||
test_name = m.group (3)
|
test_name = m.group(3)
|
||||||
# Remove tail parentheses. These are likely to be '(timeout)'
|
# Remove tail parentheses. These are likely to be '(timeout)'
|
||||||
# and other extra information that will only confuse us.
|
# and other extra information that will only confuse us.
|
||||||
test_name = re.sub ('(\s+)?\(.*$', '', test_name)
|
test_name = re.sub("(\s+)?\(.*$", "", test_name)
|
||||||
if result not in dic.keys ():
|
if result not in dic.keys():
|
||||||
dic[result] = set ()
|
dic[result] = set()
|
||||||
if test_name in dic[result]:
|
if test_name in dic[result]:
|
||||||
# If the line is already present in the dictionary, then
|
# If the line is already present in the dictionary, then
|
||||||
# we include a unique identifier in the end of it, in the
|
# 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.
|
# in order to identify the racy test.
|
||||||
i = 2
|
i = 2
|
||||||
while True:
|
while True:
|
||||||
nname = test_name + ' <<' + str (i) + '>>'
|
nname = test_name + " <<" + str(i) + ">>"
|
||||||
if nname not in dic[result]:
|
if nname not in dic[result]:
|
||||||
break
|
break
|
||||||
i += 1
|
i += 1
|
||||||
test_name = nname
|
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
|
"""Read the sumfiles (passed as a list in the FILES variable), and
|
||||||
process each one, filling the FILES_AND_TESTS global dictionary with
|
process each one, filling the FILES_AND_TESTS global dictionary with
|
||||||
information about them. """
|
information about them."""
|
||||||
global files_and_tests
|
global files_and_tests
|
||||||
|
|
||||||
for x in files:
|
for x in files:
|
||||||
with open (x, 'r') as f:
|
with open(x, "r") as f:
|
||||||
files_and_tests[x] = dict ()
|
files_and_tests[x] = dict()
|
||||||
for line in f.readlines ():
|
for line in f.readlines():
|
||||||
parse_sum_line (line, files_and_tests[x])
|
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
|
"""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
|
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
|
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
|
tests), and compare them. If a test is present in all PASS sets, then
|
||||||
it is not racy. Otherwise, it is.
|
it is not racy. Otherwise, it is.
|
||||||
|
|
||||||
This function does that for all sets (PASS, FAIL, KPASS, KFAIL, etc.),
|
This function does that for all sets (PASS, FAIL, KPASS, KFAIL, etc.),
|
||||||
and then print a sorted list (without duplicates) of all the tests
|
and then print a sorted list (without duplicates) of all the tests
|
||||||
that were found to be racy."""
|
that were found to be racy."""
|
||||||
global files_and_tests
|
global files_and_tests
|
||||||
|
|
||||||
# First, construct two dictionaries that will hold one set of
|
# 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
|
# Each set in ALL_TESTS will contain all tests, racy or not, for
|
||||||
# that state.
|
# that state.
|
||||||
nonracy_tests = dict ()
|
nonracy_tests = dict()
|
||||||
all_tests = dict ()
|
all_tests = dict()
|
||||||
for f in files_and_tests:
|
for f in files_and_tests:
|
||||||
for state in files_and_tests[f]:
|
for state in files_and_tests[f]:
|
||||||
try:
|
try:
|
||||||
nonracy_tests[state] &= files_and_tests[f][state].copy ()
|
nonracy_tests[state] &= files_and_tests[f][state].copy()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
nonracy_tests[state] = files_and_tests[f][state].copy ()
|
nonracy_tests[state] = files_and_tests[f][state].copy()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
all_tests[state] |= files_and_tests[f][state].copy ()
|
all_tests[state] |= files_and_tests[f][state].copy()
|
||||||
except KeyError:
|
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
|
# Now, we eliminate the tests that are present in states that need
|
||||||
# to be ignored. For example, tests both in the PASS and KFAIL
|
# to be ignored. For example, tests both in the PASS and KFAIL
|
||||||
# states should not be considered racy.
|
# states should not be considered racy.
|
||||||
ignored_tests = set ()
|
ignored_tests = set()
|
||||||
for s1, s2 in ignore_relations.iteritems ():
|
for s1, s2 in ignore_relations.iteritems():
|
||||||
try:
|
try:
|
||||||
ignored_tests |= (all_tests[s1] & all_tests[s2])
|
ignored_tests |= all_tests[s1] & all_tests[s2]
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
racy_tests = set ()
|
racy_tests = set()
|
||||||
for f in files_and_tests:
|
for f in files_and_tests:
|
||||||
for state in files_and_tests[f]:
|
for state in files_and_tests[f]:
|
||||||
racy_tests |= files_and_tests[f][state] - nonracy_tests[state]
|
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 "\t\t=== gdb racy tests ===\n"
|
||||||
|
|
||||||
# Print each test.
|
# Print each test.
|
||||||
for line in sorted (racy_tests):
|
for line in sorted(racy_tests):
|
||||||
print line
|
print line
|
||||||
|
|
||||||
# Print the summary.
|
# Print the summary.
|
||||||
print "\n"
|
print "\n"
|
||||||
print "\t\t=== gdb Summary ===\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
|
# It only makes sense to invoke this program if you pass two
|
||||||
# or more files to be analyzed.
|
# or more files to be analyzed.
|
||||||
sys.exit ("Usage: %s [FILE] [FILE] ..." % sys.argv[0])
|
sys.exit("Usage: %s [FILE] [FILE] ..." % sys.argv[0])
|
||||||
read_sum_files (sys.argv[1:])
|
read_sum_files(sys.argv[1:])
|
||||||
identify_racy_tests ()
|
identify_racy_tests()
|
||||||
exit (0)
|
exit(0)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class TimeTPrinter:
|
|||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
secs = int(self.val['secs'])
|
secs = int(self.val["secs"])
|
||||||
return "%s (%d)" % (asctime(gmtime(secs)), secs)
|
return "%s (%d)" % (asctime(gmtime(secs)), secs)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,21 +15,22 @@
|
|||||||
|
|
||||||
from perftest import perftest
|
from perftest import perftest
|
||||||
|
|
||||||
class BackTrace (perftest.TestCaseWithBasicMeasurements):
|
|
||||||
|
class BackTrace(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self, depth):
|
def __init__(self, depth):
|
||||||
super (BackTrace, self).__init__ ("backtrace")
|
super(BackTrace, self).__init__("backtrace")
|
||||||
self.depth = depth
|
self.depth = depth
|
||||||
|
|
||||||
def warm_up(self):
|
def warm_up(self):
|
||||||
# Warm up.
|
# 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):
|
def _do_test(self):
|
||||||
"""Do backtrace multiple times."""
|
"""Do backtrace multiple times."""
|
||||||
do_test_command = "bt %d" % self.depth
|
do_test_command = "bt %d" % self.depth
|
||||||
for _ in range(1, 15):
|
for _ in range(1, 15):
|
||||||
gdb.execute (do_test_command, False, True)
|
gdb.execute(do_test_command, False, True)
|
||||||
|
|
||||||
def execute_test(self):
|
def execute_test(self):
|
||||||
|
|
||||||
@@ -40,8 +41,8 @@ class BackTrace (perftest.TestCaseWithBasicMeasurements):
|
|||||||
line_size_command = "set dcache line-size %d" % (line_size)
|
line_size_command = "set dcache line-size %d" % (line_size)
|
||||||
size_command = "set dcache size %d" % (4096 * 64 / line_size)
|
size_command = "set dcache size %d" % (4096 * 64 / line_size)
|
||||||
# Cache is cleared by changing line-size or size.
|
# Cache is cleared by changing line-size or size.
|
||||||
gdb.execute (line_size_command)
|
gdb.execute(line_size_command)
|
||||||
gdb.execute (size_command)
|
gdb.execute(size_command)
|
||||||
|
|
||||||
func = lambda: self._do_test()
|
func = lambda: self._do_test()
|
||||||
|
|
||||||
|
|||||||
@@ -15,24 +15,28 @@
|
|||||||
|
|
||||||
from perftest import perftest
|
from perftest import perftest
|
||||||
|
|
||||||
|
|
||||||
class Disassemble(perftest.TestCaseWithBasicMeasurements):
|
class Disassemble(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super (Disassemble, self).__init__ ("disassemble")
|
super(Disassemble, self).__init__("disassemble")
|
||||||
|
|
||||||
def warm_up(self):
|
def warm_up(self):
|
||||||
do_test_command = "disassemble ada_evaluate_subexp"
|
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):
|
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
|
do_test_command = "disassemble %s" % func
|
||||||
for _ in range(c+1):
|
for _ in range(c + 1):
|
||||||
gdb.execute (do_test_command, False, True)
|
gdb.execute(do_test_command, False, True)
|
||||||
|
|
||||||
def execute_test(self):
|
def execute_test(self):
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
# Flush code cache.
|
# Flush code cache.
|
||||||
gdb.execute("set code-cache off");
|
gdb.execute("set code-cache off")
|
||||||
gdb.execute("set code-cache on");
|
gdb.execute("set code-cache on")
|
||||||
self.measure.measure(lambda: self._do_test(i), i)
|
self.measure.measure(lambda: self._do_test(i), i)
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ from perftest import perftest
|
|||||||
from perftest import measure
|
from perftest import measure
|
||||||
from perftest import utils
|
from perftest import utils
|
||||||
|
|
||||||
|
|
||||||
class NullLookup(perftest.TestCaseWithBasicMeasurements):
|
class NullLookup(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self, name, run_names, binfile):
|
def __init__(self, name, run_names, binfile):
|
||||||
# We want to measure time in this test.
|
# We want to measure time in this test.
|
||||||
@@ -33,8 +34,7 @@ class NullLookup(perftest.TestCaseWithBasicMeasurements):
|
|||||||
|
|
||||||
def execute_test(self):
|
def execute_test(self):
|
||||||
for run in self.run_names:
|
for run in self.run_names:
|
||||||
this_run_binfile = "%s-%s" % (self.binfile,
|
this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||||
utils.convert_spaces(run))
|
|
||||||
utils.select_file(this_run_binfile)
|
utils.select_file(this_run_binfile)
|
||||||
utils.runto_main()
|
utils.runto_main()
|
||||||
utils.safe_execute("mt expand-symtabs")
|
utils.safe_execute("mt expand-symtabs")
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ from perftest import perftest
|
|||||||
from perftest import measure
|
from perftest import measure
|
||||||
from perftest import utils
|
from perftest import utils
|
||||||
|
|
||||||
|
|
||||||
class PervasiveTypedef(perftest.TestCaseWithBasicMeasurements):
|
class PervasiveTypedef(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self, name, run_names, binfile):
|
def __init__(self, name, run_names, binfile):
|
||||||
# We want to measure time in this test.
|
# We want to measure time in this test.
|
||||||
@@ -37,8 +38,7 @@ class PervasiveTypedef(perftest.TestCaseWithBasicMeasurements):
|
|||||||
|
|
||||||
def execute_test(self):
|
def execute_test(self):
|
||||||
for run in self.run_names:
|
for run in self.run_names:
|
||||||
self.this_run_binfile = "%s-%s" % (self.binfile,
|
self.this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||||
utils.convert_spaces(run))
|
|
||||||
iteration = 5
|
iteration = 5
|
||||||
while iteration > 0:
|
while iteration > 0:
|
||||||
self.measure.measure(self.func, run)
|
self.measure.measure(self.func, run)
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ from perftest import perftest
|
|||||||
from perftest import measure
|
from perftest import measure
|
||||||
from perftest import utils
|
from perftest import utils
|
||||||
|
|
||||||
|
|
||||||
class PrintCerr(perftest.TestCaseWithBasicMeasurements):
|
class PrintCerr(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self, name, run_names, binfile):
|
def __init__(self, name, run_names, binfile):
|
||||||
super(PrintCerr, self).__init__(name)
|
super(PrintCerr, self).__init__(name)
|
||||||
@@ -40,8 +41,7 @@ class PrintCerr(perftest.TestCaseWithBasicMeasurements):
|
|||||||
|
|
||||||
def execute_test(self):
|
def execute_test(self):
|
||||||
for run in self.run_names:
|
for run in self.run_names:
|
||||||
this_run_binfile = "%s-%s" % (self.binfile,
|
this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||||
utils.convert_spaces(run))
|
|
||||||
utils.select_file(this_run_binfile)
|
utils.select_file(this_run_binfile)
|
||||||
utils.runto_main()
|
utils.runto_main()
|
||||||
iteration = 5
|
iteration = 5
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ from perftest import perftest
|
|||||||
from perftest import measure
|
from perftest import measure
|
||||||
from perftest import utils
|
from perftest import utils
|
||||||
|
|
||||||
|
|
||||||
class GmonsterPtypeString(perftest.TestCaseWithBasicMeasurements):
|
class GmonsterPtypeString(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self, name, run_names, binfile):
|
def __init__(self, name, run_names, binfile):
|
||||||
super(GmonsterPtypeString, self).__init__(name)
|
super(GmonsterPtypeString, self).__init__(name)
|
||||||
@@ -34,8 +35,7 @@ class GmonsterPtypeString(perftest.TestCaseWithBasicMeasurements):
|
|||||||
|
|
||||||
def execute_test(self):
|
def execute_test(self):
|
||||||
for run in self.run_names:
|
for run in self.run_names:
|
||||||
this_run_binfile = "%s-%s" % (self.binfile,
|
this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||||
utils.convert_spaces(run))
|
|
||||||
utils.select_file(this_run_binfile)
|
utils.select_file(this_run_binfile)
|
||||||
utils.runto_main()
|
utils.runto_main()
|
||||||
utils.safe_execute("mt expand-symtabs")
|
utils.safe_execute("mt expand-symtabs")
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ from perftest import perftest
|
|||||||
from perftest import measure
|
from perftest import measure
|
||||||
from perftest import utils
|
from perftest import utils
|
||||||
|
|
||||||
|
|
||||||
class GmonsterRuntoMain(perftest.TestCaseWithBasicMeasurements):
|
class GmonsterRuntoMain(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self, name, run_names, binfile):
|
def __init__(self, name, run_names, binfile):
|
||||||
super(GmonsterRuntoMain, self).__init__(name)
|
super(GmonsterRuntoMain, self).__init__(name)
|
||||||
@@ -30,8 +31,7 @@ class GmonsterRuntoMain(perftest.TestCaseWithBasicMeasurements):
|
|||||||
|
|
||||||
def execute_test(self):
|
def execute_test(self):
|
||||||
for run in self.run_names:
|
for run in self.run_names:
|
||||||
this_run_binfile = "%s-%s" % (self.binfile,
|
this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||||
utils.convert_spaces(run))
|
|
||||||
utils.select_file(this_run_binfile)
|
utils.select_file(this_run_binfile)
|
||||||
iteration = 5
|
iteration = 5
|
||||||
while iteration > 0:
|
while iteration > 0:
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ from perftest import perftest
|
|||||||
from perftest import measure
|
from perftest import measure
|
||||||
from perftest import utils
|
from perftest import utils
|
||||||
|
|
||||||
|
|
||||||
class GmonsterSelectFile(perftest.TestCaseWithBasicMeasurements):
|
class GmonsterSelectFile(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self, name, run_names, binfile):
|
def __init__(self, name, run_names, binfile):
|
||||||
super(GmonsterSelectFile, self).__init__(name)
|
super(GmonsterSelectFile, self).__init__(name)
|
||||||
@@ -34,8 +35,7 @@ class GmonsterSelectFile(perftest.TestCaseWithBasicMeasurements):
|
|||||||
|
|
||||||
def execute_test(self):
|
def execute_test(self):
|
||||||
for run in self.run_names:
|
for run in self.run_names:
|
||||||
this_run_binfile = "%s-%s" % (self.binfile,
|
this_run_binfile = "%s-%s" % (self.binfile, utils.convert_spaces(run))
|
||||||
utils.convert_spaces(run))
|
|
||||||
iteration = 5
|
iteration = 5
|
||||||
while iteration > 0:
|
while iteration > 0:
|
||||||
func = lambda: self._doit(this_run_binfile)
|
func = lambda: self._doit(this_run_binfile)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import time
|
|||||||
import os
|
import os
|
||||||
import gc
|
import gc
|
||||||
|
|
||||||
|
|
||||||
class Measure(object):
|
class Measure(object):
|
||||||
"""A class that measure and collect the interesting data for a given testcase.
|
"""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:
|
for m in self.measurements:
|
||||||
m.report(reporter, name)
|
m.report(reporter, name)
|
||||||
|
|
||||||
|
|
||||||
class Measurement(object):
|
class Measurement(object):
|
||||||
"""A measurement for a certain aspect."""
|
"""A measurement for a certain aspect."""
|
||||||
|
|
||||||
@@ -63,7 +65,7 @@ class Measurement(object):
|
|||||||
|
|
||||||
Attribute result is the TestResult associated with measurement.
|
Attribute result is the TestResult associated with measurement.
|
||||||
"""
|
"""
|
||||||
self.name = name;
|
self.name = name
|
||||||
self.result = result
|
self.result = result
|
||||||
|
|
||||||
def start(self, id):
|
def start(self, id):
|
||||||
@@ -82,8 +84,10 @@ class Measurement(object):
|
|||||||
"""Report the measured data by argument reporter."""
|
"""Report the measured data by argument reporter."""
|
||||||
self.result.report(reporter, name + " " + self.name)
|
self.result.report(reporter, name + " " + self.name)
|
||||||
|
|
||||||
|
|
||||||
class MeasurementCpuTime(Measurement):
|
class MeasurementCpuTime(Measurement):
|
||||||
"""Measurement on CPU time."""
|
"""Measurement on CPU time."""
|
||||||
|
|
||||||
# On UNIX, time.clock() measures the amount of CPU time that has
|
# On UNIX, time.clock() measures the amount of CPU time that has
|
||||||
# been used by the current process. On Windows it will measure
|
# been used by the current process. On Windows it will measure
|
||||||
# wall-clock seconds elapsed since the first call to the function.
|
# wall-clock seconds elapsed since the first call to the function.
|
||||||
@@ -98,11 +102,12 @@ class MeasurementCpuTime(Measurement):
|
|||||||
self.start_time = time.clock()
|
self.start_time = time.clock()
|
||||||
|
|
||||||
def stop(self, id):
|
def stop(self, id):
|
||||||
if os.name == 'nt':
|
if os.name == "nt":
|
||||||
cpu_time = 0
|
cpu_time = 0
|
||||||
else:
|
else:
|
||||||
cpu_time = time.clock() - self.start_time
|
cpu_time = time.clock() - self.start_time
|
||||||
self.result.record (id, cpu_time)
|
self.result.record(id, cpu_time)
|
||||||
|
|
||||||
|
|
||||||
class MeasurementWallTime(Measurement):
|
class MeasurementWallTime(Measurement):
|
||||||
"""Measurement on Wall time."""
|
"""Measurement on Wall time."""
|
||||||
@@ -116,7 +121,8 @@ class MeasurementWallTime(Measurement):
|
|||||||
|
|
||||||
def stop(self, id):
|
def stop(self, id):
|
||||||
wall_time = time.time() - self.start_time
|
wall_time = time.time() - self.start_time
|
||||||
self.result.record (id, wall_time)
|
self.result.record(id, wall_time)
|
||||||
|
|
||||||
|
|
||||||
class MeasurementVmSize(Measurement):
|
class MeasurementVmSize(Measurement):
|
||||||
"""Measurement on memory usage represented by VmSize."""
|
"""Measurement on memory usage represented by VmSize."""
|
||||||
@@ -143,4 +149,4 @@ class MeasurementVmSize(Measurement):
|
|||||||
|
|
||||||
def stop(self, id):
|
def stop(self, id):
|
||||||
memory_used = self._compute_process_memory_usage("VmSize:")
|
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.execute_test()
|
||||||
self.measure.report(reporter.TextReporter(append), self.name)
|
self.measure.report(reporter.TextReporter(append), self.name)
|
||||||
|
|
||||||
|
|
||||||
class TestCaseWithBasicMeasurements(TestCase):
|
class TestCaseWithBasicMeasurements(TestCase):
|
||||||
"""Test case measuring CPU time, wall time and memory usage."""
|
"""Test case measuring CPU time, wall time and memory usage."""
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
result_factory = testresult.SingleStatisticResultFactory()
|
result_factory = testresult.SingleStatisticResultFactory()
|
||||||
measurements = [MeasurementCpuTime(result_factory.create_result()),
|
measurements = [
|
||||||
|
MeasurementCpuTime(result_factory.create_result()),
|
||||||
MeasurementWallTime(result_factory.create_result()),
|
MeasurementWallTime(result_factory.create_result()),
|
||||||
MeasurementVmSize(result_factory.create_result())]
|
MeasurementVmSize(result_factory.create_result()),
|
||||||
super (TestCaseWithBasicMeasurements, self).__init__ (name, Measure(measurements))
|
]
|
||||||
|
super(TestCaseWithBasicMeasurements, self).__init__(name, Measure(measurements))
|
||||||
|
|||||||
@@ -57,29 +57,30 @@ class TextReporter(Reporter):
|
|||||||
"""Report results in a plain text file 'perftest.log'."""
|
"""Report results in a plain text file 'perftest.log'."""
|
||||||
|
|
||||||
def __init__(self, append):
|
def __init__(self, append):
|
||||||
super (TextReporter, self).__init__(Reporter(append))
|
super(TextReporter, self).__init__(Reporter(append))
|
||||||
self.txt_sum = None
|
self.txt_sum = None
|
||||||
self.txt_log = None
|
self.txt_log = None
|
||||||
|
|
||||||
def report(self, test_name, measurement_name, data_points):
|
def report(self, test_name, measurement_name, data_points):
|
||||||
if len(data_points) == 0:
|
if len(data_points) == 0:
|
||||||
self.txt_sum.write("%s %s *no data recorded*\n" % (
|
self.txt_sum.write(
|
||||||
test_name, measurement_name))
|
"%s %s *no data recorded*\n" % (test_name, measurement_name)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
average = sum(data_points) / len(data_points)
|
average = sum(data_points) / len(data_points)
|
||||||
data_min = min(data_points)
|
data_min = min(data_points)
|
||||||
data_max = max(data_points)
|
data_max = max(data_points)
|
||||||
self.txt_sum.write("%s %s %s\n" % (
|
self.txt_sum.write("%s %s %s\n" % (test_name, measurement_name, average))
|
||||||
test_name, measurement_name, average))
|
self.txt_log.write(
|
||||||
self.txt_log.write("%s %s %s, min %s, max %s, data %s\n" % (
|
"%s %s %s, min %s, max %s, data %s\n"
|
||||||
test_name, measurement_name, average, data_min, data_max,
|
% (test_name, measurement_name, average, data_min, data_max, data_points)
|
||||||
data_points))
|
)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
mode = "a+" if self.append else "w"
|
mode = "a+" if self.append else "w"
|
||||||
self.txt_sum = open (SUM_FILE_NAME, mode);
|
self.txt_sum = open(SUM_FILE_NAME, mode)
|
||||||
self.txt_log = open (LOG_FILE_NAME, mode);
|
self.txt_log = open(LOG_FILE_NAME, mode)
|
||||||
|
|
||||||
def end(self):
|
def end(self):
|
||||||
self.txt_sum.close ()
|
self.txt_sum.close()
|
||||||
self.txt_log.close ()
|
self.txt_log.close()
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
class TestResult(object):
|
class TestResult(object):
|
||||||
"""Base class to record and report test results.
|
"""Base class to record and report test results.
|
||||||
|
|
||||||
@@ -27,12 +28,13 @@ class TestResult(object):
|
|||||||
"""Report the test results by reporter."""
|
"""Report the test results by reporter."""
|
||||||
raise NotImplementedError("Abstract Method:report.")
|
raise NotImplementedError("Abstract Method:report.")
|
||||||
|
|
||||||
|
|
||||||
class SingleStatisticTestResult(TestResult):
|
class SingleStatisticTestResult(TestResult):
|
||||||
"""Test results for the test case with a single statistic."""
|
"""Test results for the test case with a single statistic."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super (SingleStatisticTestResult, self).__init__ ()
|
super(SingleStatisticTestResult, self).__init__()
|
||||||
self.results = dict ()
|
self.results = dict()
|
||||||
|
|
||||||
def record(self, parameter, result):
|
def record(self, parameter, result):
|
||||||
if parameter in self.results:
|
if parameter in self.results:
|
||||||
@@ -46,6 +48,7 @@ class SingleStatisticTestResult(TestResult):
|
|||||||
reporter.report(name, key, self.results[key])
|
reporter.report(name, key, self.results[key])
|
||||||
reporter.end()
|
reporter.end()
|
||||||
|
|
||||||
|
|
||||||
class ResultFactory(object):
|
class ResultFactory(object):
|
||||||
"""A factory to create an instance of TestResult."""
|
"""A factory to create an instance of TestResult."""
|
||||||
|
|
||||||
@@ -53,6 +56,7 @@ class ResultFactory(object):
|
|||||||
"""Create an instance of TestResult."""
|
"""Create an instance of TestResult."""
|
||||||
raise NotImplementedError("Abstract Method:create_result.")
|
raise NotImplementedError("Abstract Method:create_result.")
|
||||||
|
|
||||||
|
|
||||||
class SingleStatisticResultFactory(ResultFactory):
|
class SingleStatisticResultFactory(ResultFactory):
|
||||||
"""A factory to create an instance of SingleStatisticTestResult."""
|
"""A factory to create an instance of SingleStatisticTestResult."""
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
|
|
||||||
def safe_execute(command):
|
def safe_execute(command):
|
||||||
"""Execute command, ignoring any gdb errors."""
|
"""Execute command, ignoring any gdb errors."""
|
||||||
result = None
|
result = None
|
||||||
@@ -37,7 +38,7 @@ def select_file(file_name):
|
|||||||
"""
|
"""
|
||||||
safe_execute("set confirm off")
|
safe_execute("set confirm off")
|
||||||
safe_execute("kill")
|
safe_execute("kill")
|
||||||
print ("Selecting file %s" % (file_name))
|
print("Selecting file %s" % (file_name))
|
||||||
if file_name is None:
|
if file_name is None:
|
||||||
gdb.execute("file")
|
gdb.execute("file")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -15,9 +15,10 @@
|
|||||||
|
|
||||||
from perftest import perftest
|
from perftest import perftest
|
||||||
|
|
||||||
class SingleStep (perftest.TestCaseWithBasicMeasurements):
|
|
||||||
|
class SingleStep(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self, step):
|
def __init__(self, step):
|
||||||
super (SingleStep, self).__init__ ("single-step")
|
super(SingleStep, self).__init__("single-step")
|
||||||
self.step = step
|
self.step = step
|
||||||
|
|
||||||
def warm_up(self):
|
def warm_up(self):
|
||||||
|
|||||||
@@ -15,9 +15,10 @@
|
|||||||
|
|
||||||
from perftest import perftest
|
from perftest import perftest
|
||||||
|
|
||||||
class SkipCommand (perftest.TestCaseWithBasicMeasurements):
|
|
||||||
|
class SkipCommand(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self, name, step):
|
def __init__(self, name, step):
|
||||||
super (SkipCommand, self).__init__ (name)
|
super(SkipCommand, self).__init__(name)
|
||||||
self.step = step
|
self.step = step
|
||||||
|
|
||||||
def warm_up(self):
|
def warm_up(self):
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
from perftest import perftest
|
from perftest import perftest
|
||||||
|
|
||||||
|
|
||||||
class SkipPrologue(perftest.TestCaseWithBasicMeasurements):
|
class SkipPrologue(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self, count):
|
def __init__(self, count):
|
||||||
super(SkipPrologue, self).__init__("skip-prologue")
|
super(SkipPrologue, self).__init__("skip-prologue")
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
from perftest import perftest
|
from perftest import perftest
|
||||||
from perftest import measure
|
from perftest import measure
|
||||||
|
|
||||||
|
|
||||||
class SolibLoadUnload1(perftest.TestCaseWithBasicMeasurements):
|
class SolibLoadUnload1(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self, solib_count, measure_load):
|
def __init__(self, solib_count, measure_load):
|
||||||
if measure_load:
|
if measure_load:
|
||||||
@@ -26,7 +27,7 @@ class SolibLoadUnload1(perftest.TestCaseWithBasicMeasurements):
|
|||||||
else:
|
else:
|
||||||
name = "solib_unload"
|
name = "solib_unload"
|
||||||
# We want to measure time in this test.
|
# We want to measure time in this test.
|
||||||
super (SolibLoadUnload1, self).__init__ (name)
|
super(SolibLoadUnload1, self).__init__(name)
|
||||||
self.solib_count = solib_count
|
self.solib_count = solib_count
|
||||||
self.measure_load = measure_load
|
self.measure_load = measure_load
|
||||||
|
|
||||||
@@ -38,35 +39,36 @@ class SolibLoadUnload1(perftest.TestCaseWithBasicMeasurements):
|
|||||||
|
|
||||||
def execute_test(self):
|
def execute_test(self):
|
||||||
num = self.solib_count
|
num = self.solib_count
|
||||||
iteration = 5;
|
iteration = 5
|
||||||
|
|
||||||
while num > 0 and iteration > 0:
|
while num > 0 and iteration > 0:
|
||||||
# Do inferior calls to do_test_load and do_test_unload in pairs,
|
# Do inferior calls to do_test_load and do_test_unload in pairs,
|
||||||
# but measure differently.
|
# but measure differently.
|
||||||
if self.measure_load:
|
if self.measure_load:
|
||||||
do_test_load = "call do_test_load (%d)" % num
|
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)
|
self.measure.measure(func, num)
|
||||||
|
|
||||||
do_test_unload = "call do_test_unload (%d)" % num
|
do_test_unload = "call do_test_unload (%d)" % num
|
||||||
gdb.execute (do_test_unload)
|
gdb.execute(do_test_unload)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
do_test_load = "call do_test_load (%d)" % num
|
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
|
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)
|
self.measure.measure(func, num)
|
||||||
|
|
||||||
num = num / 2
|
num = num / 2
|
||||||
iteration -= 1
|
iteration -= 1
|
||||||
|
|
||||||
|
|
||||||
class SolibLoadUnload(object):
|
class SolibLoadUnload(object):
|
||||||
def __init__(self, solib_count):
|
def __init__(self, solib_count):
|
||||||
self.solib_count = solib_count;
|
self.solib_count = solib_count
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
SolibLoadUnload1(self.solib_count, True).run()
|
SolibLoadUnload1(self.solib_count, True).run()
|
||||||
|
|||||||
@@ -15,9 +15,10 @@
|
|||||||
|
|
||||||
from perftest import perftest
|
from perftest import perftest
|
||||||
|
|
||||||
class TemplateBreakpoints (perftest.TestCaseWithBasicMeasurements):
|
|
||||||
|
class TemplateBreakpoints(perftest.TestCaseWithBasicMeasurements):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super (TemplateBreakpoints, self).__init__ ("template-breakpoints")
|
super(TemplateBreakpoints, self).__init__("template-breakpoints")
|
||||||
|
|
||||||
def warm_up(self):
|
def warm_up(self):
|
||||||
for _ in range(0, 2):
|
for _ in range(0, 2):
|
||||||
|
|||||||
@@ -18,20 +18,18 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
print ("Entering f1.o auto-load script")
|
print("Entering f1.o auto-load script")
|
||||||
|
|
||||||
print ("Current objfile is: %s"
|
print("Current objfile is: %s" % gdb.current_objfile().filename)
|
||||||
% gdb.current_objfile ().filename)
|
|
||||||
|
|
||||||
print ("Chain loading f2.o...")
|
print("Chain loading f2.o...")
|
||||||
|
|
||||||
filename = gdb.current_objfile ().filename
|
filename = gdb.current_objfile().filename
|
||||||
filename = re.sub (r"-f1.o$", "-f2.o", filename)
|
filename = re.sub(r"-f1.o$", "-f2.o", filename)
|
||||||
r2 = gdb.lookup_global_symbol ('region_2').value ()
|
r2 = gdb.lookup_global_symbol("region_2").value()
|
||||||
gdb.execute ("add-symbol-file %s 0x%x" % (filename, r2))
|
gdb.execute("add-symbol-file %s 0x%x" % (filename, r2))
|
||||||
|
|
||||||
print ("After loading f2.o...")
|
print("After loading f2.o...")
|
||||||
print ("Current objfile is: %s"
|
print("Current objfile is: %s" % gdb.current_objfile().filename)
|
||||||
% 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
|
# This script is auto-loaded when the py-auto-load-chaining-f2.o
|
||||||
# object is loaded.
|
# object is loaded.
|
||||||
|
|
||||||
print ("Entering f2.o auto-load script")
|
print("Entering f2.o auto-load script")
|
||||||
|
|
||||||
print ("Current objfile is: %s"
|
print("Current objfile is: %s" % gdb.current_objfile().filename)
|
||||||
% 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
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
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
|
@staticmethod
|
||||||
def _bad_iterator(pointer, len):
|
def _bad_iterator(pointer, len):
|
||||||
start = pointer
|
start = pointer
|
||||||
end = pointer + len
|
end = pointer + len
|
||||||
while pointer != end:
|
while pointer != end:
|
||||||
yield 'intentional violation of children iterator protocol'
|
yield "intentional violation of children iterator protocol"
|
||||||
pointer += 1
|
pointer += 1
|
||||||
|
|
||||||
def children(self):
|
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):
|
class BadChildrenContainerPrinter2(object):
|
||||||
@@ -50,7 +50,7 @@ class BadChildrenContainerPrinter2(object):
|
|||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
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
|
@staticmethod
|
||||||
def _bad_iterator(pointer, len):
|
def _bad_iterator(pointer, len):
|
||||||
@@ -58,20 +58,18 @@ class BadChildrenContainerPrinter2(object):
|
|||||||
end = pointer + len
|
end = pointer + len
|
||||||
while pointer != end:
|
while pointer != end:
|
||||||
# The first argument is supposed to be a string.
|
# 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
|
pointer += 1
|
||||||
|
|
||||||
def children(self):
|
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():
|
def build_pretty_printer():
|
||||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("bad-printers")
|
pp = gdb.printing.RegexpCollectionPrettyPrinter("bad-printers")
|
||||||
|
|
||||||
pp.add_printer('container1', '^container$',
|
pp.add_printer("container1", "^container$", BadChildrenContainerPrinter1)
|
||||||
BadChildrenContainerPrinter1)
|
pp.add_printer("container2", "^container$", BadChildrenContainerPrinter2)
|
||||||
pp.add_printer('container2', '^container$',
|
|
||||||
BadChildrenContainerPrinter2)
|
|
||||||
|
|
||||||
return pp
|
return pp
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ import gdb
|
|||||||
|
|
||||||
class MyBP(gdb.Breakpoint):
|
class MyBP(gdb.Breakpoint):
|
||||||
def stop(self):
|
def stop(self):
|
||||||
print('MyBP.stop was invoked!')
|
print("MyBP.stop was invoked!")
|
||||||
# Don't make this breakpoint stop
|
# Don't make this breakpoint stop
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bp = MyBP('does_not_exist', gdb.BP_WATCHPOINT)
|
bp = MyBP("does_not_exist", gdb.BP_WATCHPOINT)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -17,31 +17,36 @@
|
|||||||
|
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
|
|
||||||
class CompleteFileInit(gdb.Command):
|
class CompleteFileInit(gdb.Command):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
gdb.Command.__init__(self,'completefileinit',gdb.COMMAND_USER,gdb.COMPLETE_FILENAME)
|
gdb.Command.__init__(
|
||||||
|
self, "completefileinit", gdb.COMMAND_USER, gdb.COMPLETE_FILENAME
|
||||||
|
)
|
||||||
|
|
||||||
|
def invoke(self, argument, from_tty):
|
||||||
|
raise gdb.GdbError("not implemented")
|
||||||
|
|
||||||
def invoke(self,argument,from_tty):
|
|
||||||
raise gdb.GdbError('not implemented')
|
|
||||||
|
|
||||||
class CompleteFileMethod(gdb.Command):
|
class CompleteFileMethod(gdb.Command):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
gdb.Command.__init__(self,'completefilemethod',gdb.COMMAND_USER)
|
gdb.Command.__init__(self, "completefilemethod", gdb.COMMAND_USER)
|
||||||
|
|
||||||
def invoke(self,argument,from_tty):
|
def invoke(self, argument, from_tty):
|
||||||
raise gdb.GdbError('not implemented')
|
raise gdb.GdbError("not implemented")
|
||||||
|
|
||||||
def complete(self,text,word):
|
def complete(self, text, word):
|
||||||
return gdb.COMPLETE_FILENAME
|
return gdb.COMPLETE_FILENAME
|
||||||
|
|
||||||
|
|
||||||
class CompleteFileCommandCond(gdb.Command):
|
class CompleteFileCommandCond(gdb.Command):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
gdb.Command.__init__(self,'completefilecommandcond',gdb.COMMAND_USER)
|
gdb.Command.__init__(self, "completefilecommandcond", gdb.COMMAND_USER)
|
||||||
|
|
||||||
def invoke(self,argument,from_tty):
|
def invoke(self, argument, from_tty):
|
||||||
raise gdb.GdbError('not implemented')
|
raise gdb.GdbError("not implemented")
|
||||||
|
|
||||||
def complete(self,text,word):
|
def complete(self, text, word):
|
||||||
# This is a test made to know if the command
|
# This is a test made to know if the command
|
||||||
# completion still works fine. When the user asks to
|
# completion still works fine. When the user asks to
|
||||||
# complete something like "completefilecommandcond
|
# complete something like "completefilecommandcond
|
||||||
@@ -53,87 +58,149 @@ class CompleteFileCommandCond(gdb.Command):
|
|||||||
else:
|
else:
|
||||||
return gdb.COMPLETE_FILENAME
|
return gdb.COMPLETE_FILENAME
|
||||||
|
|
||||||
|
|
||||||
class CompleteLimit1(gdb.Command):
|
class CompleteLimit1(gdb.Command):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
gdb.Command.__init__(self,'completelimit1',gdb.COMMAND_USER)
|
gdb.Command.__init__(self, "completelimit1", gdb.COMMAND_USER)
|
||||||
|
|
||||||
def invoke(self,argument,from_tty):
|
def invoke(self, argument, from_tty):
|
||||||
raise gdb.GdbError('not implemented')
|
raise gdb.GdbError("not implemented")
|
||||||
|
|
||||||
def complete(self,text,word):
|
def complete(self, text, word):
|
||||||
return ["cl11", "cl12", "cl13"]
|
return ["cl11", "cl12", "cl13"]
|
||||||
|
|
||||||
|
|
||||||
class CompleteLimit2(gdb.Command):
|
class CompleteLimit2(gdb.Command):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
gdb.Command.__init__(self,'completelimit2',
|
gdb.Command.__init__(self, "completelimit2", gdb.COMMAND_USER)
|
||||||
gdb.COMMAND_USER)
|
|
||||||
|
|
||||||
def invoke(self,argument,from_tty):
|
def invoke(self, argument, from_tty):
|
||||||
raise gdb.GdbError('not implemented')
|
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):
|
class CompleteLimit3(gdb.Command):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
gdb.Command.__init__(self,'completelimit3',
|
gdb.Command.__init__(self, "completelimit3", gdb.COMMAND_USER)
|
||||||
gdb.COMMAND_USER)
|
|
||||||
|
|
||||||
def invoke(self,argument,from_tty):
|
def invoke(self, argument, from_tty):
|
||||||
raise gdb.GdbError('not implemented')
|
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):
|
class CompleteLimit4(gdb.Command):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
gdb.Command.__init__(self,'completelimit4',
|
gdb.Command.__init__(self, "completelimit4", gdb.COMMAND_USER)
|
||||||
gdb.COMMAND_USER)
|
|
||||||
|
|
||||||
def invoke(self,argument,from_tty):
|
def invoke(self, argument, from_tty):
|
||||||
raise gdb.GdbError('not implemented')
|
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):
|
class CompleteLimit5(gdb.Command):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
gdb.Command.__init__(self,'completelimit5',
|
gdb.Command.__init__(self, "completelimit5", gdb.COMMAND_USER)
|
||||||
gdb.COMMAND_USER)
|
|
||||||
|
|
||||||
def invoke(self,argument,from_tty):
|
def invoke(self, argument, from_tty):
|
||||||
raise gdb.GdbError('not implemented')
|
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):
|
class CompleteLimit6(gdb.Command):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
gdb.Command.__init__(self,'completelimit6',
|
gdb.Command.__init__(self, "completelimit6", gdb.COMMAND_USER)
|
||||||
gdb.COMMAND_USER)
|
|
||||||
|
|
||||||
def invoke(self,argument,from_tty):
|
def invoke(self, argument, from_tty):
|
||||||
raise gdb.GdbError('not implemented')
|
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):
|
class CompleteLimit7(gdb.Command):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
gdb.Command.__init__(self,'completelimit7',
|
gdb.Command.__init__(self, "completelimit7", gdb.COMMAND_USER)
|
||||||
gdb.COMMAND_USER)
|
|
||||||
|
|
||||||
def invoke(self,argument,from_tty):
|
def invoke(self, argument, from_tty):
|
||||||
raise gdb.GdbError('not implemented')
|
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()
|
CompleteFileInit()
|
||||||
CompleteFileMethod()
|
CompleteFileMethod()
|
||||||
|
|||||||
@@ -15,11 +15,15 @@
|
|||||||
|
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
|
|
||||||
class ClassName(gdb.Command):
|
class ClassName(gdb.Command):
|
||||||
'a'
|
"a"
|
||||||
|
|
||||||
def __init__(self):
|
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):
|
def invoke(self, args, from_tty):
|
||||||
print
|
print
|
||||||
|
|
||||||
|
|
||||||
ClassName()
|
ClassName()
|
||||||
|
|||||||
@@ -17,102 +17,114 @@
|
|||||||
# printers.
|
# printers.
|
||||||
import gdb
|
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):
|
def signal_stop_handler(event):
|
||||||
if (isinstance (event, gdb.StopEvent)):
|
if isinstance(event, gdb.StopEvent):
|
||||||
print ("event type: stop")
|
print("event type: stop")
|
||||||
if (isinstance (event, gdb.BreakpointEvent)):
|
if isinstance(event, gdb.SignalEvent):
|
||||||
print ("stop reason: breakpoint")
|
print("stop reason: signal")
|
||||||
print ("first breakpoint number: %s" % (event.breakpoint.number))
|
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:
|
for bp in event.breakpoints:
|
||||||
print ("breakpoint number: %s" % (bp.number))
|
print("breakpoint number: %s" % (bp.number))
|
||||||
if ( event.inferior_thread is not None) :
|
if event.inferior_thread is not None:
|
||||||
print ("thread num: %s" % (event.inferior_thread.num))
|
print("thread num: %s" % (event.inferior_thread.num))
|
||||||
else:
|
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):
|
def exit_handler(event):
|
||||||
assert (isinstance (event, gdb.ContinueEvent))
|
assert isinstance(event, gdb.ExitedEvent)
|
||||||
print ("event type: continue")
|
print("event type: exit")
|
||||||
if ( event.inferior_thread is not None) :
|
print("exit code: %d" % (event.exit_code))
|
||||||
print ("thread num: %s" % (event.inferior_thread.num))
|
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):
|
def continue_handler(event):
|
||||||
assert (isinstance (event, gdb.ClearObjFilesEvent))
|
assert isinstance(event, gdb.ContinueEvent)
|
||||||
print ("event type: clear_objfiles")
|
print("event type: continue")
|
||||||
print ("progspace: %s" % (event.progspace.filename))
|
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)):
|
def new_objfile_handler(event):
|
||||||
print ("event type: pre-call")
|
assert isinstance(event, gdb.NewObjFileEvent)
|
||||||
elif (isinstance (event, gdb.InferiorCallPostEvent)):
|
print("event type: new_objfile")
|
||||||
print ("event type: post-call")
|
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:
|
else:
|
||||||
assert False
|
assert False
|
||||||
print ("ptid: %s" % (event.ptid,))
|
print("ptid: %s" % (event.ptid,))
|
||||||
print ("address: 0x%x" % (event.address))
|
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))
|
|
||||||
|
|
||||||
|
|
||||||
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."""
|
"""Test events."""
|
||||||
|
|
||||||
def __init__ (self):
|
def __init__(self):
|
||||||
gdb.Command.__init__ (self, "test-events", gdb.COMMAND_STACK)
|
gdb.Command.__init__(self, "test-events", gdb.COMMAND_STACK)
|
||||||
|
|
||||||
def invoke (self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
gdb.events.stop.connect (signal_stop_handler)
|
gdb.events.stop.connect(signal_stop_handler)
|
||||||
gdb.events.stop.connect (breakpoint_stop_handler)
|
gdb.events.stop.connect(breakpoint_stop_handler)
|
||||||
gdb.events.exited.connect (exit_handler)
|
gdb.events.exited.connect(exit_handler)
|
||||||
gdb.events.cont.connect (continue_handler)
|
gdb.events.cont.connect(continue_handler)
|
||||||
gdb.events.inferior_call.connect (inferior_call_handler)
|
gdb.events.inferior_call.connect(inferior_call_handler)
|
||||||
gdb.events.memory_changed.connect (memory_changed_handler)
|
gdb.events.memory_changed.connect(memory_changed_handler)
|
||||||
gdb.events.register_changed.connect (register_changed_handler)
|
gdb.events.register_changed.connect(register_changed_handler)
|
||||||
print ("Event testers registered.")
|
print("Event testers registered.")
|
||||||
|
|
||||||
test_events ()
|
|
||||||
|
|
||||||
class test_newobj_events (gdb.Command):
|
test_events()
|
||||||
|
|
||||||
|
|
||||||
|
class test_newobj_events(gdb.Command):
|
||||||
"""NewObj events."""
|
"""NewObj events."""
|
||||||
|
|
||||||
def __init__ (self):
|
def __init__(self):
|
||||||
gdb.Command.__init__ (self, "test-objfile-events", gdb.COMMAND_STACK)
|
gdb.Command.__init__(self, "test-objfile-events", gdb.COMMAND_STACK)
|
||||||
|
|
||||||
def invoke (self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
gdb.events.new_objfile.connect (new_objfile_handler)
|
gdb.events.new_objfile.connect(new_objfile_handler)
|
||||||
gdb.events.clear_objfiles.connect (clear_objfiles_handler)
|
gdb.events.clear_objfiles.connect(clear_objfiles_handler)
|
||||||
print ("Object file events registered.")
|
print("Object file events registered.")
|
||||||
|
|
||||||
test_newobj_events ()
|
|
||||||
|
test_newobj_events()
|
||||||
|
|||||||
@@ -16,74 +16,78 @@
|
|||||||
# This file is part of the GDB testsuite. It tests python Finish
|
# This file is part of the GDB testsuite. It tests python Finish
|
||||||
# Breakpoints.
|
# Breakpoints.
|
||||||
|
|
||||||
class MyFinishBreakpoint (gdb.FinishBreakpoint):
|
|
||||||
|
class MyFinishBreakpoint(gdb.FinishBreakpoint):
|
||||||
def __init__(self, val, frame):
|
def __init__(self, val, frame):
|
||||||
gdb.FinishBreakpoint.__init__ (self, frame)
|
gdb.FinishBreakpoint.__init__(self, frame)
|
||||||
print ("MyFinishBreakpoint init")
|
print("MyFinishBreakpoint init")
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
print ("MyFinishBreakpoint stop with %d" % int (self.val.dereference ()))
|
print("MyFinishBreakpoint stop with %d" % int(self.val.dereference()))
|
||||||
print ("return_value is: %d" % int (self.return_value))
|
print("return_value is: %d" % int(self.return_value))
|
||||||
gdb.execute ("where 1")
|
gdb.execute("where 1")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def out_of_scope(self):
|
def out_of_scope(self):
|
||||||
print ("MyFinishBreakpoint out of scope")
|
print("MyFinishBreakpoint out of scope")
|
||||||
|
|
||||||
|
|
||||||
class TestBreakpoint(gdb.Breakpoint):
|
class TestBreakpoint(gdb.Breakpoint):
|
||||||
def __init__(self):
|
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.silent = True
|
||||||
self.count = 0
|
self.count = 0
|
||||||
print ("TestBreakpoint init")
|
print("TestBreakpoint init")
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.count += 1
|
self.count += 1
|
||||||
try:
|
try:
|
||||||
TestFinishBreakpoint (gdb.newest_frame (), self.count)
|
TestFinishBreakpoint(gdb.newest_frame(), self.count)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
print (e)
|
print(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class TestFinishBreakpoint (gdb.FinishBreakpoint):
|
|
||||||
def __init__ (self, frame, count):
|
|
||||||
self.count = count
|
|
||||||
gdb.FinishBreakpoint.__init__ (self, frame, internal=1)
|
|
||||||
|
|
||||||
|
class TestFinishBreakpoint(gdb.FinishBreakpoint):
|
||||||
|
def __init__(self, frame, count):
|
||||||
|
self.count = count
|
||||||
|
gdb.FinishBreakpoint.__init__(self, frame, internal=1)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
print ("-->", self.number)
|
print("-->", self.number)
|
||||||
if (self.count == 3):
|
if self.count == 3:
|
||||||
print ("test stop: %d" % self.count)
|
print("test stop: %d" % self.count)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
print ("test don't stop: %d" % self.count)
|
print("test don't stop: %d" % self.count)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def out_of_scope(self):
|
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):
|
class TestExplicitBreakpoint(gdb.Breakpoint):
|
||||||
def stop(self):
|
def stop(self):
|
||||||
try:
|
try:
|
||||||
SimpleFinishBreakpoint (gdb.newest_frame ())
|
SimpleFinishBreakpoint(gdb.newest_frame())
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
print (e)
|
print(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class SimpleFinishBreakpoint(gdb.FinishBreakpoint):
|
class SimpleFinishBreakpoint(gdb.FinishBreakpoint):
|
||||||
def __init__(self, frame):
|
def __init__(self, frame):
|
||||||
gdb.FinishBreakpoint.__init__ (self, frame)
|
gdb.FinishBreakpoint.__init__(self, frame)
|
||||||
|
|
||||||
print ("SimpleFinishBreakpoint init")
|
print("SimpleFinishBreakpoint init")
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
print ("SimpleFinishBreakpoint stop" )
|
print("SimpleFinishBreakpoint stop")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def out_of_scope(self):
|
def out_of_scope(self):
|
||||||
print ("SimpleFinishBreakpoint out of scope")
|
print("SimpleFinishBreakpoint out of scope")
|
||||||
|
|
||||||
print ("Python script imported")
|
|
||||||
|
print("Python script imported")
|
||||||
|
|||||||
@@ -16,18 +16,19 @@
|
|||||||
# This file is part of the GDB testsuite. It tests python Finish
|
# This file is part of the GDB testsuite. It tests python Finish
|
||||||
# Breakpoints.
|
# Breakpoints.
|
||||||
|
|
||||||
|
|
||||||
class ExceptionFinishBreakpoint(gdb.FinishBreakpoint):
|
class ExceptionFinishBreakpoint(gdb.FinishBreakpoint):
|
||||||
def __init__(self, frame):
|
def __init__(self, frame):
|
||||||
gdb.FinishBreakpoint.__init__ (self, frame, internal=1)
|
gdb.FinishBreakpoint.__init__(self, frame, internal=1)
|
||||||
self.silent = True
|
self.silent = True
|
||||||
print ("init ExceptionFinishBreakpoint")
|
print("init ExceptionFinishBreakpoint")
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
print ("stopped at ExceptionFinishBreakpoint")
|
print("stopped at ExceptionFinishBreakpoint")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def out_of_scope(self):
|
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
|
import gdb
|
||||||
|
|
||||||
class PointPrinter (object):
|
|
||||||
def __init__ (self, val):
|
class PointPrinter(object):
|
||||||
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string (self):
|
def to_string(self):
|
||||||
return 'Pretty Point (%s, %s)' % (self.val['x'], self.val['y'])
|
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."
|
"Look-up and return a pretty-printer that can print val."
|
||||||
|
|
||||||
# Get the type.
|
# Get the type.
|
||||||
@@ -33,17 +35,18 @@ def test_lookup_function (val):
|
|||||||
|
|
||||||
# If it points to a reference, get the reference.
|
# If it points to a reference, get the reference.
|
||||||
if type.code == gdb.TYPE_CODE_REF:
|
if type.code == gdb.TYPE_CODE_REF:
|
||||||
type = type.target ()
|
type = type.target()
|
||||||
|
|
||||||
# Get the unqualified type, stripped of typedefs.
|
# 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
|
typename = type.tag
|
||||||
|
|
||||||
if typename == 'point':
|
if typename == "point":
|
||||||
return PointPrinter (val)
|
return PointPrinter(val)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
gdb.pretty_printers.append (test_lookup_function)
|
|
||||||
|
gdb.pretty_printers.append(test_lookup_function)
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
import re
|
import re
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
class pp_s (object):
|
|
||||||
|
class pp_s(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
@@ -24,19 +25,20 @@ class pp_s (object):
|
|||||||
m = self.val["m"]
|
m = self.val["m"]
|
||||||
return "m=<" + str(self.val["m"]) + ">"
|
return "m=<" + str(self.val["m"]) + ">"
|
||||||
|
|
||||||
class pp_ss (object):
|
|
||||||
|
class pp_ss(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return "super struct"
|
return "super struct"
|
||||||
|
|
||||||
def children (self):
|
def children(self):
|
||||||
yield 'a', self.val['a']
|
yield "a", self.val["a"]
|
||||||
yield 'b', self.val['b']
|
yield "b", self.val["b"]
|
||||||
|
|
||||||
|
|
||||||
def lookup_function (val):
|
def lookup_function(val):
|
||||||
"Look-up and return a pretty-printer that can print val."
|
"Look-up and return a pretty-printer that can print val."
|
||||||
|
|
||||||
# Get the type.
|
# Get the type.
|
||||||
@@ -44,10 +46,10 @@ def lookup_function (val):
|
|||||||
|
|
||||||
# If it points to a reference, get the reference.
|
# If it points to a reference, get the reference.
|
||||||
if type.code == gdb.TYPE_CODE_REF:
|
if type.code == gdb.TYPE_CODE_REF:
|
||||||
type = type.target ()
|
type = type.target()
|
||||||
|
|
||||||
# Get the unqualified type, stripped of typedefs.
|
# 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
|
typename = type.tag
|
||||||
@@ -58,18 +60,19 @@ def lookup_function (val):
|
|||||||
# if a printer is registered for that type. Return an
|
# if a printer is registered for that type. Return an
|
||||||
# instantiation of the printer if found.
|
# instantiation of the printer if found.
|
||||||
for function in pretty_printers_dict:
|
for function in pretty_printers_dict:
|
||||||
if function.match (typename):
|
if function.match(typename):
|
||||||
return pretty_printers_dict[function] (val)
|
return pretty_printers_dict[function](val)
|
||||||
|
|
||||||
# Cannot find a pretty printer. Return None.
|
# Cannot find a pretty printer. Return None.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def register_pretty_printers ():
|
def register_pretty_printers():
|
||||||
pretty_printers_dict[re.compile ('^s$')] = pp_s
|
pretty_printers_dict[re.compile("^s$")] = pp_s
|
||||||
pretty_printers_dict[re.compile ('^ss$')] = pp_ss
|
pretty_printers_dict[re.compile("^ss$")] = pp_ss
|
||||||
|
|
||||||
|
|
||||||
pretty_printers_dict = {}
|
pretty_printers_dict = {}
|
||||||
|
|
||||||
register_pretty_printers ()
|
register_pretty_printers()
|
||||||
gdb.pretty_printers.append (lookup_function)
|
gdb.pretty_printers.append(lookup_function)
|
||||||
|
|||||||
@@ -20,33 +20,32 @@ import copy
|
|||||||
|
|
||||||
# A FrameDecorator that just returns gdb.Frame.pc () from 'function'.
|
# A FrameDecorator that just returns gdb.Frame.pc () from 'function'.
|
||||||
# We want to ensure that GDB correctly handles this case.
|
# We want to ensure that GDB correctly handles this case.
|
||||||
class Function_Returns_Address (FrameDecorator):
|
class Function_Returns_Address(FrameDecorator):
|
||||||
|
|
||||||
def __init__(self, fobj):
|
def __init__(self, fobj):
|
||||||
super (Function_Returns_Address, self).__init__ (fobj)
|
super(Function_Returns_Address, self).__init__(fobj)
|
||||||
self._fobj = fobj
|
self._fobj = fobj
|
||||||
|
|
||||||
def function (self):
|
def function(self):
|
||||||
frame = self.inferior_frame ()
|
frame = self.inferior_frame()
|
||||||
return frame.pc ()
|
return frame.pc()
|
||||||
|
|
||||||
class Frame_Filter ():
|
|
||||||
|
|
||||||
def __init__ (self):
|
class Frame_Filter:
|
||||||
|
def __init__(self):
|
||||||
self.name = "function_returns_address"
|
self.name = "function_returns_address"
|
||||||
self.priority = 100
|
self.priority = 100
|
||||||
self.enabled = True
|
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(),
|
# Python 3.x moved the itertools.imap functionality to map(),
|
||||||
# so check if it is available.
|
# so check if it is available.
|
||||||
if hasattr(itertools, "imap"):
|
if hasattr(itertools, "imap"):
|
||||||
frame_iter = itertools.imap (Function_Returns_Address,
|
frame_iter = itertools.imap(Function_Returns_Address, frame_iter)
|
||||||
frame_iter)
|
|
||||||
else:
|
else:
|
||||||
frame_iter = map(Function_Returns_Address, frame_iter)
|
frame_iter = map(Function_Returns_Address, frame_iter)
|
||||||
|
|
||||||
return frame_iter
|
return frame_iter
|
||||||
|
|
||||||
|
|
||||||
Frame_Filter()
|
Frame_Filter()
|
||||||
|
|||||||
@@ -20,40 +20,40 @@ import itertools
|
|||||||
from gdb.FrameDecorator import FrameDecorator
|
from gdb.FrameDecorator import FrameDecorator
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
class Reverse_Function (FrameDecorator):
|
|
||||||
|
|
||||||
|
class Reverse_Function(FrameDecorator):
|
||||||
def __init__(self, fobj):
|
def __init__(self, fobj):
|
||||||
super(Reverse_Function, self).__init__(fobj)
|
super(Reverse_Function, self).__init__(fobj)
|
||||||
self.fobj = fobj
|
self.fobj = fobj
|
||||||
|
|
||||||
def function (self):
|
def function(self):
|
||||||
fname = str (self.fobj.function())
|
fname = str(self.fobj.function())
|
||||||
if (fname == None or fname == ""):
|
if fname == None or fname == "":
|
||||||
return None
|
return None
|
||||||
if fname == 'end_func':
|
if fname == "end_func":
|
||||||
extra = self.fobj.inferior_frame().read_var('str').string()
|
extra = self.fobj.inferior_frame().read_var("str").string()
|
||||||
else:
|
else:
|
||||||
extra = ''
|
extra = ""
|
||||||
fname = fname[::-1] + extra
|
fname = fname[::-1] + extra
|
||||||
return fname
|
return fname
|
||||||
|
|
||||||
class FrameFilter ():
|
|
||||||
|
|
||||||
def __init__ (self):
|
class FrameFilter:
|
||||||
|
def __init__(self):
|
||||||
self.name = "Reverse"
|
self.name = "Reverse"
|
||||||
self.priority = 100
|
self.priority = 100
|
||||||
self.enabled = True
|
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(),
|
# Python 3.x moved the itertools.imap functionality to map(),
|
||||||
# so check if it is available.
|
# so check if it is available.
|
||||||
if hasattr(itertools, "imap"):
|
if hasattr(itertools, "imap"):
|
||||||
frame_iter = itertools.imap (Reverse_Function,
|
frame_iter = itertools.imap(Reverse_Function, frame_iter)
|
||||||
frame_iter)
|
|
||||||
else:
|
else:
|
||||||
frame_iter = map(Reverse_Function, frame_iter)
|
frame_iter = map(Reverse_Function, frame_iter)
|
||||||
|
|
||||||
return frame_iter
|
return frame_iter
|
||||||
|
|
||||||
|
|
||||||
FrameFilter()
|
FrameFilter()
|
||||||
|
|||||||
@@ -20,71 +20,70 @@ import itertools
|
|||||||
from gdb.FrameDecorator import FrameDecorator
|
from gdb.FrameDecorator import FrameDecorator
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
class Reverse_Function (FrameDecorator):
|
|
||||||
|
|
||||||
|
class Reverse_Function(FrameDecorator):
|
||||||
def __init__(self, fobj):
|
def __init__(self, fobj):
|
||||||
super(Reverse_Function, self).__init__(fobj)
|
super(Reverse_Function, self).__init__(fobj)
|
||||||
self.fobj = fobj
|
self.fobj = fobj
|
||||||
|
|
||||||
def function (self):
|
def function(self):
|
||||||
fname = str (self.fobj.function())
|
fname = str(self.fobj.function())
|
||||||
if (fname == None or fname == ""):
|
if fname == None or fname == "":
|
||||||
return None
|
return None
|
||||||
if fname == 'end_func':
|
if fname == "end_func":
|
||||||
extra = self.fobj.inferior_frame().read_var('str').string()
|
extra = self.fobj.inferior_frame().read_var("str").string()
|
||||||
else:
|
else:
|
||||||
extra = ''
|
extra = ""
|
||||||
fname = fname[::-1] + extra
|
fname = fname[::-1] + extra
|
||||||
return fname
|
return fname
|
||||||
|
|
||||||
class Dummy (FrameDecorator):
|
|
||||||
|
|
||||||
|
class Dummy(FrameDecorator):
|
||||||
def __init__(self, fobj):
|
def __init__(self, fobj):
|
||||||
super(Dummy, self).__init__(fobj)
|
super(Dummy, self).__init__(fobj)
|
||||||
self.fobj = fobj
|
self.fobj = fobj
|
||||||
|
|
||||||
def function (self):
|
def function(self):
|
||||||
return "Dummy function"
|
return "Dummy function"
|
||||||
|
|
||||||
def address (self):
|
def address(self):
|
||||||
return 0x123
|
return 0x123
|
||||||
|
|
||||||
def filename (self):
|
def filename(self):
|
||||||
return "Dummy filename"
|
return "Dummy filename"
|
||||||
|
|
||||||
def frame_args (self):
|
def frame_args(self):
|
||||||
return [("Foo",gdb.Value(12)),("Bar","Stuff"), ("FooBar",42)]
|
return [("Foo", gdb.Value(12)), ("Bar", "Stuff"), ("FooBar", 42)]
|
||||||
|
|
||||||
def frame_locals (self):
|
def frame_locals(self):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def line (self):
|
def line(self):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def elided (self):
|
def elided(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
class FrameFilter ():
|
|
||||||
|
|
||||||
def __init__ (self):
|
class FrameFilter:
|
||||||
|
def __init__(self):
|
||||||
self.name = "Reverse"
|
self.name = "Reverse"
|
||||||
self.priority = 100
|
self.priority = 100
|
||||||
self.enabled = True
|
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(),
|
# Python 3.x moved the itertools.imap functionality to map(),
|
||||||
# so check if it is available.
|
# so check if it is available.
|
||||||
if hasattr(itertools, "imap"):
|
if hasattr(itertools, "imap"):
|
||||||
frame_iter = itertools.imap (Reverse_Function,
|
frame_iter = itertools.imap(Reverse_Function, frame_iter)
|
||||||
frame_iter)
|
|
||||||
else:
|
else:
|
||||||
frame_iter = map(Reverse_Function, frame_iter)
|
frame_iter = map(Reverse_Function, frame_iter)
|
||||||
|
|
||||||
return frame_iter
|
return frame_iter
|
||||||
|
|
||||||
class ElidingFrameDecorator(FrameDecorator):
|
|
||||||
|
|
||||||
|
class ElidingFrameDecorator(FrameDecorator):
|
||||||
def __init__(self, frame, elided_frames):
|
def __init__(self, frame, elided_frames):
|
||||||
super(ElidingFrameDecorator, self).__init__(frame)
|
super(ElidingFrameDecorator, self).__init__(frame)
|
||||||
self.elided_frames = elided_frames
|
self.elided_frames = elided_frames
|
||||||
@@ -92,11 +91,12 @@ class ElidingFrameDecorator(FrameDecorator):
|
|||||||
def elided(self):
|
def elided(self):
|
||||||
return iter(self.elided_frames)
|
return iter(self.elided_frames)
|
||||||
|
|
||||||
def address (self):
|
def address(self):
|
||||||
# Regression test for an overflow in the python layer.
|
# 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
|
mask = (1 << bitsize) - 1
|
||||||
return 0xffffffffffffffff & mask
|
return 0xFFFFFFFFFFFFFFFF & mask
|
||||||
|
|
||||||
|
|
||||||
class ElidingIterator:
|
class ElidingIterator:
|
||||||
def __init__(self, ii):
|
def __init__(self, ii):
|
||||||
@@ -107,7 +107,7 @@ class ElidingIterator:
|
|||||||
|
|
||||||
def next(self):
|
def next(self):
|
||||||
frame = next(self.input_iterator)
|
frame = next(self.input_iterator)
|
||||||
if str(frame.function()) != 'func1':
|
if str(frame.function()) != "func1":
|
||||||
return frame
|
return frame
|
||||||
|
|
||||||
# Suppose we want to return the 'func1' frame but elide the
|
# Suppose we want to return the 'func1' frame but elide the
|
||||||
@@ -123,16 +123,17 @@ class ElidingIterator:
|
|||||||
def __next__(self):
|
def __next__(self):
|
||||||
return self.next()
|
return self.next()
|
||||||
|
|
||||||
class FrameElider ():
|
|
||||||
|
|
||||||
def __init__ (self):
|
class FrameElider:
|
||||||
|
def __init__(self):
|
||||||
self.name = "Elider"
|
self.name = "Elider"
|
||||||
self.priority = 900
|
self.priority = 900
|
||||||
self.enabled = True
|
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
|
# This is here so the test can change the kind of error that is
|
||||||
# thrown.
|
# thrown.
|
||||||
@@ -144,24 +145,26 @@ class ErrorInName(FrameDecorator):
|
|||||||
FrameDecorator.__init__(self, frame)
|
FrameDecorator.__init__(self, frame)
|
||||||
|
|
||||||
def function(self):
|
def function(self):
|
||||||
raise name_error('whoops')
|
raise name_error("whoops")
|
||||||
|
|
||||||
|
|
||||||
# A filter that supplies buggy frames. Disabled by default.
|
# A filter that supplies buggy frames. Disabled by default.
|
||||||
class ErrorFilter():
|
class ErrorFilter:
|
||||||
def __init__ (self):
|
def __init__(self):
|
||||||
self.name = "Error"
|
self.name = "Error"
|
||||||
self.priority = 1
|
self.priority = 1
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
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(),
|
# Python 3.x moved the itertools.imap functionality to map(),
|
||||||
# so check if it is available.
|
# so check if it is available.
|
||||||
if hasattr(itertools, "imap"):
|
if hasattr(itertools, "imap"):
|
||||||
return itertools.imap (ErrorInName, frame_iter)
|
return itertools.imap(ErrorInName, frame_iter)
|
||||||
else:
|
else:
|
||||||
return map(ErrorInName, frame_iter)
|
return map(ErrorInName, frame_iter)
|
||||||
|
|
||||||
|
|
||||||
FrameFilter()
|
FrameFilter()
|
||||||
FrameElider()
|
FrameElider()
|
||||||
ErrorFilter()
|
ErrorFilter()
|
||||||
|
|||||||
@@ -22,31 +22,33 @@ import gdb
|
|||||||
stop_handler_str = ""
|
stop_handler_str = ""
|
||||||
cont_handler_str = ""
|
cont_handler_str = ""
|
||||||
|
|
||||||
def signal_stop_handler (event):
|
|
||||||
|
def signal_stop_handler(event):
|
||||||
"""Stop event handler"""
|
"""Stop event handler"""
|
||||||
assert (isinstance (event, gdb.StopEvent))
|
assert isinstance(event, gdb.StopEvent)
|
||||||
global stop_handler_str
|
global stop_handler_str
|
||||||
stop_handler_str = "stop_handler\n"
|
stop_handler_str = "stop_handler\n"
|
||||||
stop_handler_str += gdb.execute("info break", False, True)
|
stop_handler_str += gdb.execute("info break", False, True)
|
||||||
|
|
||||||
|
|
||||||
def continue_handler (event):
|
def continue_handler(event):
|
||||||
"""Continue event handler"""
|
"""Continue event handler"""
|
||||||
assert (isinstance (event, gdb.ContinueEvent))
|
assert isinstance(event, gdb.ContinueEvent)
|
||||||
global cont_handler_str
|
global cont_handler_str
|
||||||
cont_handler_str = "continue_handler\n"
|
cont_handler_str = "continue_handler\n"
|
||||||
cont_handler_str += gdb.execute("info break", False, True)
|
cont_handler_str += gdb.execute("info break", False, True)
|
||||||
|
|
||||||
|
|
||||||
class test_events (gdb.Command):
|
class test_events(gdb.Command):
|
||||||
"""Test events."""
|
"""Test events."""
|
||||||
|
|
||||||
def __init__ (self):
|
def __init__(self):
|
||||||
gdb.Command.__init__ (self, "test-events", gdb.COMMAND_STACK)
|
gdb.Command.__init__(self, "test-events", gdb.COMMAND_STACK)
|
||||||
|
|
||||||
def invoke (self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
gdb.events.stop.connect (signal_stop_handler)
|
gdb.events.stop.connect(signal_stop_handler)
|
||||||
gdb.events.cont.connect (continue_handler)
|
gdb.events.cont.connect(continue_handler)
|
||||||
print ("Event testers registered.")
|
print("Event testers registered.")
|
||||||
|
|
||||||
test_events ()
|
|
||||||
|
test_events()
|
||||||
|
|||||||
@@ -29,29 +29,29 @@ class cons_pp(object):
|
|||||||
def to_string(self):
|
def to_string(self):
|
||||||
if long(self._val) == 0:
|
if long(self._val) == 0:
|
||||||
return "nil"
|
return "nil"
|
||||||
elif long(self._val['type']) == 0:
|
elif long(self._val["type"]) == 0:
|
||||||
return "( . )"
|
return "( . )"
|
||||||
else:
|
else:
|
||||||
return "%d" % self._val['atom']['ival']
|
return "%d" % self._val["atom"]["ival"]
|
||||||
|
|
||||||
def children(self):
|
def children(self):
|
||||||
if long(self._val) == 0:
|
if long(self._val) == 0:
|
||||||
return []
|
return []
|
||||||
elif long(self._val['type']) == 0:
|
elif long(self._val["type"]) == 0:
|
||||||
return [
|
return [("atom", self._val["atom"])]
|
||||||
('atom', self._val['atom'])
|
|
||||||
]
|
|
||||||
else:
|
else:
|
||||||
return [
|
return [
|
||||||
('car' , self._val["slots"][0]),
|
("car", self._val["slots"][0]),
|
||||||
('cdr' , self._val["slots"][1]),
|
("cdr", self._val["slots"][1]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def cons_pp_lookup(val):
|
def cons_pp_lookup(val):
|
||||||
if str(val.type) == 'struct cons *':
|
if str(val.type) == "struct cons *":
|
||||||
return cons_pp(val)
|
return cons_pp(val)
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
del gdb.pretty_printers[1:]
|
del gdb.pretty_printers[1:]
|
||||||
gdb.pretty_printers.append(cons_pp_lookup)
|
gdb.pretty_printers.append(cons_pp_lookup)
|
||||||
|
|||||||
@@ -19,15 +19,17 @@
|
|||||||
import re
|
import re
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
def _iterator1 (pointer, len):
|
|
||||||
|
def _iterator1(pointer, len):
|
||||||
while len > 0:
|
while len > 0:
|
||||||
map = pointer.dereference()
|
map = pointer.dereference()
|
||||||
yield ('', map['name'])
|
yield ("", map["name"])
|
||||||
yield ('', map.dereference())
|
yield ("", map.dereference())
|
||||||
pointer += 1
|
pointer += 1
|
||||||
len -= 1
|
len -= 1
|
||||||
|
|
||||||
def _iterator2 (pointer1, pointer2, len):
|
|
||||||
|
def _iterator2(pointer1, pointer2, len):
|
||||||
while len > 0:
|
while len > 0:
|
||||||
yield ("", pointer1.dereference())
|
yield ("", pointer1.dereference())
|
||||||
yield ("", pointer2.dereference())
|
yield ("", pointer2.dereference())
|
||||||
@@ -35,42 +37,42 @@ def _iterator2 (pointer1, pointer2, len):
|
|||||||
pointer2 += 1
|
pointer2 += 1
|
||||||
len -= 1
|
len -= 1
|
||||||
|
|
||||||
class pp_map (object):
|
|
||||||
|
class pp_map(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
if (self.val['show_header'] == 0):
|
if self.val["show_header"] == 0:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return "pp_map"
|
return "pp_map"
|
||||||
|
|
||||||
def children(self):
|
def children(self):
|
||||||
return _iterator2(self.val['keys'],
|
return _iterator2(self.val["keys"], self.val["values"], self.val["length"])
|
||||||
self.val['values'],
|
|
||||||
self.val['length'])
|
|
||||||
|
|
||||||
def display_hint (self):
|
def display_hint(self):
|
||||||
return 'map'
|
return "map"
|
||||||
|
|
||||||
class pp_map_map (object):
|
|
||||||
|
class pp_map_map(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
if (self.val['show_header'] == 0):
|
if self.val["show_header"] == 0:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return "pp_map_map"
|
return "pp_map_map"
|
||||||
|
|
||||||
def children(self):
|
def children(self):
|
||||||
return _iterator1(self.val['values'],
|
return _iterator1(self.val["values"], self.val["length"])
|
||||||
self.val['length'])
|
|
||||||
|
|
||||||
def display_hint (self):
|
def display_hint(self):
|
||||||
return 'map'
|
return "map"
|
||||||
|
|
||||||
def lookup_function (val):
|
|
||||||
|
def lookup_function(val):
|
||||||
"Look-up and return a pretty-printer that can print val."
|
"Look-up and return a pretty-printer that can print val."
|
||||||
|
|
||||||
# Get the type.
|
# Get the type.
|
||||||
@@ -78,10 +80,10 @@ def lookup_function (val):
|
|||||||
|
|
||||||
# If it points to a reference, get the reference.
|
# If it points to a reference, get the reference.
|
||||||
if type.code == gdb.TYPE_CODE_REF:
|
if type.code == gdb.TYPE_CODE_REF:
|
||||||
type = type.target ()
|
type = type.target()
|
||||||
|
|
||||||
# Get the unqualified type, stripped of typedefs.
|
# 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
|
typename = type.tag
|
||||||
@@ -93,14 +95,15 @@ def lookup_function (val):
|
|||||||
# if a printer is registered for that type. Return an
|
# if a printer is registered for that type. Return an
|
||||||
# instantiation of the printer if found.
|
# instantiation of the printer if found.
|
||||||
for function in pretty_printers_dict:
|
for function in pretty_printers_dict:
|
||||||
if function.match (typename):
|
if function.match(typename):
|
||||||
return pretty_printers_dict[function] (val)
|
return pretty_printers_dict[function](val)
|
||||||
|
|
||||||
# Cannot find a pretty printer. Return None.
|
# Cannot find a pretty printer. Return None.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# Lookup a printer for VAL in the typedefs dict.
|
# 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)."
|
"Look-up and return a pretty-printer that can print val (typedefs)."
|
||||||
|
|
||||||
# Get the type.
|
# Get the type.
|
||||||
@@ -113,23 +116,25 @@ def lookup_typedefs_function (val):
|
|||||||
# printer is registered for that type. Return an instantiation of
|
# printer is registered for that type. Return an instantiation of
|
||||||
# the printer if found.
|
# the printer if found.
|
||||||
for function in typedefs_pretty_printers_dict:
|
for function in typedefs_pretty_printers_dict:
|
||||||
if function.match (type.name):
|
if function.match(type.name):
|
||||||
return typedefs_pretty_printers_dict[function] (val)
|
return typedefs_pretty_printers_dict[function](val)
|
||||||
|
|
||||||
# Cannot find a pretty printer.
|
# Cannot find a pretty printer.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def register_pretty_printers ():
|
|
||||||
pretty_printers_dict[re.compile ('^struct map_t$')] = pp_map
|
def register_pretty_printers():
|
||||||
pretty_printers_dict[re.compile ('^map_t$')] = pp_map
|
pretty_printers_dict[re.compile("^struct map_t$")] = pp_map
|
||||||
pretty_printers_dict[re.compile ('^struct map_map_t$')] = pp_map_map
|
pretty_printers_dict[re.compile("^map_t$")] = pp_map
|
||||||
pretty_printers_dict[re.compile ('^map_map_t$')] = pp_map_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.
|
# Dict for struct types with typedefs fully stripped.
|
||||||
pretty_printers_dict = {}
|
pretty_printers_dict = {}
|
||||||
# Dict for typedef types.
|
# Dict for typedef types.
|
||||||
typedefs_pretty_printers_dict = {}
|
typedefs_pretty_printers_dict = {}
|
||||||
|
|
||||||
register_pretty_printers ()
|
register_pretty_printers()
|
||||||
gdb.pretty_printers.append (lookup_function)
|
gdb.pretty_printers.append(lookup_function)
|
||||||
gdb.pretty_printers.append (lookup_typedefs_function)
|
gdb.pretty_printers.append(lookup_typedefs_function)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
class pp_ss:
|
class pp_ss:
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
@@ -24,7 +25,8 @@ class pp_ss:
|
|||||||
def to_string(self):
|
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"]) + ">"
|
||||||
|
|
||||||
def lookup_function (val):
|
|
||||||
|
def lookup_function(val):
|
||||||
"Look-up and return a pretty-printer that can print val."
|
"Look-up and return a pretty-printer that can print val."
|
||||||
|
|
||||||
# Get the type.
|
# Get the type.
|
||||||
@@ -32,10 +34,10 @@ def lookup_function (val):
|
|||||||
|
|
||||||
# If it points to a reference, get the reference.
|
# If it points to a reference, get the reference.
|
||||||
if type.code == gdb.TYPE_CODE_REF:
|
if type.code == gdb.TYPE_CODE_REF:
|
||||||
type = type.target ()
|
type = type.target()
|
||||||
|
|
||||||
# Get the unqualified type, stripped of typedefs.
|
# 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
|
typename = type.tag
|
||||||
@@ -47,17 +49,19 @@ def lookup_function (val):
|
|||||||
# if a printer is registered for that type. Return an
|
# if a printer is registered for that type. Return an
|
||||||
# instantiation of the printer if found.
|
# instantiation of the printer if found.
|
||||||
for function in pretty_printers_dict:
|
for function in pretty_printers_dict:
|
||||||
if function.match (typename):
|
if function.match(typename):
|
||||||
return pretty_printers_dict[function] (val)
|
return pretty_printers_dict[function](val)
|
||||||
|
|
||||||
# Cannot find a pretty printer. Return None.
|
# Cannot find a pretty printer. Return None.
|
||||||
|
|
||||||
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 = {}
|
pretty_printers_dict = {}
|
||||||
|
|
||||||
register_pretty_printers ()
|
register_pretty_printers()
|
||||||
gdb.current_progspace().pretty_printers.append (lookup_function)
|
gdb.current_progspace().pretty_printers.append(lookup_function)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class TimePrinter:
|
|||||||
|
|
||||||
|
|
||||||
def time_sniffer(val):
|
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 TimePrinter(val)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ def lookup_function_lookup_test(val):
|
|||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return ("x=<" + str(self.val["x"]) +
|
return "x=<" + str(self.val["x"]) + "> y=<" + str(self.val["y"]) + ">"
|
||||||
"> y=<" + str(self.val["y"]) + ">")
|
|
||||||
|
|
||||||
typename = gdb.types.get_basic_type(val.type).tag
|
typename = gdb.types.get_basic_type(val.type).tag
|
||||||
# Note: typename could be None.
|
# Note: typename could be None.
|
||||||
@@ -37,7 +36,7 @@ def lookup_function_lookup_test(val):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class pp_s (object):
|
class pp_s(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
@@ -49,7 +48,7 @@ class pp_s (object):
|
|||||||
return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
||||||
|
|
||||||
|
|
||||||
class pp_ss (object):
|
class pp_ss(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
@@ -60,15 +59,18 @@ class pp_ss (object):
|
|||||||
def build_pretty_printer():
|
def build_pretty_printer():
|
||||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
|
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
|
||||||
|
|
||||||
pp.add_printer('struct s', '^struct s$', pp_s)
|
pp.add_printer("struct s", "^struct s$", pp_s)
|
||||||
pp.add_printer('s', '^s$', pp_s)
|
pp.add_printer("s", "^s$", pp_s)
|
||||||
|
|
||||||
# Use a lambda this time to exercise doing things this way.
|
# 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("struct ss", "^struct ss$", lambda val: pp_ss(val))
|
||||||
pp.add_printer('ss', '^ss$', lambda val: pp_ss(val))
|
pp.add_printer("ss", "^ss$", lambda val: pp_ss(val))
|
||||||
|
|
||||||
pp.add_printer('enum flag_enum', '^flag_enum$',
|
pp.add_printer(
|
||||||
gdb.printing.FlagEnumerationPrinter('enum flag_enum'))
|
"enum flag_enum",
|
||||||
|
"^flag_enum$",
|
||||||
|
gdb.printing.FlagEnumerationPrinter("enum flag_enum"),
|
||||||
|
)
|
||||||
|
|
||||||
return pp
|
return pp
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class TimePrinter:
|
|||||||
|
|
||||||
def build_pretty_printer():
|
def build_pretty_printer():
|
||||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-notag")
|
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-notag")
|
||||||
pp.add_printer('time_t', 'time_t', TimePrinter)
|
pp.add_printer("time_t", "time_t", TimePrinter)
|
||||||
return pp
|
return pp
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ def lookup_function_lookup_test(val):
|
|||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return ("x=<" + str(self.val["x"]) +
|
return "x=<" + str(self.val["x"]) + "> y=<" + str(self.val["y"]) + ">"
|
||||||
"> y=<" + str(self.val["y"]) + ">")
|
|
||||||
|
|
||||||
typename = gdb.types.get_basic_type(val.type).tag
|
typename = gdb.types.get_basic_type(val.type).tag
|
||||||
# Note: typename could be None.
|
# Note: typename could be None.
|
||||||
@@ -37,7 +36,7 @@ def lookup_function_lookup_test(val):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class pp_s1 (object):
|
class pp_s1(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
@@ -47,7 +46,7 @@ class pp_s1 (object):
|
|||||||
return "s1 a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
return "s1 a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
||||||
|
|
||||||
|
|
||||||
class pp_s2 (object):
|
class pp_s2(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
@@ -60,8 +59,8 @@ class pp_s2 (object):
|
|||||||
def build_pretty_printer1():
|
def build_pretty_printer1():
|
||||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
|
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
|
||||||
|
|
||||||
pp.add_printer('struct s', '^struct s$', pp_s1)
|
pp.add_printer("struct s", "^struct s$", pp_s1)
|
||||||
pp.add_printer('s', '^s$', pp_s1)
|
pp.add_printer("s", "^s$", pp_s1)
|
||||||
|
|
||||||
return pp
|
return pp
|
||||||
|
|
||||||
@@ -72,9 +71,10 @@ def build_pretty_printer2():
|
|||||||
# register_pretty_printer.
|
# register_pretty_printer.
|
||||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
|
pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
|
||||||
|
|
||||||
pp.add_printer('struct s', '^struct s$', pp_s2)
|
pp.add_printer("struct s", "^struct s$", pp_s2)
|
||||||
pp.add_printer('s', '^s$', pp_s2)
|
pp.add_printer("s", "^s$", pp_s2)
|
||||||
|
|
||||||
return pp
|
return pp
|
||||||
|
|
||||||
|
|
||||||
# Note: Registering the printers is done in the .exp file.
|
# Note: Registering the printers is done in the .exp file.
|
||||||
|
|||||||
@@ -19,73 +19,78 @@
|
|||||||
import re
|
import re
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
def _iterator (pointer, len):
|
|
||||||
|
def _iterator(pointer, len):
|
||||||
start = pointer
|
start = pointer
|
||||||
end = pointer + len
|
end = pointer + len
|
||||||
while pointer != end:
|
while pointer != end:
|
||||||
yield ('[%d]' % int (pointer - start), pointer.dereference())
|
yield ("[%d]" % int(pointer - start), pointer.dereference())
|
||||||
pointer += 1
|
pointer += 1
|
||||||
|
|
||||||
|
|
||||||
# Same as _iterator but can be told to raise an exception.
|
# Same as _iterator but can be told to raise an exception.
|
||||||
def _iterator_except (pointer, len):
|
def _iterator_except(pointer, len):
|
||||||
start = pointer
|
start = pointer
|
||||||
end = pointer + len
|
end = pointer + len
|
||||||
while pointer != end:
|
while pointer != end:
|
||||||
if exception_flag:
|
if exception_flag:
|
||||||
raise gdb.MemoryError ('hi bob')
|
raise gdb.MemoryError("hi bob")
|
||||||
yield ('[%d]' % int (pointer - start), pointer.dereference())
|
yield ("[%d]" % int(pointer - start), pointer.dereference())
|
||||||
pointer += 1
|
pointer += 1
|
||||||
|
|
||||||
|
|
||||||
# Test returning a Value from a printer.
|
# Test returning a Value from a printer.
|
||||||
class string_print (object):
|
class string_print(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return self.val['whybother']['contents']
|
return self.val["whybother"]["contents"]
|
||||||
|
|
||||||
|
|
||||||
# Test a class-based printer.
|
# Test a class-based printer.
|
||||||
class ContainerPrinter (object):
|
class ContainerPrinter(object):
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
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):
|
def children(self):
|
||||||
return _iterator(self.val['elements'], self.val['len'])
|
return _iterator(self.val["elements"], self.val["len"])
|
||||||
|
|
||||||
def display_hint (self):
|
def display_hint(self):
|
||||||
if (self.val['is_map_p'] and self.val['is_array_p']):
|
if self.val["is_map_p"] and self.val["is_array_p"]:
|
||||||
raise Exception ("invalid object state found in display_hint")
|
raise Exception("invalid object state found in display_hint")
|
||||||
|
|
||||||
if (self.val['is_map_p']):
|
if self.val["is_map_p"]:
|
||||||
return 'map'
|
return "map"
|
||||||
elif (self.val['is_array_p']):
|
elif self.val["is_array_p"]:
|
||||||
return 'array'
|
return "array"
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# Treats a container as array.
|
# Treats a container as array.
|
||||||
class ArrayPrinter (object):
|
class ArrayPrinter(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
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):
|
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.
|
# Flag to make NoStringContainerPrinter throw an exception.
|
||||||
exception_flag = False
|
exception_flag = False
|
||||||
|
|
||||||
# Test a printer where to_string is None
|
# Test a printer where to_string is None
|
||||||
class NoStringContainerPrinter (object):
|
class NoStringContainerPrinter(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
@@ -93,28 +98,29 @@ class NoStringContainerPrinter (object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def children(self):
|
def children(self):
|
||||||
return _iterator_except (self.val['elements'], self.val['len'])
|
return _iterator_except(self.val["elements"], self.val["len"])
|
||||||
|
|
||||||
|
|
||||||
# See ToStringReturnsValueWrapper.
|
# See ToStringReturnsValueWrapper.
|
||||||
class ToStringReturnsValueInner:
|
class ToStringReturnsValueInner:
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
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
|
# Test a printer that returns a gdb.Value in its to_string. That gdb.Value
|
||||||
# also has its own pretty-printer.
|
# also has its own pretty-printer.
|
||||||
class ToStringReturnsValueWrapper:
|
class ToStringReturnsValueWrapper:
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return self.val['inner']
|
return self.val["inner"]
|
||||||
|
|
||||||
class pp_s (object):
|
|
||||||
|
class pp_s(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
@@ -125,155 +131,174 @@ class pp_s (object):
|
|||||||
raise Exception("&a(%s) != b(%s)" % (str(a.address), str(b)))
|
raise Exception("&a(%s) != b(%s)" % (str(a.address), str(b)))
|
||||||
return " a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
return " a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
|
||||||
|
|
||||||
class pp_ss (object):
|
|
||||||
|
class pp_ss(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
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_sss (object):
|
|
||||||
|
class pp_sss(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
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
|
self.val = val
|
||||||
|
|
||||||
def to_string (self):
|
def to_string(self):
|
||||||
return "pp value variable is: " + str (self.val['value'])
|
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
|
self.val = val
|
||||||
|
|
||||||
def to_string (self):
|
def to_string(self):
|
||||||
return "pp class name: " + self.val.type.tag
|
return "pp class name: " + self.val.type.tag
|
||||||
|
|
||||||
class pp_nullstr (object):
|
|
||||||
|
class pp_nullstr(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
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"
|
"Print a std::basic_string of some kind"
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
len = self.val['length']
|
len = self.val["length"]
|
||||||
return self.val['null_str'].string (gdb.target_charset(), length = len)
|
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
|
pp_ls_encoding = None
|
||||||
|
|
||||||
class pp_ls (object):
|
|
||||||
|
class pp_ls(object):
|
||||||
"Print a std::basic_string of some kind"
|
"Print a std::basic_string of some kind"
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
length = self.val['len']
|
length = self.val["len"]
|
||||||
if pp_ls_encoding is not None:
|
if pp_ls_encoding is not None:
|
||||||
if length >= 0:
|
if length >= 0:
|
||||||
return self.val['lazy_str'].lazy_string(
|
return self.val["lazy_str"].lazy_string(
|
||||||
encoding = pp_ls_encoding,
|
encoding=pp_ls_encoding, length=length
|
||||||
length = length)
|
)
|
||||||
else:
|
else:
|
||||||
return self.val['lazy_str'].lazy_string(
|
return self.val["lazy_str"].lazy_string(encoding=pp_ls_encoding)
|
||||||
encoding = pp_ls_encoding)
|
|
||||||
else:
|
else:
|
||||||
if length >= 0:
|
if length >= 0:
|
||||||
return self.val['lazy_str'].lazy_string(length = length)
|
return self.val["lazy_str"].lazy_string(length=length)
|
||||||
else:
|
else:
|
||||||
return self.val['lazy_str'].lazy_string()
|
return self.val["lazy_str"].lazy_string()
|
||||||
|
|
||||||
def display_hint (self):
|
def display_hint(self):
|
||||||
return 'string'
|
return "string"
|
||||||
|
|
||||||
class pp_hint_error (object):
|
|
||||||
|
class pp_hint_error(object):
|
||||||
"Throw error from display_hint"
|
"Throw error from display_hint"
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return 'hint_error_val'
|
return "hint_error_val"
|
||||||
|
|
||||||
def display_hint (self):
|
def display_hint(self):
|
||||||
raise Exception("hint failed")
|
raise Exception("hint failed")
|
||||||
|
|
||||||
class pp_children_as_list (object):
|
|
||||||
|
class pp_children_as_list(object):
|
||||||
"Throw error from display_hint"
|
"Throw error from display_hint"
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return 'children_as_list_val'
|
return "children_as_list_val"
|
||||||
|
|
||||||
def children (self):
|
def children(self):
|
||||||
return [('one', 1)]
|
return [("one", 1)]
|
||||||
|
|
||||||
class pp_outer (object):
|
|
||||||
|
class pp_outer(object):
|
||||||
"Print struct outer"
|
"Print struct outer"
|
||||||
|
|
||||||
def __init__ (self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string (self):
|
def to_string(self):
|
||||||
return "x = %s" % self.val['x']
|
return "x = %s" % self.val["x"]
|
||||||
|
|
||||||
def children (self):
|
def children(self):
|
||||||
yield 's', self.val['s']
|
yield "s", self.val["s"]
|
||||||
yield 'x', self.val['x']
|
yield "x", self.val["x"]
|
||||||
|
|
||||||
class MemoryErrorString (object):
|
|
||||||
|
class MemoryErrorString(object):
|
||||||
"Raise an error"
|
"Raise an error"
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
raise gdb.MemoryError ("Cannot access memory.")
|
raise gdb.MemoryError("Cannot access memory.")
|
||||||
|
|
||||||
def display_hint (self):
|
def display_hint(self):
|
||||||
return 'string'
|
return "string"
|
||||||
|
|
||||||
class pp_eval_type (object):
|
|
||||||
|
class pp_eval_type(object):
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
gdb.execute("bt", to_string=True)
|
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):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return "type=%s, val=%s" % (self.val.type, int(self.val))
|
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"
|
"A printer without a to_string method"
|
||||||
|
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
|
|
||||||
def children(self):
|
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."
|
"Look-up and return a pretty-printer that can print val."
|
||||||
|
|
||||||
# Get the type.
|
# Get the type.
|
||||||
@@ -281,10 +306,10 @@ def lookup_function (val):
|
|||||||
|
|
||||||
# If it points to a reference, get the reference.
|
# If it points to a reference, get the reference.
|
||||||
if type.code == gdb.TYPE_CODE_REF:
|
if type.code == gdb.TYPE_CODE_REF:
|
||||||
type = type.target ()
|
type = type.target()
|
||||||
|
|
||||||
# Get the unqualified type, stripped of typedefs.
|
# 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
|
typename = type.tag
|
||||||
@@ -296,21 +321,24 @@ def lookup_function (val):
|
|||||||
# if a printer is registered for that type. Return an
|
# if a printer is registered for that type. Return an
|
||||||
# instantiation of the printer if found.
|
# instantiation of the printer if found.
|
||||||
for function in pretty_printers_dict:
|
for function in pretty_printers_dict:
|
||||||
if function.match (typename):
|
if function.match(typename):
|
||||||
return pretty_printers_dict[function] (val)
|
return pretty_printers_dict[function](val)
|
||||||
|
|
||||||
# Cannot find a pretty printer. Return None.
|
# Cannot find a pretty printer. Return None.
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def disable_lookup_function ():
|
|
||||||
|
def disable_lookup_function():
|
||||||
lookup_function.enabled = False
|
lookup_function.enabled = False
|
||||||
|
|
||||||
def enable_lookup_function ():
|
|
||||||
|
def enable_lookup_function():
|
||||||
lookup_function.enabled = True
|
lookup_function.enabled = True
|
||||||
|
|
||||||
|
|
||||||
# Lookup a printer for VAL in the typedefs dict.
|
# 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)."
|
"Look-up and return a pretty-printer that can print val (typedefs)."
|
||||||
|
|
||||||
# Get the type.
|
# Get the type.
|
||||||
@@ -323,72 +351,82 @@ def lookup_typedefs_function (val):
|
|||||||
# printer is registered for that type. Return an instantiation of
|
# printer is registered for that type. Return an instantiation of
|
||||||
# the printer if found.
|
# the printer if found.
|
||||||
for function in typedefs_pretty_printers_dict:
|
for function in typedefs_pretty_printers_dict:
|
||||||
if function.match (type.name):
|
if function.match(type.name):
|
||||||
return typedefs_pretty_printers_dict[function] (val)
|
return typedefs_pretty_printers_dict[function](val)
|
||||||
|
|
||||||
# Cannot find a pretty printer.
|
# Cannot find a pretty printer.
|
||||||
return None
|
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
|
def register_pretty_printers():
|
||||||
pretty_printers_dict[re.compile ('^ss$')] = pp_ss
|
pretty_printers_dict[re.compile("^struct s$")] = pp_s
|
||||||
pretty_printers_dict[re.compile ('^const S &$')] = pp_s
|
pretty_printers_dict[re.compile("^s$")] = pp_s
|
||||||
pretty_printers_dict[re.compile ('^SSS$')] = pp_sss
|
pretty_printers_dict[re.compile("^S$")] = pp_s
|
||||||
|
|
||||||
pretty_printers_dict[re.compile ('^VirtualTest$')] = pp_multiple_virtual
|
pretty_printers_dict[re.compile("^struct ss$")] = pp_ss
|
||||||
pretty_printers_dict[re.compile ('^Vbase1$')] = pp_vbase1
|
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 ('^struct nullstr$')] = pp_nullstr
|
pretty_printers_dict[re.compile("^VirtualTest$")] = pp_multiple_virtual
|
||||||
pretty_printers_dict[re.compile ('^nullstr$')] = pp_nullstr
|
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
|
||||||
|
|
||||||
# Note that we purposely omit the typedef names here.
|
# Note that we purposely omit the typedef names here.
|
||||||
# Printer lookup is based on canonical name.
|
# Printer lookup is based on canonical name.
|
||||||
# However, we do need both tagged and untagged variants, to handle
|
# However, we do need both tagged and untagged variants, to handle
|
||||||
# both the C and C++ cases.
|
# both the C and C++ cases.
|
||||||
pretty_printers_dict[re.compile ('^struct string_repr$')] = string_print
|
pretty_printers_dict[re.compile("^struct string_repr$")] = string_print
|
||||||
pretty_printers_dict[re.compile ('^struct container$')] = ContainerPrinter
|
pretty_printers_dict[re.compile("^struct container$")] = ContainerPrinter
|
||||||
pretty_printers_dict[re.compile ('^struct justchildren$')] = NoStringContainerPrinter
|
pretty_printers_dict[re.compile("^struct justchildren$")] = NoStringContainerPrinter
|
||||||
pretty_printers_dict[re.compile ('^string_repr$')] = string_print
|
pretty_printers_dict[re.compile("^string_repr$")] = string_print
|
||||||
pretty_printers_dict[re.compile ('^container$')] = ContainerPrinter
|
pretty_printers_dict[re.compile("^container$")] = ContainerPrinter
|
||||||
pretty_printers_dict[re.compile ('^justchildren$')] = NoStringContainerPrinter
|
pretty_printers_dict[re.compile("^justchildren$")] = NoStringContainerPrinter
|
||||||
|
|
||||||
pretty_printers_dict[re.compile ('^struct to_string_returns_value_inner$')] = ToStringReturnsValueInner
|
pretty_printers_dict[
|
||||||
pretty_printers_dict[re.compile ('^to_string_returns_value_inner$')] = ToStringReturnsValueInner
|
re.compile("^struct to_string_returns_value_inner$")
|
||||||
pretty_printers_dict[re.compile ('^struct to_string_returns_value_wrapper$')] = ToStringReturnsValueWrapper
|
] = ToStringReturnsValueInner
|
||||||
pretty_printers_dict[re.compile ('^to_string_returns_value_wrapper$')] = ToStringReturnsValueWrapper
|
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("^struct ns$")] = pp_ns
|
||||||
pretty_printers_dict[re.compile ('^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("^struct lazystring$")] = pp_ls
|
||||||
pretty_printers_dict[re.compile ('^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("^struct outerstruct$")] = pp_outer
|
||||||
pretty_printers_dict[re.compile ('^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("^struct hint_error$")] = pp_hint_error
|
||||||
pretty_printers_dict[re.compile ('^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("^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("^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.
|
# Dict for struct types with typedefs fully stripped.
|
||||||
pretty_printers_dict = {}
|
pretty_printers_dict = {}
|
||||||
# Dict for typedef types.
|
# Dict for typedef types.
|
||||||
typedefs_pretty_printers_dict = {}
|
typedefs_pretty_printers_dict = {}
|
||||||
|
|
||||||
register_pretty_printers ()
|
register_pretty_printers()
|
||||||
gdb.pretty_printers.append (lookup_function)
|
gdb.pretty_printers.append(lookup_function)
|
||||||
gdb.pretty_printers.append (lookup_typedefs_function)
|
gdb.pretty_printers.append(lookup_typedefs_function)
|
||||||
|
|||||||
@@ -28,22 +28,23 @@
|
|||||||
import gdb
|
import gdb
|
||||||
from gdb.unwinder import Unwinder
|
from gdb.unwinder import Unwinder
|
||||||
|
|
||||||
|
|
||||||
class TestUnwinder(Unwinder):
|
class TestUnwinder(Unwinder):
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def reset_count (cls):
|
def reset_count(cls):
|
||||||
cls.count = 0
|
cls.count = 0
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def inc_count (cls):
|
def inc_count(cls):
|
||||||
cls.count += 1
|
cls.count += 1
|
||||||
|
|
||||||
test = 'check_undefined_symbol'
|
test = "check_undefined_symbol"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def set_test (cls, test) :
|
def set_test(cls, test):
|
||||||
cls.test = test
|
cls.test = test
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -59,19 +60,19 @@ class TestUnwinder(Unwinder):
|
|||||||
self.recurse_level += 1
|
self.recurse_level += 1
|
||||||
TestUnwinder.inc_count()
|
TestUnwinder.inc_count()
|
||||||
|
|
||||||
if TestUnwinder.test == 'check_user_reg_pc' :
|
if TestUnwinder.test == "check_user_reg_pc":
|
||||||
|
|
||||||
pc = pending_frame.read_register('pc')
|
pc = pending_frame.read_register("pc")
|
||||||
pc_as_int = int(pc.cast(gdb.lookup_type('int')))
|
pc_as_int = int(pc.cast(gdb.lookup_type("int")))
|
||||||
# gdb.write("In unwinder: pc=%x\n" % pc_as_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 = gdb.parse_and_eval("$pc")
|
||||||
pc_as_int = int(pc.cast(gdb.lookup_type('int')))
|
pc_as_int = int(pc.cast(gdb.lookup_type("int")))
|
||||||
# gdb.write("In unwinder: pc=%x\n" % pc_as_int)
|
# gdb.write("In unwinder: pc=%x\n" % pc_as_int)
|
||||||
|
|
||||||
elif TestUnwinder.test == 'check_undefined_symbol' :
|
elif TestUnwinder.test == "check_undefined_symbol":
|
||||||
|
|
||||||
try:
|
try:
|
||||||
val = gdb.parse_and_eval("undefined_symbol")
|
val = gdb.parse_and_eval("undefined_symbol")
|
||||||
@@ -83,5 +84,6 @@ class TestUnwinder(Unwinder):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
gdb.unwinder.register_unwinder(None, TestUnwinder(), True)
|
gdb.unwinder.register_unwinder(None, TestUnwinder(), True)
|
||||||
gdb.write("Python script imported\n")
|
gdb.write("Python script imported\n")
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
class pp_ss:
|
class pp_ss:
|
||||||
def __init__(self, val):
|
def __init__(self, val):
|
||||||
self.val = val
|
self.val = val
|
||||||
@@ -24,7 +25,8 @@ class pp_ss:
|
|||||||
def to_string(self):
|
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"]) + ">"
|
||||||
|
|
||||||
def lookup_function (val):
|
|
||||||
|
def lookup_function(val):
|
||||||
"Look-up and return a pretty-printer that can print val."
|
"Look-up and return a pretty-printer that can print val."
|
||||||
|
|
||||||
# Get the type.
|
# Get the type.
|
||||||
@@ -32,10 +34,10 @@ def lookup_function (val):
|
|||||||
|
|
||||||
# If it points to a reference, get the reference.
|
# If it points to a reference, get the reference.
|
||||||
if type.code == gdb.TYPE_CODE_REF:
|
if type.code == gdb.TYPE_CODE_REF:
|
||||||
type = type.target ()
|
type = type.target()
|
||||||
|
|
||||||
# Get the unqualified type, stripped of typedefs.
|
# 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
|
typename = type.tag
|
||||||
@@ -47,17 +49,19 @@ def lookup_function (val):
|
|||||||
# if a printer is registered for that type. Return an
|
# if a printer is registered for that type. Return an
|
||||||
# instantiation of the printer if found.
|
# instantiation of the printer if found.
|
||||||
for function in pretty_printers_dict:
|
for function in pretty_printers_dict:
|
||||||
if function.match (typename):
|
if function.match(typename):
|
||||||
return pretty_printers_dict[function] (val)
|
return pretty_printers_dict[function](val)
|
||||||
|
|
||||||
# Cannot find a pretty printer. Return None.
|
# Cannot find a pretty printer. Return None.
|
||||||
|
|
||||||
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 = {}
|
pretty_printers_dict = {}
|
||||||
|
|
||||||
register_pretty_printers ()
|
register_pretty_printers()
|
||||||
gdb.current_progspace().pretty_printers.append (lookup_function)
|
gdb.current_progspace().pretty_printers.append(lookup_function)
|
||||||
|
|||||||
@@ -15,21 +15,24 @@
|
|||||||
|
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
|
|
||||||
class Recognizer(object):
|
class Recognizer(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
|
|
||||||
def recognize(self, type_obj):
|
def recognize(self, type_obj):
|
||||||
if type_obj.tag == 'basic_string':
|
if type_obj.tag == "basic_string":
|
||||||
return 'string'
|
return "string"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class StringTypePrinter(object):
|
class StringTypePrinter(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.name = 'string'
|
self.name = "string"
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
|
|
||||||
def instantiate(self):
|
def instantiate(self):
|
||||||
return Recognizer()
|
return Recognizer()
|
||||||
|
|
||||||
|
|
||||||
gdb.type_printers.append(StringTypePrinter())
|
gdb.type_printers.append(StringTypePrinter())
|
||||||
|
|||||||
@@ -23,49 +23,50 @@ from gdb.unwinder import Unwinder
|
|||||||
|
|
||||||
apb_global = None
|
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."""
|
the unwinding process."""
|
||||||
|
|
||||||
class frame_id (object):
|
class frame_id(object):
|
||||||
""" Basic frame id."""
|
"""Basic frame id."""
|
||||||
|
|
||||||
def __init__ (self, sp, pc):
|
def __init__(self, sp, pc):
|
||||||
""" Create the frame id."""
|
"""Create the frame id."""
|
||||||
self.sp = sp
|
self.sp = sp
|
||||||
self.pc = pc
|
self.pc = pc
|
||||||
|
|
||||||
def __init__ (self):
|
def __init__(self):
|
||||||
"""Create the unwinder."""
|
"""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.void_ptr_t = gdb.lookup_type("void").pointer()
|
||||||
self.regs = None
|
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
|
"""Return a list of register names that should be read. Only
|
||||||
gathers the list once, then caches the result."""
|
gathers the list once, then caches the result."""
|
||||||
if (self.regs != None):
|
if self.regs != None:
|
||||||
return self.regs
|
return self.regs
|
||||||
|
|
||||||
# Collect the names of all registers to read.
|
# Collect the names of all registers to read.
|
||||||
self.regs = list (pending_frame.architecture ()
|
self.regs = list(pending_frame.architecture().register_names())
|
||||||
.register_names ())
|
|
||||||
|
|
||||||
return self.regs
|
return self.regs
|
||||||
|
|
||||||
def __call__ (self, pending_frame):
|
def __call__(self, pending_frame):
|
||||||
"""Actually performs the unwind, or at least sniffs this frame
|
"""Actually performs the unwind, or at least sniffs this frame
|
||||||
to see if the unwinder should claim it, which is never does."""
|
to see if the unwinder should claim it, which is never does."""
|
||||||
try:
|
try:
|
||||||
for r in (self.get_regs (pending_frame)):
|
for r in self.get_regs(pending_frame):
|
||||||
v = pending_frame.read_register (r).cast (self.void_ptr_t)
|
v = pending_frame.read_register(r).cast(self.void_ptr_t)
|
||||||
except:
|
except:
|
||||||
print ("Dummy unwinder, exception")
|
print("Dummy unwinder, exception")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
return None
|
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
|
import gdb.types
|
||||||
from gdb.unwinder import Unwinder, register_unwinder
|
from gdb.unwinder import Unwinder, register_unwinder
|
||||||
|
|
||||||
|
|
||||||
class TestGlobalUnwinder(Unwinder):
|
class TestGlobalUnwinder(Unwinder):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(TestGlobalUnwinder, self).__init__("global_unwinder")
|
super(TestGlobalUnwinder, self).__init__("global_unwinder")
|
||||||
@@ -27,6 +28,7 @@ class TestGlobalUnwinder(Unwinder):
|
|||||||
print("%s called" % self.name)
|
print("%s called" % self.name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class TestProgspaceUnwinder(Unwinder):
|
class TestProgspaceUnwinder(Unwinder):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
super(TestProgspaceUnwinder, self).__init__("%s_ps_unwinder" % name)
|
super(TestProgspaceUnwinder, self).__init__("%s_ps_unwinder" % name)
|
||||||
@@ -35,6 +37,7 @@ class TestProgspaceUnwinder(Unwinder):
|
|||||||
print("%s called" % self.name)
|
print("%s called" % self.name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class TestObjfileUnwinder(Unwinder):
|
class TestObjfileUnwinder(Unwinder):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
super(TestObjfileUnwinder, self).__init__("%s_obj_unwinder" % name)
|
super(TestObjfileUnwinder, self).__init__("%s_obj_unwinder" % name)
|
||||||
@@ -44,7 +47,6 @@ class TestObjfileUnwinder(Unwinder):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gdb.unwinder.register_unwinder(None, TestGlobalUnwinder())
|
gdb.unwinder.register_unwinder(None, TestGlobalUnwinder())
|
||||||
saw_runtime_error = False
|
saw_runtime_error = False
|
||||||
try:
|
try:
|
||||||
@@ -54,6 +56,7 @@ except RuntimeError:
|
|||||||
if not saw_runtime_error:
|
if not saw_runtime_error:
|
||||||
raise RuntimeError("Missing runtime error from register_unwinder.")
|
raise RuntimeError("Missing runtime error from register_unwinder.")
|
||||||
gdb.unwinder.register_unwinder(None, TestGlobalUnwinder(), replace=True)
|
gdb.unwinder.register_unwinder(None, TestGlobalUnwinder(), replace=True)
|
||||||
gdb.unwinder.register_unwinder(gdb.current_progspace(),
|
gdb.unwinder.register_unwinder(
|
||||||
TestProgspaceUnwinder("py_unwind_maint"))
|
gdb.current_progspace(), TestProgspaceUnwinder("py_unwind_maint")
|
||||||
|
)
|
||||||
print("Python script imported")
|
print("Python script imported")
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
import gdb
|
import gdb
|
||||||
from gdb.unwinder import Unwinder
|
from gdb.unwinder import Unwinder
|
||||||
|
|
||||||
class FrameId(object):
|
|
||||||
|
|
||||||
|
class FrameId(object):
|
||||||
def __init__(self, sp, pc):
|
def __init__(self, sp, pc):
|
||||||
self._sp = sp
|
self._sp = sp
|
||||||
self._pc = pc
|
self._pc = pc
|
||||||
@@ -30,6 +30,7 @@ class FrameId(object):
|
|||||||
def pc(self):
|
def pc(self):
|
||||||
return self._pc
|
return self._pc
|
||||||
|
|
||||||
|
|
||||||
class TestUnwinder(Unwinder):
|
class TestUnwinder(Unwinder):
|
||||||
AMD64_RBP = 6
|
AMD64_RBP = 6
|
||||||
AMD64_RSP = 7
|
AMD64_RSP = 7
|
||||||
@@ -42,9 +43,9 @@ class TestUnwinder(Unwinder):
|
|||||||
self._last_arch = None
|
self._last_arch = None
|
||||||
|
|
||||||
# Update the register descriptor AMD64_RIP based on ARCH.
|
# Update the register descriptor AMD64_RIP based on ARCH.
|
||||||
def _update_register_descriptors (self, arch):
|
def _update_register_descriptors(self, arch):
|
||||||
if (self._last_arch != arch):
|
if self._last_arch != arch:
|
||||||
TestUnwinder.AMD64_RIP = arch.registers ().find ("rip")
|
TestUnwinder.AMD64_RIP = arch.registers().find("rip")
|
||||||
self._last_arch = arch
|
self._last_arch = arch
|
||||||
|
|
||||||
def _read_word(self, address):
|
def _read_word(self, address):
|
||||||
@@ -79,12 +80,12 @@ class TestUnwinder(Unwinder):
|
|||||||
# Check that we can access the architecture of the pending
|
# Check that we can access the architecture of the pending
|
||||||
# frame, and that this is the same architecture as for the
|
# frame, and that this is the same architecture as for the
|
||||||
# currently selected inferior.
|
# currently selected inferior.
|
||||||
inf_arch = gdb.selected_inferior ().architecture ()
|
inf_arch = gdb.selected_inferior().architecture()
|
||||||
frame_arch = pending_frame.architecture ()
|
frame_arch = pending_frame.architecture()
|
||||||
if (inf_arch != frame_arch):
|
if inf_arch != frame_arch:
|
||||||
raise gdb.GdbError ("architecture mismatch")
|
raise gdb.GdbError("architecture mismatch")
|
||||||
|
|
||||||
self._update_register_descriptors (frame_arch)
|
self._update_register_descriptors(frame_arch)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# NOTE: the registers in Unwinder API can be referenced
|
# NOTE: the registers in Unwinder API can be referenced
|
||||||
@@ -102,15 +103,16 @@ class TestUnwinder(Unwinder):
|
|||||||
|
|
||||||
frame_id = FrameId(
|
frame_id = FrameId(
|
||||||
pending_frame.read_register(TestUnwinder.AMD64_RSP),
|
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 = pending_frame.create_unwind_info(frame_id)
|
||||||
unwind_info.add_saved_register(TestUnwinder.AMD64_RBP,
|
unwind_info.add_saved_register(TestUnwinder.AMD64_RBP, previous_bp)
|
||||||
previous_bp)
|
|
||||||
unwind_info.add_saved_register("rip", previous_ip)
|
unwind_info.add_saved_register("rip", previous_ip)
|
||||||
unwind_info.add_saved_register("rsp", previous_sp)
|
unwind_info.add_saved_register("rsp", previous_sp)
|
||||||
return unwind_info
|
return unwind_info
|
||||||
except (gdb.error, RuntimeError):
|
except (gdb.error, RuntimeError):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
gdb.unwinder.register_unwinder(None, TestUnwinder(), True)
|
gdb.unwinder.register_unwinder(None, TestUnwinder(), True)
|
||||||
print("Python script imported")
|
print("Python script imported")
|
||||||
|
|||||||
@@ -25,52 +25,55 @@ from gdb.xmethod import SimpleXMethodMatcher
|
|||||||
|
|
||||||
|
|
||||||
def A_plus_A(obj, opr):
|
def A_plus_A(obj, opr):
|
||||||
print('From Python <A_plus_A>:')
|
print("From Python <A_plus_A>:")
|
||||||
return obj['a'] + opr['a']
|
return obj["a"] + opr["a"]
|
||||||
|
|
||||||
|
|
||||||
def plus_plus_A(obj):
|
def plus_plus_A(obj):
|
||||||
print('From Python <plus_plus_A>:')
|
print("From Python <plus_plus_A>:")
|
||||||
return obj['a'] + 1
|
return obj["a"] + 1
|
||||||
|
|
||||||
|
|
||||||
def A_geta(obj):
|
def A_geta(obj):
|
||||||
print('From Python <A_geta>:')
|
print("From Python <A_geta>:")
|
||||||
return obj['a']
|
return obj["a"]
|
||||||
|
|
||||||
|
|
||||||
def A_getarrayind(obj, index):
|
def A_getarrayind(obj, index):
|
||||||
print('From Python <A_getarrayind>:')
|
print("From Python <A_getarrayind>:")
|
||||||
return obj['array'][index]
|
return obj["array"][index]
|
||||||
|
|
||||||
|
|
||||||
def A_indexoper(obj, index):
|
def A_indexoper(obj, index):
|
||||||
return obj['array'][index].reference_value()
|
return obj["array"][index].reference_value()
|
||||||
|
|
||||||
|
|
||||||
def B_indexoper(obj, index):
|
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_A = gdb.parse_and_eval("(dop::A *) 0").type.target()
|
||||||
type_B = gdb.parse_and_eval('(dop::B *) 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_int = gdb.parse_and_eval("(int *) 0").type.target()
|
||||||
|
|
||||||
|
|
||||||
# The E class matcher and worker test two things:
|
# The E class matcher and worker test two things:
|
||||||
# 1. xmethod returning None.
|
# 1. xmethod returning None.
|
||||||
# 2. Matcher returning a list of workers.
|
# 2. Matcher returning a list of workers.
|
||||||
|
|
||||||
|
|
||||||
class E_method_char_worker(XMethodWorker):
|
class E_method_char_worker(XMethodWorker):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_arg_types(self):
|
def get_arg_types(self):
|
||||||
return gdb.lookup_type('char')
|
return gdb.lookup_type("char")
|
||||||
|
|
||||||
def get_result_type(self, obj, arg):
|
def get_result_type(self, obj, arg):
|
||||||
return gdb.lookup_type('void')
|
return gdb.lookup_type("void")
|
||||||
|
|
||||||
def __call__(self, obj, arg):
|
def __call__(self, obj, arg):
|
||||||
print('From Python <E_method_char>')
|
print("From Python <E_method_char>")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -79,25 +82,25 @@ class E_method_int_worker(XMethodWorker):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def get_arg_types(self):
|
def get_arg_types(self):
|
||||||
return gdb.lookup_type('int')
|
return gdb.lookup_type("int")
|
||||||
|
|
||||||
# Note: get_result_type method elided on purpose
|
# Note: get_result_type method elided on purpose
|
||||||
|
|
||||||
def __call__(self, obj, arg):
|
def __call__(self, obj, arg):
|
||||||
print('From Python <E_method_int>')
|
print("From Python <E_method_int>")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class E_method_matcher(XMethodMatcher):
|
class E_method_matcher(XMethodMatcher):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
XMethodMatcher.__init__(self, 'E_methods')
|
XMethodMatcher.__init__(self, "E_methods")
|
||||||
self.methods = [XMethod('method_int'), XMethod('method_char')]
|
self.methods = [XMethod("method_int"), XMethod("method_char")]
|
||||||
|
|
||||||
def match(self, class_type, method_name):
|
def match(self, class_type, method_name):
|
||||||
class_tag = class_type.unqualified().tag
|
class_tag = class_type.unqualified().tag
|
||||||
if not re.match('^dop::E$', class_tag):
|
if not re.match("^dop::E$", class_tag):
|
||||||
return None
|
return None
|
||||||
if not re.match('^method$', method_name):
|
if not re.match("^method$", method_name):
|
||||||
return None
|
return None
|
||||||
workers = []
|
workers = []
|
||||||
if self.methods[0].enabled:
|
if self.methods[0].enabled:
|
||||||
@@ -111,6 +114,7 @@ class E_method_matcher(XMethodMatcher):
|
|||||||
# xmethod matchers and workers for template classes and template
|
# xmethod matchers and workers for template classes and template
|
||||||
# methods.
|
# methods.
|
||||||
|
|
||||||
|
|
||||||
class G_size_diff_worker(XMethodWorker):
|
class G_size_diff_worker(XMethodWorker):
|
||||||
def __init__(self, class_template_type, method_template_type):
|
def __init__(self, class_template_type, method_template_type):
|
||||||
self._class_template_type = class_template_type
|
self._class_template_type = class_template_type
|
||||||
@@ -120,9 +124,8 @@ class G_size_diff_worker(XMethodWorker):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def __call__(self, obj):
|
def __call__(self, obj):
|
||||||
print('From Python G<>::size_diff()')
|
print("From Python G<>::size_diff()")
|
||||||
return (self._method_template_type.sizeof -
|
return self._method_template_type.sizeof - self._class_template_type.sizeof
|
||||||
self._class_template_type.sizeof)
|
|
||||||
|
|
||||||
|
|
||||||
class G_size_mul_worker(XMethodWorker):
|
class G_size_mul_worker(XMethodWorker):
|
||||||
@@ -134,7 +137,7 @@ class G_size_mul_worker(XMethodWorker):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def __call__(self, obj):
|
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
|
return self._class_template_type.sizeof * self._method_template_val
|
||||||
|
|
||||||
|
|
||||||
@@ -147,16 +150,14 @@ class G_mul_worker(XMethodWorker):
|
|||||||
return self._method_template_type
|
return self._method_template_type
|
||||||
|
|
||||||
def __call__(self, obj, arg):
|
def __call__(self, obj, arg):
|
||||||
print('From Python G<>::mul()')
|
print("From Python G<>::mul()")
|
||||||
return obj['t'] * arg
|
return obj["t"] * arg
|
||||||
|
|
||||||
|
|
||||||
class G_methods_matcher(XMethodMatcher):
|
class G_methods_matcher(XMethodMatcher):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
XMethodMatcher.__init__(self, 'G_methods')
|
XMethodMatcher.__init__(self, "G_methods")
|
||||||
self.methods = [XMethod('size_diff'),
|
self.methods = [XMethod("size_diff"), XMethod("size_mul"), XMethod("mul")]
|
||||||
XMethod('size_mul'),
|
|
||||||
XMethod('mul')]
|
|
||||||
|
|
||||||
def _is_enabled(self, name):
|
def _is_enabled(self, name):
|
||||||
for method in self.methods:
|
for method in self.methods:
|
||||||
@@ -165,16 +166,15 @@ class G_methods_matcher(XMethodMatcher):
|
|||||||
|
|
||||||
def match(self, class_type, method_name):
|
def match(self, class_type, method_name):
|
||||||
class_tag = class_type.unqualified().tag
|
class_tag = class_type.unqualified().tag
|
||||||
if not re.match('^dop::G<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$',
|
if not re.match("^dop::G<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$", class_tag):
|
||||||
class_tag):
|
|
||||||
return None
|
return None
|
||||||
t_name = class_tag[7:-1]
|
t_name = class_tag[7:-1]
|
||||||
try:
|
try:
|
||||||
t_type = gdb.lookup_type(t_name)
|
t_type = gdb.lookup_type(t_name)
|
||||||
except gdb.error:
|
except gdb.error:
|
||||||
return None
|
return None
|
||||||
if re.match('^size_diff<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$', method_name):
|
if re.match("^size_diff<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$", method_name):
|
||||||
if not self._is_enabled('size_diff'):
|
if not self._is_enabled("size_diff"):
|
||||||
return None
|
return None
|
||||||
t1_name = method_name[10:-1]
|
t1_name = method_name[10:-1]
|
||||||
try:
|
try:
|
||||||
@@ -182,13 +182,13 @@ class G_methods_matcher(XMethodMatcher):
|
|||||||
return G_size_diff_worker(t_type, t1_type)
|
return G_size_diff_worker(t_type, t1_type)
|
||||||
except gdb.error:
|
except gdb.error:
|
||||||
return None
|
return None
|
||||||
if re.match('^size_mul<[ ]*[0-9]+[ ]*>$', method_name):
|
if re.match("^size_mul<[ ]*[0-9]+[ ]*>$", method_name):
|
||||||
if not self._is_enabled('size_mul'):
|
if not self._is_enabled("size_mul"):
|
||||||
return None
|
return None
|
||||||
m_val = int(method_name[9:-1])
|
m_val = int(method_name[9:-1])
|
||||||
return G_size_mul_worker(t_type, m_val)
|
return G_size_mul_worker(t_type, m_val)
|
||||||
if re.match('^mul<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$', method_name):
|
if re.match("^mul<[ ]*[_a-zA-Z][ _a-zA-Z0-9]*>$", method_name):
|
||||||
if not self._is_enabled('mul'):
|
if not self._is_enabled("mul"):
|
||||||
return None
|
return None
|
||||||
t1_name = method_name[4:-1]
|
t1_name = method_name[4:-1]
|
||||||
try:
|
try:
|
||||||
@@ -199,41 +199,29 @@ class G_methods_matcher(XMethodMatcher):
|
|||||||
|
|
||||||
|
|
||||||
global_dm_list = [
|
global_dm_list = [
|
||||||
SimpleXMethodMatcher(r'A_plus_A',
|
SimpleXMethodMatcher(
|
||||||
r'^dop::A$',
|
r"A_plus_A",
|
||||||
r'operator\+',
|
r"^dop::A$",
|
||||||
|
r"operator\+",
|
||||||
A_plus_A,
|
A_plus_A,
|
||||||
# This is a replacement, hence match the arg type
|
# This is a replacement, hence match the arg type
|
||||||
# exactly!
|
# exactly!
|
||||||
type_A.const().reference()),
|
type_A.const().reference(),
|
||||||
SimpleXMethodMatcher(r'plus_plus_A',
|
),
|
||||||
r'^dop::A$',
|
SimpleXMethodMatcher(r"plus_plus_A", r"^dop::A$", r"operator\+\+", plus_plus_A),
|
||||||
r'operator\+\+',
|
SimpleXMethodMatcher(r"A_geta", r"^dop::A$", r"^geta$", A_geta),
|
||||||
plus_plus_A),
|
SimpleXMethodMatcher(
|
||||||
SimpleXMethodMatcher(r'A_geta',
|
r"A_getarrayind", r"^dop::A$", r"^getarrayind$", A_getarrayind, type_int
|
||||||
r'^dop::A$',
|
),
|
||||||
r'^geta$',
|
SimpleXMethodMatcher(
|
||||||
A_geta),
|
r"A_indexoper", r"^dop::A$", r"operator\[\]", A_indexoper, type_int
|
||||||
SimpleXMethodMatcher(r'A_getarrayind',
|
),
|
||||||
r'^dop::A$',
|
SimpleXMethodMatcher(
|
||||||
r'^getarrayind$',
|
r"B_indexoper", r"^dop::B$", r"operator\[\]", B_indexoper, type_int
|
||||||
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:
|
for matcher in global_dm_list:
|
||||||
gdb.xmethod.register_xmethod_matcher(gdb, matcher)
|
gdb.xmethod.register_xmethod_matcher(gdb, matcher)
|
||||||
gdb.xmethod.register_xmethod_matcher(gdb.current_progspace(),
|
gdb.xmethod.register_xmethod_matcher(gdb.current_progspace(), G_methods_matcher())
|
||||||
G_methods_matcher())
|
gdb.xmethod.register_xmethod_matcher(gdb.current_progspace(), E_method_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
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# 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.
|
# A global place into which we can write the window title.
|
||||||
titles_at_the_close = {}
|
titles_at_the_close = {}
|
||||||
|
|
||||||
|
|
||||||
class EventWindow:
|
class EventWindow:
|
||||||
def __init__ (self, win):
|
def __init__(self, win):
|
||||||
self._win = win
|
self._win = win
|
||||||
self._count = 0
|
self._count = 0
|
||||||
win.title = "This Is The Event Window"
|
win.title = "This Is The Event Window"
|
||||||
self._stop_listener = lambda e : self._event ('stop', e)
|
self._stop_listener = lambda e: self._event("stop", e)
|
||||||
gdb.events.stop.connect (self._stop_listener)
|
gdb.events.stop.connect(self._stop_listener)
|
||||||
self._exit_listener = lambda e : self._event ('exit', e)
|
self._exit_listener = lambda e: self._event("exit", e)
|
||||||
gdb.events.exited.connect (self._exit_listener)
|
gdb.events.exited.connect(self._exit_listener)
|
||||||
self._events = []
|
self._events = []
|
||||||
|
|
||||||
# Ensure we can erase and write to the window from the
|
# Ensure we can erase and write to the window from the
|
||||||
# constructor, the window should be valid by this point.
|
# constructor, the window should be valid by this point.
|
||||||
self._win.erase ()
|
self._win.erase()
|
||||||
self._win.write ("Hello world...")
|
self._win.write("Hello world...")
|
||||||
|
|
||||||
def close (self):
|
def close(self):
|
||||||
global cleanup_properly
|
global cleanup_properly
|
||||||
global titles_at_the_close
|
global titles_at_the_close
|
||||||
|
|
||||||
# Ensure that window properties can be read within the close method.
|
# Ensure that window properties can be read within the close method.
|
||||||
titles_at_the_close[self._win.title] = dict (width=self._win.width,
|
titles_at_the_close[self._win.title] = dict(
|
||||||
height=self._win.height)
|
width=self._win.width, height=self._win.height
|
||||||
|
)
|
||||||
|
|
||||||
# The following calls are pretty pointless, but this ensures
|
# The following calls are pretty pointless, but this ensures
|
||||||
# that we can erase and write to a window from the close
|
# that we can erase and write to a window from the close
|
||||||
# method, the last moment a window should be valid.
|
# method, the last moment a window should be valid.
|
||||||
self._win.erase ()
|
self._win.erase()
|
||||||
self._win.write ("Goodbye cruel world...")
|
self._win.write("Goodbye cruel world...")
|
||||||
|
|
||||||
if cleanup_properly:
|
if cleanup_properly:
|
||||||
# Disconnect the listeners and delete the lambda functions.
|
# Disconnect the listeners and delete the lambda functions.
|
||||||
# This removes cyclic references to SELF, and so alows SELF to
|
# This removes cyclic references to SELF, and so alows SELF to
|
||||||
# be deleted.
|
# be deleted.
|
||||||
gdb.events.stop.disconnect (self._stop_listener)
|
gdb.events.stop.disconnect(self._stop_listener)
|
||||||
gdb.events.exited.disconnect (self._exit_listener)
|
gdb.events.exited.disconnect(self._exit_listener)
|
||||||
self._stop_listener = None
|
self._stop_listener = None
|
||||||
self._exit_listener = None
|
self._exit_listener = None
|
||||||
|
|
||||||
def _event (self, type, event):
|
def _event(self, type, event):
|
||||||
global perform_valid_check
|
global perform_valid_check
|
||||||
global update_title
|
global update_title
|
||||||
|
|
||||||
self._count += 1
|
self._count += 1
|
||||||
self._events.insert (0, type)
|
self._events.insert(0, type)
|
||||||
if not perform_valid_check or self._win.is_valid ():
|
if not perform_valid_check or self._win.is_valid():
|
||||||
if update_title:
|
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:
|
else:
|
||||||
self.render ()
|
self.render()
|
||||||
|
|
||||||
def render (self):
|
def render(self):
|
||||||
self._win.erase ()
|
self._win.erase()
|
||||||
w = self._win.width
|
w = self._win.width
|
||||||
h = self._win.height
|
h = self._win.height
|
||||||
for i in range (min (h, len (self._events))):
|
for i in range(min(h, len(self._events))):
|
||||||
self._win.write (self._events[i] + "\n")
|
self._win.write(self._events[i] + "\n")
|
||||||
|
|
||||||
|
|
||||||
gdb.register_window_type("events", EventWindow)
|
gdb.register_window_type("events", EventWindow)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import gdb
|
|||||||
|
|
||||||
the_window = None
|
the_window = None
|
||||||
|
|
||||||
|
|
||||||
class TestWindow:
|
class TestWindow:
|
||||||
def __init__(self, win):
|
def __init__(self, win):
|
||||||
global the_window
|
global the_window
|
||||||
@@ -38,14 +39,17 @@ class TestWindow:
|
|||||||
def remove_title(self):
|
def remove_title(self):
|
||||||
del self.win.title
|
del self.win.title
|
||||||
|
|
||||||
|
|
||||||
gdb.register_window_type("test", TestWindow)
|
gdb.register_window_type("test", TestWindow)
|
||||||
|
|
||||||
# Call REMOVE_TITLE on the global window object.
|
# Call REMOVE_TITLE on the global window object.
|
||||||
def delete_window_title ():
|
def delete_window_title():
|
||||||
the_window.remove_title ()
|
the_window.remove_title()
|
||||||
|
|
||||||
|
|
||||||
# A TUI window "constructor" that always fails.
|
# A TUI window "constructor" that always fails.
|
||||||
def failwin(win):
|
def failwin(win):
|
||||||
raise RuntimeError("Whoops")
|
raise RuntimeError("Whoops")
|
||||||
|
|
||||||
|
|
||||||
gdb.register_window_type("fail", failwin)
|
gdb.register_window_type("fail", failwin)
|
||||||
|
|||||||
@@ -38,11 +38,12 @@ import os
|
|||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
fmt = sys.argv[1]
|
fmt = sys.argv[1]
|
||||||
else:
|
else:
|
||||||
fmt = '[%b %d %H:%M:%S]'
|
fmt = "[%b %d %H:%M:%S]"
|
||||||
|
|
||||||
mypid = os.getpid()
|
mypid = os.getpid()
|
||||||
|
|
||||||
for line in fileinput.input('-'):
|
for line in fileinput.input("-"):
|
||||||
sys.stdout.write("{} [{}] {}".format(datetime.datetime.now().strftime(fmt),
|
sys.stdout.write(
|
||||||
mypid, line))
|
"{} [{}] {}".format(datetime.datetime.now().strftime(fmt), mypid, line)
|
||||||
|
)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|||||||
Reference in New Issue
Block a user