【问题标题】:gdb crash when using breakpoints使用断点时 gdb 崩溃
【发布时间】:2019-09-16 23:59:52
【问题描述】:

在我尝试调试的每个程序中,每次我使用断点并尝试运行任何程序 gdb 崩溃时,我都会得到相同的结果。我在不同的程序上尝试了同样的事情,它一直这样。

我将在这个简单的地方展示结果:

int main(int argc,char* argv[]){
    for(int i = 0;i < 200; i++){
        printf("%d\n",i);
    }
}
gcc main.c -m32 -std=c99 -o test
GNU gdb (Debian 8.3-1) 8.3
Copyright (C) 2019 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 test...
(No debugging symbols found in test)
(gdb) disas main
Dump of assembler code for function main:
   0x00001199 <+0>: lea    0x4(%esp),%ecx
   0x0000119d <+4>: and    $0xfffffff0,%esp
   0x000011a0 <+7>: pushl  -0x4(%ecx)
   0x000011a3 <+10>:    push   %ebp
   0x000011a4 <+11>:    mov    %esp,%ebp
   0x000011a6 <+13>:    push   %ebx
   0x000011a7 <+14>:    push   %ecx
   0x000011a8 <+15>:    sub    $0x10,%esp
   0x000011ab <+18>:    call   0x10a0 <__x86.get_pc_thunk.bx>
   0x000011b0 <+23>:    add    $0x2e50,%ebx
   0x000011b6 <+29>:    movl   $0x0,-0xc(%ebp)
   0x000011bd <+36>:    jmp    0x11d8 <main+63>
   0x000011bf <+38>:    sub    $0x8,%esp
   0x000011c2 <+41>:    pushl  -0xc(%ebp)
   0x000011c5 <+44>:    lea    -0x1ff8(%ebx),%eax
   0x000011cb <+50>:    push   %eax
   0x000011cc <+51>:    call   0x1030 <printf@plt>
   0x000011d1 <+56>:    add    $0x10,%esp
   0x000011d4 <+59>:    addl   $0x1,-0xc(%ebp)
   0x000011d8 <+63>:    cmpl   $0xc7,-0xc(%ebp)
   0x000011df <+70>:    jle    0x11bf <main+38>
   0x000011e1 <+72>:    mov    $0x0,%eax
   0x000011e6 <+77>:    lea    -0x8(%ebp),%esp
   0x000011e9 <+80>:    pop    %ecx
   0x000011ea <+81>:    pop    %ebx
   0x000011eb <+82>:    pop    %ebp
   0x000011ec <+83>:    lea    -0x4(%ecx),%esp
   0x000011ef <+86>:    ret    
End of assembler dump.
(gdb) break *0x000011ef
Breakpoint 1 at 0x11ef
(gdb) run
Starting program: /root/test 

[1]+  Stopped                 gdb test

我尝试在另一台 linux 机器上做同样的事情,它工作正常。那么可能是什么问题呢?

更新:我找到了断点问题的临时解决方案(所以 gdb 不会崩溃),您在开始时使用命令(启动),一切都会正常工作:

GNU gdb (Debian 8.3-1) 8.3
Copyright (C) 2019 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 test...
(No debugging symbols found in test)
(gdb) start
Temporary breakpoint 1 at 0x11a8
Starting program: /root/test 

Temporary breakpoint 1, 0x565561a8 in main ()
(gdb) enable
(gdb) disas main
Dump of assembler code for function main:
   0x56556199 <+0>: lea    0x4(%esp),%ecx
   0x5655619d <+4>: and    $0xfffffff0,%esp
   0x565561a0 <+7>: pushl  -0x4(%ecx)
   0x565561a3 <+10>:    push   %ebp
   0x565561a4 <+11>:    mov    %esp,%ebp
   0x565561a6 <+13>:    push   %ebx
   0x565561a7 <+14>:    push   %ecx
=> 0x565561a8 <+15>:    sub    $0x10,%esp
   0x565561ab <+18>:    call   0x565560a0 <__x86.get_pc_thunk.bx>
   0x565561b0 <+23>:    add    $0x2e50,%ebx
   0x565561b6 <+29>:    movl   $0x0,-0xc(%ebp)
   0x565561bd <+36>:    jmp    0x565561d8 <main+63>
   0x565561bf <+38>:    sub    $0x8,%esp
   0x565561c2 <+41>:    pushl  -0xc(%ebp)
   0x565561c5 <+44>:    lea    -0x1ff8(%ebx),%eax
   0x565561cb <+50>:    push   %eax
   0x565561cc <+51>:    call   0x56556030 <printf@plt>
   0x565561d1 <+56>:    add    $0x10,%esp
   0x565561d4 <+59>:    addl   $0x1,-0xc(%ebp)
   0x565561d8 <+63>:    cmpl   $0xc7,-0xc(%ebp)
   0x565561df <+70>:    jle    0x565561bf <main+38>
   0x565561e1 <+72>:    mov    $0x0,%eax
   0x565561e6 <+77>:    lea    -0x8(%ebp),%esp
   0x565561e9 <+80>:    pop    %ecx
   0x565561ea <+81>:    pop    %ebx
   0x565561eb <+82>:    pop    %ebp
   0x565561ec <+83>:    lea    -0x4(%ecx),%esp
   0x565561ef <+86>:    ret    
