首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用gdb脚本剪枝回溯输出

用gdb脚本剪枝回溯输出
EN

Stack Overflow用户
提问于 2013-05-09 17:48:20
回答 3查看 1.3K关注 0票数 2

我的程序有100个线程,其中大多数是空闲的,并且在空闲时共享一个非常好定义的回溯。大多数情况下,我只对不空闲的线程感兴趣,因此没有“公共”回溯。我认为使用gdb脚本是一种很好的方法。

代码语言:javascript
复制
define backtraces
    thread apply all bt
end

这个脚本只需打印所有的回溯。是否有一种方法可以将输出存储到一个变量中,然后我可以处理、修剪和只显示相关的回溯?

我天真地尝试:

代码语言:javascript
复制
define backtraces
    set $bts = thread apply all bt
    // do whatever processing here
end

但这与预期的情况不符:

当前上下文中没有符号“线程”。

有更好的方法吗?或者是关于如何在gdb中增强脚本的好教程?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-09 23:44:42

通过使用俄文答案中的链接,我得到了一些有用的东西。这是为了子孙后代,因为它是完全不明显的。

代码语言:javascript
复制
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:

代码语言:javascript
复制
source traces.py

还有其他方法来调用这个python脚本。

票数 2
EN

Stack Overflow用户

发布于 2013-05-09 18:50:12

有更好的方法吗?

您需要使用Python脚本来实现您想要的结果。

滤波回溯可能是一个好的开始。

票数 2
EN

Stack Overflow用户

发布于 2020-04-24 19:07:51

这就是我根据JaredC所写的:

代码语言:javascript
复制
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"])

您可以在创建时向类提供要忽略的框架。您也可以将其泛化,以便为命令提供一个名称来注册,这样您就可以使用不同的筛选方法获得不同的命令。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16467923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档