Debugging 想知道在gdb中接收seg故障时会发生什么吗

Debugging 想知道在gdb中接收seg故障时会发生什么吗,debugging,segmentation-fault,gdb,Debugging,Segmentation Fault,Gdb,也许初学者程序中最常见的错误是它包含seg错误。但是,当使用gdb进行调试时,我无法确切了解seg故障是什么以及它是如何发生的。例如,gdb调试器将在main.c:13:bool flag=false中发出program received SEGMENTATION FAULT或program received SEGMENTATION FAULT。(事实上,我相信一个程序不会因为bool变量的定义而收到seg fault。肯定还有其他的东西)类似的东西 但这还不够具体,信息量也不够。我想知道导致

也许初学者程序中最常见的错误是它包含seg错误。但是,当使用gdb进行调试时,我无法确切了解seg故障是什么以及它是如何发生的。例如,gdb调试器将在main.c:13:bool flag=false中发出
program received SEGMENTATION FAULT
program received SEGMENTATION FAULT。(事实上,我相信一个程序不会因为bool变量的定义而收到seg fault。肯定还有其他的东西)类似的东西

但这还不够具体,信息量也不够。我想知道导致seg故障的具体变量及其位置。例如,如果我在一个没有初始化的函数中定义一个指针
a
,然后在之后使用它,我通常会收到seg fault。我希望gdb准确地告诉我,是变量
A
导致seg故障,其值和位置是

有什么想法吗?

回溯(bt)和变量的源代码行/打印输出通常足以诊断问题的原因。为此,您需要使用调试信息构建,而不需要进行大多数优化(-GCC中的O0-g3)


或者尝试一些不同的工具,例如,它使诊断内存分配问题变得更容易。

好吧,我将举一个简单的例子,如下所示

#include <stdio.h>

void main()
{
int *p=NULL;
printf("I Should be coring now");
printf("%d", *p);
}
(gdb) disas /m main
Dump of assembler code for function main:
4       {
   0x080483c4 <+0>:     push   %ebp
   0x080483c5 <+1>:     mov    %esp,%ebp
   0x080483c7 <+3>:     and    $0xfffffff0,%esp
   0x080483ca <+6>:     sub    $0x20,%esp

5       int *p=NULL;
   0x080483cd <+9>:     movl   $0x0,0x1c(%esp)

6       printf("I Should be coring now");
   0x080483d5 <+17>:    mov    $0x80484c4,%eax
   0x080483da <+22>:    mov    %eax,(%esp)
   0x080483dd <+25>:    call   0x80482f4 <printf@plt>

7       printf("%d", *p);
   0x080483e2 <+30>:    mov    0x1c(%esp),%eax
=> 0x080483e6 <+34>:    mov    (%eax),%edx
   0x080483e8 <+36>:    mov    $0x80484db,%eax
   0x080483ed <+41>:    mov    %edx,0x4(%esp)
   0x080483f1 <+45>:    mov    %eax,(%esp)
   0x080483f4 <+48>:    call   0x80482f4 <printf@plt>

8       }
   0x080483f9 <+53>:    leave
   0x080483fa <+54>:    ret

End of assembler dump.
(gdb)
在这个琐碎的例子中,它是非常直接的。但出于名义的考虑,让我们假设,我们需要更多的信息。现在,让我们在出现SIGSEGV时,尝试查找
pc
pc
有效地表示,在执行特定指令时,核心发生了

Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.SCLC6_4.5.R1.1.1.i686
(gdb) info registers
eax            0x0      0
ecx            0xbffff6f8       -1073744136
edx            0x2c5340 2904896
ebx            0x2c3ff4 2899956
esp            0xbffff710       0xbffff710
ebp            0xbffff738       0xbffff738
esi            0x0      0
edi            0x0      0
eip            0x80483e6        0x80483e6 <main+34>
eflags         0x10292  [ AF SF IF RF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51

虽然这可能不是开箱即用的,但根据我的经验,它将提供接近90%的准确性。

在gdb下运行程序时出现错误后,命令
print flag
print&flag
输出了什么?非常感谢您的回答。我从中学到了很多。但是,顺便问一下,你的答案中的
pc
是什么?还有,当您键入command
info register
时,这些
eip
esp
ebp
…的确切含义是什么?(虽然我知道什么是寄存器,但我真的不知道它们是什么意思。另外,如果可以的话,请你回答另一个关于我的
gdb
的问题好吗?我已经尝试了答案中提供的解决方案,但是,该解决方案(
wat-location var
)似乎在大多数情况下都会导致我出现
seg故障
(gdb) disas /m main
Dump of assembler code for function main:
4       {
   0x080483c4 <+0>:     push   %ebp
   0x080483c5 <+1>:     mov    %esp,%ebp
   0x080483c7 <+3>:     and    $0xfffffff0,%esp
   0x080483ca <+6>:     sub    $0x20,%esp

5       int *p=NULL;
   0x080483cd <+9>:     movl   $0x0,0x1c(%esp)

6       printf("I Should be coring now");
   0x080483d5 <+17>:    mov    $0x80484c4,%eax
   0x080483da <+22>:    mov    %eax,(%esp)
   0x080483dd <+25>:    call   0x80482f4 <printf@plt>

7       printf("%d", *p);
   0x080483e2 <+30>:    mov    0x1c(%esp),%eax
=> 0x080483e6 <+34>:    mov    (%eax),%edx
   0x080483e8 <+36>:    mov    $0x80484db,%eax
   0x080483ed <+41>:    mov    %edx,0x4(%esp)
   0x080483f1 <+45>:    mov    %eax,(%esp)
   0x080483f4 <+48>:    call   0x80482f4 <printf@plt>

8       }
   0x080483f9 <+53>:    leave
   0x080483fa <+54>:    ret

End of assembler dump.
(gdb)