Debugging 想知道在gdb中接收seg故障时会发生什么吗
也许初学者程序中最常见的错误是它包含seg错误。但是,当使用gdb进行调试时,我无法确切了解seg故障是什么以及它是如何发生的。例如,gdb调试器将在main.c:13:bool flag=false中发出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。肯定还有其他的东西)类似的东西 但这还不够具体,信息量也不够。我想知道导致
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
是什么?还有,当您键入commandinfo 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)