告诉gdb跳过标准文件

Tell gdb to skip standard files

本文关键字:标准文件 gdb 告诉      更新时间:2023-10-16

我正在用GDB调试c++代码,当它进入一些包含标准库对象的对象的构造函数时,它会显示这些对象的构造函数(如std::map)和下面的所有内容。

我知道next操作符,但我更愿意将任何标准库代码基本上列入黑名单,这绝不是我正在调查的错误的来源。我所希望的行为是,一个简单的skip将把我送到下一个"user-land"代码。

gdb 7.12支持文件globbing,以指定在调试器中跳过的文件。相同的文档如下:

https://sourceware.org/gdb/onlinedocs/gdb/Skipping-Over-Functions-and-Files.html

要跳过进入目录/usr/include/c++/5/bits中的所有库头文件,请在~/.gdbinit

中添加以下行
# To skip all .h files in /usr/include/c++/5/bits
skip -gfi /usr/include/c++/5/bits/*.h

如果要跳过特定的文件,例如stl_vector.h,请将以下行添加到~/.gdbinit

# To skip the file /usr/include/c++/5/bits/stl_vector.h
skip file /usr/include/c++/5/bits/stl_vector.h

使用gdb 7.11及以下版本执行上述操作会导致以下错误:

Ignore function pending future shared library load? (y or [n]) [answered N; input not from terminal]

然而,gdb 7.12似乎已经解决了上述问题。

这个博客解决了gdb 7.11或以下版本的相同问题。

注意—您可以在gdb命令提示符中使用以下命令列出标记为跳过

的所有文件
info skip

* GDB 7.4的变化

  • GDB现在允许您在使用"skip function"answers"skip file"命令步进时跳过不感兴趣的函数和文件。

步骤说明,跳过所有没有源代码的文件

这对于大多数应用程序来说太慢了,但它很有趣!

基于:显示gdb中执行的每个汇编指令

class ContinueUntilSource(gdb.Command):
    def __init__(self):
        super().__init__(
            'cus',
            gdb.COMMAND_BREAKPOINTS,
            gdb.COMPLETE_NONE,
            False
        )
    def invoke(self, argument, from_tty):
        argv = gdb.string_to_argv(argument)
        if argv:
            gdb.write('Does not take any arguments.n')
        else:
            done = False
            thread = gdb.inferiors()[0].threads()[0]
            while True:
                message = gdb.execute('si', to_string=True)
                if not thread.is_valid():
                    break
                try:
                    path = gdb.selected_frame().find_sal().symtab.fullname()
                except:
                    pass
                else:
                    if os.path.exists(path):
                        break
ContinueUntilSource()

在Ubuntu 16.04, GDB 7.11中测试。GitHub上游.

std::function case

如何一步调试到std::函数用户代码从c++功能与GDB?

修改自Ciro Santilli的回答命令ss步骤内部特定源代码。您可以指定源文件名,否则将步进当前文件名。非常方便步进bison/yacc源或其他元源生成С代码和插入#line指令。

import os.path
class StepSource(gdb.Command):
    def __init__(self):
        super().__init__(
            'ss',
            gdb.COMMAND_BREAKPOINTS,
            gdb.COMPLETE_NONE,
            False
        )
    def invoke(self, argument, from_tty):
        argv = gdb.string_to_argv(argument)
        if argv:
            if len(argv) > 1:
                gdb.write('Usage:nns [source-name]]n')
                return
            source = argv[0]
            full_path = False if os.path.basename(source) == source else True
        else:
            source = gdb.selected_frame().find_sal().symtab.fullname()
            full_path = True
        thread = gdb.inferiors()[0].threads()[0]
        while True:
            message = gdb.execute('next', to_string=True)
            if not thread.is_valid():
                break
            try:
                cur_source = gdb.selected_frame().find_sal().symtab.fullname()
                if not full_path:
                    cur_source = os.path.basename(cur_source)
            except:
                break
            else:
                if source == cur_source:
                    break
StepSource()

已知bug
  1. 在运行时不中断SIGINT调试器;
  2. pass更改为break,因为不确定是否正确。