【问题标题】:GDB: error setting break point in template class functions in header filesGDB:在头文件的模板类函数中设置断点错误
【发布时间】:2011-06-07 16:42:00
【问题描述】:

我使用了两个不同版本的 GDB,都在以下代码中出现问题:

MyFile.h中删减代码:

template<class T>
struct ABC: PQR<T> {
  void flow(PP pp) {
    const QX qx = XYZ<Z>::foo(pp); // Trying to set a breakpoint here, line no. 2533
    ASSERTp(qx >= last_qx());
   }
}

GDB 7.1:

Reading symbols from /path_to_exec/exec...done.
(gdb) break MyFile.h:2533
Note: breakpoint 1 also set at pc 0x121.
Note: breakpoint 1 also set at pc 0x121.
Note: breakpoint 1 also set at pc 0x121.
Note: breakpoint 1 also set at pc 0x156.
Note: breakpoint 1 also set at pc 0x156.
Note: breakpoint 1 also set at pc 0x121.
Note: breakpoint 1 also set at pc 0x121.
Note: breakpoint 1 also set at pc 0x121.
Note: breakpoint 1 also set at pc 0x121.
Note: breakpoint 1 also set at pc 0x121.
Note: breakpoint 1 also set at pc 0x121.
Note: breakpoint 1 also set at pc 0x156.
Note: breakpoint 1 also set at pc 0x156.
Note: breakpoint 1 also set at pc 0x121.
Breakpoint 1 at 0x44e5c4: file PacketEngine.h, line 2533. (23 locations)
(gdb) run
Starting program: /path_to_exec/exec -options
Warning:
Cannot insert breakpoint 1.
Error accessing memory address 0x121: Input/output error.
Cannot insert breakpoint 1.
Error accessing memory address 0x156: Input/output error.

为什么要为一个设置 23 个断点?再往下,它在run

上给出错误

GDB 6.3:

 This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/tls/libthread_db.so.1".

(gdb) break MyFile.h:2533
No line 2533 in file "MyFile.h".

在程序开始时,它甚至不接受断点 如果我中断函数 ASSERTp,它就会中断。然后。如果我“向上”并键入 break,它会成功插入断点 (break MyFile.h:2533)。 [因此它以某种方式在程序实际运行后找到文件/行]。 然而,尽管设置了断点,但在重新运行程序时,它不会在第 2533 行停止,而是仅在第 2534 行停止(函数 ASSERTp 中的断点)。

我的问题:

1) 有人可以帮我解决这个问题吗?

2) 我经常遇到模板代码和 GDB 的问题。有没有好的免费的 C++ 模板调试器?

3) 不是很重要,但如果重要的话是一个附带问题:哪个版本更可取? 7.1 似乎有更多的错误,但我记得在一些运行中,它给出的问题更少。


系统信息:

uname -a
Linux ... 2.6.9-67.ELsmp #1 SMP Fri Nov 16 12:49:06 EST 2007 x86_64 x86_64 x86_64 GNU/Linux

file /usr/bin/gdb   #### GDB 6.3
/usr/bin/gdb: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), stripped

file ~/local/bin/gdb  #### GDB 7.1
/home/user/local/bin/gdb: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), not stripped

file /path_to_exec/exec
/path_to_exec/exec: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), not stripped

【问题讨论】:

  • 代码库很大且模板化程度很高,因此重现错误可能很困难 :(。因此欢迎任何缩小问题范围的提示。

标签: c++ templates gdb breakpoints header-files


【解决方案1】:

我不是任何其他 linux 调试器,但我从未遇到过您解释的此类问题。

您提出的问题非常好(所以您可能做到了),但是您是否使用调试符号编译了源代码?

编辑

顺便说一句,我还没有尝试过 gdb 7.1 - 只有 6.8 版本。如果你觉得 bug 很大,可以尝试使用 6 版本的最后一个版本。

【讨论】:

  • 是的,我确实使用了 -g 标志。此外,不幸的是,我一直遇到 gdb 的两种问题(1)头文件中的断点 2)模板)。我们的代码被大量模板化[模板的深度嵌套](并且非常大 - 数百 K 行) - 所以我必须接受错误可能不容易重构。
  • @JP19 “数百个 K 行”——这就是 WTF 本身。也许 gdb 对大文件有问题?我试过的最大文件是10k,还不错。
  • 对不起,我的意思是总行数。我试图传达的观点是,重现该错误可能很困难 :(。因此欢迎任何解决问题的提示。大多数文件肯定少于 10K 行。
  • 我会尝试 6.8 看看是否有帮助。
【解决方案2】:

我见过类似的情况(使用 GDB 7.0),模板函数中设置的断点永远不会被命中。

我们的项目是使用旧版本的 G++ 构建的(比我的发行版中的版本旧得多)。我发现通过使用我们开发的相同编译器构建 GDB 版本,问题得到了解决。

【讨论】:

  • 这很有趣。我认为我尝试的 7.1 版本是使用与我们的代码相同的 G++ 构建的,但不确定。我会检查一下。
【解决方案3】:

gdb 为每个实例化模板设置不同的断点,即为程序中 T(可能还有 Z)假定的每种不同类型。但是,它试图在 0x121 处设置断点的地址似乎太低了,可能对应于某些系统位置。这可能就是 gdb 无法设置断点的原因。

您应该尝试 gdb 7.2,也许这会有所帮助。

另外,e2dbg 是一种不同类型的 Linux 调试器,但不如 gdb 成熟。 http://www.eresi-project.org/wiki/TheEmbeddedELFDebugger

【讨论】:

    猜你喜欢
    • 2010-12-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 2014-03-29
    • 2012-08-10
    • 1970-01-01
    相关资源
    最近更新 更多