GDB断点不影响模板功能 [英] GDB breakpoints do not hit template functions

查看:63
本文介绍了GDB断点不影响模板功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过GDB在C ++中的模板函数中设置断点我尝试了三种可能的方法.

I am trying set breakpoints in template functions in C++ via GDB I tried three possible approaches.

  1. break fileName:functionName =>适用于非模板函数(特定于一个函数)
  2. rbreak fileName :.=>给定文件中所有功能的断点,但似乎没有使用模板功能
  3. break fileName:lineNumber =>既适用于非模板函数,也适用于模板函数,但存在问题对我来说,这是我每次都必须修改此行号.

总体目标是使用如下所示的脚本通过GDB跟踪完整的代码流,但是我的代码也具有许多模板功能.下面的示例GDB脚本

A overall objective is am using a script like below to trace the full codeflow via GDB, but my code has lot of template functions too. Sample GDB script below

set logging on
b func2
commands
silent
bt 1
continue
end
b func1
commands
silent
bt 1
set logging off
continue
end

  • 一个选择是使用rbreak filename:.
  • 运行一次代码,然后
  • 再次运行代码而不退出GDB.这次,它认识到功能和断点有效.
  • 您能帮忙提出一个适当的解决方案,还是让我知道我是否缺少某些东西?任何帮助/建议都将受到高度赞赏,并大大简化了我的调试工作.

    Could you please help suggest a proper solution or let me know if I am missing something ? Any help/suggestion is highly appreciated and simplify my debug a lot.

    非常感谢!

    推荐答案

    问题很可能是您尝试在gdb中设置断点时使用的函数名称.

    The problem is most likely the function name you are using when trying to set a breakpoint in gdb.

    gdb使用的函数名称不是源文件中的名称,而是二进制文件中的名称.模板功能实际上不是功能.它们只是配方",当您使用模板实际编译代码时,编译器将使用配方为您实现一个功能(对于您实际使用的每种模板参数组合,一个功能).

    The function names that gdb use are not what's in the source file, but what's in the binary. Template functions are not actually functions. They are just "recipe" and when you actually compile the code using the template the compiler will implement a function for you using the recipe (one for each combination of template parameters you have actually used).

    考虑以下代码

    #include <iostream>
    
    double tripleInput(double x) { return 3 * x; }
    
    template <typename T>
    inline T doubleInput(const T& x) {
        return 2 * x;
    }
    
    
    int main(int argc, char *argv[])
    {
        std::cout << doubleInput(13) << std::endl;
        std::cout << doubleInput(1.72) << std::endl;
    
        std::cout << tripleInput(1.72) << std::endl;
        return 0;
    }
    

    当我们编译它并在gdb中调试时,gdb将看到三个函数(在 main 之外): tripleInput doubleInput< int> doubleInput< double> .如果您使用gdb break TripleInput 编写一个断点,则会在 tripleInput 函数中添加一个断点,但是如果您只编写 break doubleInput ,则gdb会说该函数没有定义.

    When we compile this and debug in gdb there are three functions that gdb will see (besides main): tripleInput, doubleInput<int> and doubleInput<double>. If you write in gdb break tripleInput a breakpoint will be added in the tripleInput function, but if you write just break doubleInput gdb will say the function is not defined.

    您需要编写 break doubleInput< int> break doubleInput< double> ,但是请注意,像这样添加断点只会在该特定实例中停止模板.它与在模板中的行上添加断点不同.在这种情况下,gdb实际上会添加一个具有多个位置的断点.在使用两种方法创建断点后尝试尝试 info断点,以查看不同之处.

    You need to write either break doubleInput<int> or break doubleInput<double>, but notice that adding a breakpoint like this will only stop in that specific instance of the template. It is different from adding a breakpoint to a line in the template. In that case gdb actually adds a breakpoint with multiple locations. Try info breakpoints after creating a breakpoint with both methods to see the different.

    我不知道可以做诸如 break doubleInput< *> 之类的事情,但是从文档中看,这似乎是不可能的.

    I don't know it is possible to do something such as break doubleInput<*>, but from a look in the documentation it does not seem to be possible.

    提示:在gdb部分中,TAB将完成函数名称,包括模板实例.

    TIP: In a gdb section TAB will complete the function names, including template instances.

    我完全忘记了 rbreak .它可以在与正则表达式匹配的所有函数上设置断点.这意味着我们可以轻松地在所有功能模板实例中添加一个断点,

    I completely forgot about rbreak. It can set breakpoints on all functions matching a regular expression. This means that we can easily add a breakpoint in all function template instances with

    rbreak doubleInput*
    

    甚至是文件中的所有功能都带有

    or even in all functions in a file with

    rbreak main.cpp:.*
    

    这篇关于GDB断点不影响模板功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