这是 ubuntu 16.04 中的 gdb 错误吗?

Posted

技术标签:

【中文标题】这是 ubuntu 16.04 中的 gdb 错误吗?【英文标题】:Is this a gdb bug in ubuntu 16.04? 【发布时间】:2020-06-16 05:57:48 【问题描述】:

我使用gdb附加一个程序,然后在函数engine::monAppendSystemInfo中设置断点。当断点被命中时,gdb coredump(实际上是我的程序在engine::monAppendSystemInfo 中崩溃了)。这不是一个不可避免的问题。只出现过两次,无法复制。

这里是engine::monAppendSystemInfo的对比汇编代码。

下面的代码是从 coredump 文件反汇编而来的:

Dump of assembler code for function engine::monAppendSystemInfo(bson::BSONObjBuilder&, unsigned int):
   0x00000000011188f1 <+0>:     push   %rbp
   0x00000000011188f2 <+1>:     mov    %rsp,%rbp
   0x00000000011188f5 <+4>:     push   %r12
   0x00000000011188f7 <+6>:     push   %rbx
   0x00000000011188f8 <+7>:     sub    $0xb20,%rsp
   0x00000000011188ff <+14>:    mov    %rdi,-0xa98(%rbp)
   0x0000000001118906 <+21>:    mov    %esi,-0xa9c(%rbp)
   0x000000000111890c <+27>:    int3                      // strange point
=> 0x000000000111890d <+28>:    mov    0x28,%rax          // crash for accessing 0x28
   0x0000000001118915 <+36>:    mov    %rax,-0x18(%rbp)

下面的代码是从普通gdb反汇编出来的,程序可以继续运行:

Dump of assembler code for function engine::monAppendSystemInfo(bson::BSONObjBuilder&, unsigned int):
   0x00000000011188f1 <+0>:     push   %rbp
   0x00000000011188f2 <+1>:     mov    %rsp,%rbp
   0x00000000011188f5 <+4>:     push   %r12
   0x00000000011188f7 <+6>:     push   %rbx
   0x00000000011188f8 <+7>:     sub    $0xb20,%rsp
   0x00000000011188ff <+14>:    mov    %rdi,-0xa98(%rbp)
   0x0000000001118906 <+21>:    mov    %esi,-0xa9c(%rbp)
=> 0x000000000111890c <+27>:    mov    %fs:0x28,%rax     // "%fs:0x28" was changed to "0x28" in above
   0x0000000001118915 <+36>:    mov    %rax,-0x18(%rbp)

我的linux是:ubuntu16.04.4 LTS,环境如下:

root@lyysdbserver1:~# g++ --version  
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609  
Copyright (C) 2015 Free Software Foundation, Inc.

root@lyysdbserver1:~# gdb --version  
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1  
Copyright (C) 2016 Free Software Foundation, Inc.  

为什么“%fs:0x28”改为“0x28”?这是一个 gdb 错误吗?

【问题讨论】:

未定义的行为?请提供minimal reproducible example 【参考方案1】:

当 GDB 已经设置断点时,您可能正在寻找程序的核心转储。 int 3 是 GDB 设置断点的方式。当你恢复时,int 3 指令应该被原始字节替换。

看看机器代码如何比较这两个指令序列:

mov %fs:0x28,%rax;    64 48 8b 04 25 28 00 00 00
int 3; mov 0x28,%rax; cc 48 8b 04 25 28 00 00 00

【讨论】:

以上是关于这是 ubuntu 16.04 中的 gdb 错误吗?的主要内容,如果未能解决你的问题,请参考以下文章

Ubuntu 16.04 调试caffe深度学习框架

CLion 中的 GDB Monitor 命令

torch7 gnuplot 包中的错误? (Ubuntu 16.04)

ubuntu16.04发生严重错误,怎么补救

CLion 中的 J-Link GDB 调试

gdb 打印内存 x