End of assembler dump.
(gdb) break *0x565561df
Breakpoint 2 at 0x565561df
(gdb) info break
Num     Type           Disp Enb Address    What
2       breakpoint     keep y   0x565561df <main+70>
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/test 

Breakpoint 2, 0x565561df in main ()
(gdb) step
Single stepping until exit from function main,
which has no line number information.
0

Breakpoint 2, 0x565561df in main ()
(gdb) 
Single stepping until exit from function main,
which has no line number information.
1

Breakpoint 2, 0x565561df in main ()
(gdb) 
Single stepping until exit from function main,
which has no line number information.
2

Breakpoint 2, 0x565561df in main ()
(gdb) 
Single stepping until exit from function main,
which has no line number information.
3

Breakpoint 2, 0x565561df in main ()
(gdb) 
Single stepping until exit from function main,
which has no line number information.
4

Breakpoint 2, 0x565561df in main ()

不幸的是,这是一个临时解决方案,只是为了处理断点,它与崩溃问题无关。

【问题讨论】:

  • 您是否使用 csh 作为默认 shell?可能相关:stackoverflow.com/q/10472184/72178.
  • 不,我的默认 shell 是 bash
  • 在运行程序之前尝试set debug infrun 1。 GDB 将打印有关程序启动期间发生的更多信息。

标签: crash gdb


【解决方案1】:

您很可能尝试使用此命令break *0x000011ef 在无效地址处设置断点。 0x11ef 是该指令在 ELF 段内的偏移量,但程序在加载/启动时将被重新定位。

您应该尝试start,然后尝试disas main,然后放置断点。

GDB 像这样停止是当 GDB 在尝试放置断点时抛出错误时发生的错误,它已在上游 GDB 中通过此补丁修复:

https://sourceware.org/ml/gdb-patches/2019-05/msg00361.html

一旦你看到 GDB 像这样停止:

[1]+ 已停止 gdb soQuestionProgram

你应该被扔回一个shell。只需使用fg 命令恢复 GDB 并继续您的调试会话。 GDB 8.4 发布后,此错误将得到修复。

【讨论】:

  • 好吧,我在另一台 linux 机器上尝试了相同的断点,它工作正常,(GDB 7.4.1),然后我在我原来的机器上尝试了相同的 GDB,结果相同:(我使用Kali Linux 2019.3
  • 如果在失败的机器上你只是尝试start 然后disas main,我强烈怀疑你会看到main 不在你认为的位置。此外,GDB 7.4.1 可能在我上面链接的错误被引入之前,我不确定错误何时出现,这可能是您没有看到 SIGSTOP 的原因。
  • 谢谢,这个建议很有帮助,我已经执行了命令:start,然后断点工作正常,当我在另一台机器上尝试不使用 start 命令时,它说内存地址无效 没有崩溃所以这是一个临时解决方案,它与崩溃问题无关。
  • 正如我所说,这是 GDB 中的一个错误,当 GDB 无法插入断点时触发,并将在下一个 GDB 版本中修复。我(错误地,我猜)假设您实际上想要插入一个有用的断点,而不仅仅是触发 GDB 错误,这就是为什么我还建议您如何设置一个有用的断点。我猜每个人都有自己的:)
【解决方案2】:

一直这样

首先:GDB 没有崩溃。它只是被阻止了(被你的外壳)。您可以使用 shell fg 命令将其取回。

第二:这与 GDB 无关,与您的终端配置有关。使用reset可以解决这个问题。

【讨论】:

  • reset 命令不起作用,fg 命令将我带回 gdb。我尝试使用不同的终端模拟器和相同的结果,加上使用不同的外壳和相同的结果,也许这与.bashrc有关?
猜你喜欢
  • 2012-08-07
  • 2016-07-09
  • 1970-01-01
  • 2022-09-24
  • 1970-01-01
  • 2015-12-17
  • 1970-01-01
  • 2011-11-22
  • 2016-08-22
相关资源
最近更新 更多