这是我基于 JaredC 得出的结论:
import gdb
class FilteredThreadBacktraceCommand(gdb.Command):
"""
Implements a command that allows printing the backtrace only for threads
that do not have given frames.
The class must be instantiated with a list of the frames to ignore. If the
stack for a thread has any of those frames then the stack for that thread
will not be printed (a visual dot will be printed to show a thread was just
ignored and provide a notion of progress).
"""
def __init__(self, ignored_frames):
super (FilteredThreadBacktraceCommand, self).__init__ ("fbt", gdb.COMMAND_STACK)
self.ignored_frames = ignored_frames
def invoke(self, arg, from_tty):
args = gdb.string_to_argv(arg)
if len(args) != 0:
gdb.write("ERROR: invalid number of arguments.\n")
return
# This loops through all the Thread objects in the process
for thread in gdb.selected_inferior().threads():
# This is equivalent to 'thread X'
thread.switch()
f = gdb.newest_frame()
frames = []
invalid_thread = False
while f is not None:
if any(ignored_frame in f.name() for ignored_frame in self.ignored_frames):
invalid_thread = True
break
frames.append(f)
f = gdb.Frame.older(f)
if invalid_thread:
# Visual effect as iterating frames might take a while
sys.stdout.write('.')
sys.stdout.flush()
continue
print "\nThread %s:" % thread.num
for i in range(len(frames)):
f = frames[i]
funcInfo = f.function()
printStr = "#{} in {}".format(i, f.name())
if f.function():
printStr += " at {}:{}".format(funcInfo.symtab.filename, funcInfo.line)
else:
printStr += " at (???)"
print(printStr)
FilteredThreadBacktraceCommand(["os::PlatformEvent::park"])
您可以在创建时向班级提供要忽略的框架。也可以使其通用,以便为要注册的命令提供名称,以便您可以使用具有不同过滤的不同命令。