gpt4 book ai didi

linux - gdb demangler 加载符号时出现段错误

转载 作者:太空宇宙 更新时间:2023-11-04 10:57:40 24 4
gpt4 key购买 nike

最近,我开始在使用 GDB 调试我的产品时遇到麻烦。我找到了问题的根源,但还没有解决方法。

我的代码是用 C++11 编写的,广泛使用了元编程。为了捕获和修复可能的崩溃,它使用调试信息进行编译,用于在 SIGSEGV 处理程序上进行 demangling。

扩展项目使一些元组变得非常大。

我将问题缩小为:取消注释一个元组中的一种类型,并在加载符号时在 gdb 中捕获段错误。

用谷歌搜索这似乎是一项乏味的任务。使用 gdb 调试 gdb 也没有带来更多的洞察力。我唯一找到的东西 - 是 similar bug ,但该跟踪器声明它已修复并确认在我的 gdb (7.7.1) 版本中已修复

我使用 Ubuntu 14.04 作为开发箱,Centos7 作为生产服务器,这里是“gdb --args gdb”的输出:

xxx@xxx$ gdb --args gdb ./epayworker
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from gdb...(no debugging symbols found)...done.
(gdb) run
Starting program: /usr/bin/gdb ./epayworker
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./epayworker...
Program received signal SIGSEGV, Segmentation fault.
0x0000000000719da1 in cplus_demangle_print_callback ()
(gdb) bt -25
#0 0x0000000000719da1 in cplus_demangle_print_callback ()
#1 0x0000000000719fb4 in ?? ()
#2 0x000000000071a0c7 in ?? ()
#3 0x000000000071a26e in cplus_demangle_v3 ()
#4 0x000000000070c3c6 in cplus_demangle ()
#5 0x000000000068fdbb in bfd_demangle ()
#6 0x000000000055f269 in symbol_set_names ()
#7 0x00000000005cb985 in prim_record_minimal_symbol_full ()
#8 0x00000000004f82ba in ?? ()
#9 0x00000000004f8b95 in ?? ()
#10 0x000000000056a8d9 in ?? ()
#11 0x000000000056a459 in ?? ()
#12 0x000000000056a9b4 in symbol_file_add ()
#13 0x000000000056aa15 in ?? ()
#14 0x00000000005921be in catch_command_errors_const ()
#15 0x0000000000594da5 in ?? ()
#16 0x000000000059205a in catch_errors ()
#17 0x0000000000595244 in gdb_main ()
#18 0x000000000045391e in main ()
(gdb)

在这个阶段,我对更改生产服务器核心的编译器并不感到兴奋。对架构造成限制的错误也不是最好的事情。

所以我的问题是:我是否缺少某种类型的标志来克服 gdb 中的某些内部限制?或者这只是 gdb 中的一个错误?或者也许我不应该害怕并迁移到更新的编译器版本?

谢谢,对我的困惑有任何帮助。

更新:

这似乎是一个相当不错的死局。最近我一直在玩元组,似乎问题与某些特定符号无关,而是与某种缓冲区溢出有关。因为来回交换类型、重命名它们、缩短名称长度并没有什么不同,但在元组中的类型数量达到一定阈值后,就会出现崩溃。

我发现的最大元组类型名长度是 ~77600 个字符(再添加一种类型 - gdb 崩溃)

旁注是 Netbeans 8.0.2 也存在错误:在具有大名称长度的类型名称的调用堆栈窗口中,在某个阈值之后,它开始进行某种包装,并在上打印相同类型名称的不同部分同一行的顶部,使其完全不可读。在一些更大的阈值之后,typename 就消失了,使行变空。

我会提交错误。但出于显而易见的原因,我不能向公众发布我的代码。所以我将尝试提取造成这种困惑的部分,并用它构建一个测试应用程序。该部分是:用于构建反射的元函数,如 meta-for_each 等。

抱歉,现在截止日期很紧,所以尽快有更多时间。

最佳答案

也许有些令人惊讶的是,demangler 是一款复杂的软件。而且,随着 C++ 的发展,修饰方案变得更加复杂,因此分解器也变得更加复杂。有时会有错误。

现在,通常这没什么大不了的。但是,为了提供良好的用户体验(部分原因是编译器 DWARF 生成的历史问题),gdb 急切地分解符号。如果一个这样的符号触发了 demangler 错误——砰!

这就是你所经历的。

去年,一个补丁使用了一个 SEGV 捕捉器来包装对 demangler 的调用。通过这种方式,gdb 至少可以在一定程度上免受 demangler 错误的影响——它会打印出有问题的符号并尝试继续前进。

您的 gdb 可能已被修补以针对某些特定的已知错误修复 demangler,但可能还没有 SEGV 捕获补丁。所以我建议你升级 gdb。这应该有所帮助。

另外,让我推荐遵循 Gary 的错误报告说明:https://sourceware.org/bugzilla/show_bug.cgi?id=14963#c35 .也就是说,如果您知道该符号,请提交 GCC 错误;否则向复制者提交 gdb 错误,然后有人会对其进行分类。

据我所知,此错误没有合理的解决方法。这就是 SEGV 捕捉器进入的原因。然而,有一个不合理的解决方法——编辑二进制文件以重命名有问题的符号以避免 demangler 崩溃。但是,实际上,构建自己的 gdb 更简单、更安全。

关于linux - gdb demangler 加载符号时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28249044/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com