我的程序有100个线程,其中大多数是空闲的,并且在空闲时共享一个非常好定义的回溯。大多数情况下,我只对不空闲的线程感兴趣,因此没有“公共”回溯。我认为使用gdb脚本是一种很好的方法。
define backtraces
thread apply all bt
end这个脚本只需打印所有的回溯。是否有一种方法可以将输出存储到一个变量中,然后我可以处理、修剪和只显示相关的回溯?
我天真地尝试:
define backtraces
set $bts = thread apply all bt
// do whatever processing here
end但这与预期的情况不符:
当前上下文中没有符号“线程”。
有更好的方法吗?或者是关于如何在gdb中增强脚本的好教程?
发布于 2013-05-09 23:44:42
通过使用俄文答案中的链接,我得到了一些有用的东西。这是为了子孙后代,因为它是完全不明显的。
import gdb
# 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()
print "Thread %s" % thread.num
# Just execute a raw gdb command
gdb.execute('bt')
framesNames = []
f = gdb.newest_frame()
while f is not None:
framesNames.append(gdb.Frame.name(f))
f = gdb.Frame.older(f)
# do something with the name of each frame如果它位于一个名为traces.py的文件中,那么您可以在gdb中执行python:
source traces.py还有其他方法来调用这个python脚本。
发布于 2013-05-09 18:50:12
有更好的方法吗?
您需要使用Python脚本来实现您想要的结果。
滤波回溯可能是一个好的开始。
发布于 2020-04-24 19:07:51
这就是我根据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"])您可以在创建时向类提供要忽略的框架。您也可以将其泛化,以便为命令提供一个名称来注册,这样您就可以使用不同的筛选方法获得不同的命令。
https://stackoverflow.com/questions/16467923
复制相似问题