使用gdb脚本修剪回溯输出
我的程序有100个线程,其中大多数是空闲的,并且在空闲时共享定义良好的回溯。大多数时候,我只对非空闲线程感兴趣,因此没有“公共”回溯。我认为使用gdb脚本将是一种很好的方法使用gdb脚本修剪回溯输出,gdb,Gdb,我的程序有100个线程,其中大多数是空闲的,并且在空闲时共享定义良好的回溯。大多数时候,我只对非空闲线程感兴趣,因此没有“公共”回溯。我认为使用gdb脚本将是一种很好的方法 define backtraces thread apply all bt end 此脚本将只打印所有回溯。有没有一种方法可以将这个输出存储到一个变量中,然后我可以处理、删减并只显示相关的回溯 我天真地尝试: define backtraces set $bts = thread apply all bt
define backtraces
thread apply all bt
end
此脚本将只打印所有回溯。有没有一种方法可以将这个输出存储到一个变量中,然后我可以处理、删减并只显示相关的回溯
我天真地尝试:
define backtraces
set $bts = thread apply all bt
// do whatever processing here
end
但这并没有达到预期的效果:
当前上下文中没有“线程”符号
有更好的方法吗?还是关于如何在gdb中增强脚本的好教程
有更好的方法吗
您将需要使用来实现所需的结果
这可能是一个好的开始
有更好的方法吗
您将需要使用来实现所需的结果
这可能是一个好的开始。使用俄语答案中的链接,我能够找到一些有用的东西。这是留给后代的,因为它完全不明显
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脚本。使用俄文答案中的链接,我可以得到一些有用的东西。这是留给后代的,因为它完全不明显
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脚本。这是我根据JaredC编写的:
导入gdb
类FilteredThreadBacktraceCommand(gdb.Command):
"""
实现一个命令,该命令只允许为线程打印回溯跟踪
没有给定帧的。
必须使用要忽略的帧列表实例化该类
线程的堆栈具有这些帧中的任何帧,然后该线程的堆栈具有这些帧
不会打印(将打印一个可视点,以显示刚刚打印的线
忽略并提供进展的概念)。
"""
def uuu init uuu(自,忽略的帧):
super(FilteredThreadBacktraceCommand,self)。\uuu init\uuuu(“fbt”,gdb.COMMAND\u堆栈)
self.ignored\u frames=忽略的\u frames
def调用(self、arg、from_tty):
args=gdb.string_到_argv(arg)
如果len(args)!=0:
写入(“错误:参数数量无效。\n”)
回来
#这将遍历进程中的所有线程对象
对于gdb中的线程。所选的线程()。线程():
#这相当于“线程X”
thread.switch()
f=gdb.最新的_帧()
帧=[]
无效的线程=False
虽然f不是无:
如果有(对于self.ignored_frames中的ignored_frames,f.name()中的ignored_frames):
无效的线程=True
打破
帧。追加(f)
f=gdb.Frame.older(f)
如果线程无效:
#迭代帧时的视觉效果可能需要一些时间
sys.stdout.write('.')
sys.stdout.flush()
持续
打印“\n读取%s:”%thread.num
对于范围内的i(len(帧)):
f=帧[i]
funcInfo=f.函数()
printStr=“{}中的{}”。格式(i,f.name())
如果f.函数()
printStr+=“at{}:{}”。格式(funcInfo.symtab.filename,funcInfo.line)
其他:
printStr+=“在(???)”
打印(printStr)
FilteredThreadBacktraceCommand([“os::PlatformEvent::park”])
可以在创建时向类提供要忽略的帧。我们还可以将其设置为通用,以便为要注册的命令提供一个名称,这样您就可以使用不同的过滤功能使用不同的命令。这是我根据JaredC编写的内容得出的结论:
导入gdb
类FilteredThreadBacktraceCommand(gdb.Command):
"""
实现一个命令,该命令只允许为线程打印回溯跟踪
没有给定帧的。
必须使用要忽略的帧列表实例化该类
线程的堆栈具有这些帧中的任何帧,然后该线程的堆栈具有这些帧
不会打印(将打印一个可视点,以显示刚刚打印的线
忽略并提供进展的概念)。
"""
def uuu init uuu(自,忽略的帧):
super(FilteredThreadBacktraceCommand,self)。\uuu init\uuuu(“fbt”,gdb.COMMAND\u堆栈)
self.ignored\u frames=忽略的\u frames
def调用(self、arg、from_tty):
args=gdb.string_到_argv(arg)
如果len(args)!=0:
写入(“错误:参数数量无效。\n”)
回来
#这将遍历进程中的所有线程对象
对于gdb中的线程。所选的线程()。线程():
#这相当于“线程X”
thread.switch()
f=gdb.最新的_帧()
帧=[]
无效的线程=False
虽然f不是无:
如果有(对于self.ignored_frames中的ignored_frames,f.name()中的ignored_frames):
无效的线程=True
打破
帧。追加(f)
f=gdb.Frame.older(f)
如果线程无效:
#迭代帧时的视觉效果可能需要一些时间
sys.stdout.write('.')
sys.stdout.flush()
持续
打印“\n读取%s:”%thread.num
对于范围内的i(len(帧)):
f=帧[i]
funcInfo=f.函数()
printStr=“{}中的{}”。格式(i,f.name())
如果f.函数()