- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
最近,我开始在使用 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/
假设我定义了一个 new gdb command其中包括别名。 import gdb import string class PrettyPrintString (gdb.Command):
是否可以使用 gdb 的 if 或 while 条件来测试 gdb 命令是否成功(而不是查询程序值或变量)? 现在为了清楚起见,我谈论的是 gdb 内置命令(即当您在 gdb 中键入 help 时出现
我只是使用 gdb 逐行逐行执行代码,以了解它是如何工作的以及它在做什么。我第一次这样做时效果很好,但现在下一个命令无法正常工作。有时它前进,有时它倒退。这没有意义。每次我这样做似乎都是相同的模式。下
我怎样才能运行类似 gdb -e path/to/exe -ex 'run --argnamae argvalue' 的东西? 让我们假设在过去一两年内有一个最新版本的 gfb。 Gdb 运行并打印响
我正在使用 gdb 调试程序,并且我想要命令的输出 $(perl -e 'print "A"x20') 作为我的论点。我怎样才能做到这一点?这样,论点将非常灵活。 最佳答案 您可以使用 run 命令,
我在 linux 上使用 gdb 版本 7.5.1,并试图使用诸如 $_memeq 之类的便利功能只是发现它显然不存在: Undefined command: "$_memeq". Try "help
我有: 正在运行的剥离二进制文件 总局 未剥离的二进制文件 我可以连接到运行剥离的二进制文件 (gdp -p PID)。如何将未剥离二进制文件中的符号提供给连接到正在运行的进程的 gdb? 最佳答案
我偶然发现了gdb的自动显示功能,该功能非常强大且方便。打电话后 (gdb) display/i $pc (gdb) display $rax 监视的值将在每个步骤后自动显示: (gdb) si 0x
我知道 Linux 等现代操作系统并不总是在应用程序最初链接的同一地址执行应用程序。但是,当调试器开始四处查看时,它需要知道原始链接地址和最终执行地址之间的关系。 GDB如何计算偏移量? 澄清:我不是
我想知道是否有可能从GDB本身获取已调试应用程序已打开但未关闭的文件/目录的列表? 当前,我设置了一个断点,然后使用lsof这样的外部程序来检查打开的文件。 但是这种方法确实很烦人。 环境:Debia
我想执行非常简单的命令 print var1, var2, var3, var4 在 gdb 中不时检查变量的值。 我不想使用显示,因为它会扰乱我的 View 。 我该如何做到这一点?现在我能做的就是
这个问题已经有答案了: gdb scripting: execute commands at selected breakpoint (1 个回答) 已关闭 8 年前。 我需要检查一个变量以确定它是否
在命令行下,我知道使用 echo $?给我退出代码。在gdb中,我使用“r”来运行程序,程序终止,那么gdb是如何得到这个退出码的呢? gdb 里面有什么命令吗? 谢谢! 最佳答案 当程序退出时,gd
我遇到了核心,无法从中获取回溯。我有两个问题。 我可以从以下位置找出导致崩溃的行或崩溃发生的位置吗列出命令输出? 否则如何处理。我应该将 heuristic-fence-post 设置为多少才能得到一
调试时加断点,运行bt可以看到栈帧。 通过运行信息寄存器选择帧时,可以看到特定帧上的寄存器值。 例如,考虑在第 5 帧设置断点。当断点被击中时,进入第 3 帧,可以看到查看寄存器值。 在第 5 帧设置
gdb 如何打印结构?来自 zengr 在 how does gdb work? 引用的“GDB 内部”文档看起来 GDB 使用 BFD 库从一个或多个符号表加载符号。如果是这种情况,gdb 怎么知道
我只是使用 gdb 逐行逐行执行代码,以了解它是如何工作的以及它在做什么。我第一次这样做时效果很好,但现在下一个命令无法正常工作。有时它前进,有时它倒退。这没有意义。每次我这样做似乎都是相同的模式。下
当我执行以下命令时,我得到不同的 function() 地址 (gdb) 中断函数() function() 0x804834a 处的断点 1。 (gdb) 打印函数() function() 0x8
我已经安装了 (OSX Mojave 10.14.6.) Eclipse CDT 和 GNU MCU Eclipse plugin最后 GNU Tools for ARM .我的目标是使用 GDB (
我必须对文件(main 和 functions)进行 cpp,然后让它们构建一个 exe 文件(代码)和两个目标文件(main.o 和 functions.o)。 如何从 gdb 命令行调试特定文件“
我是一名优秀的程序员,十分优秀!