2011-10-11 52 views
6

为什么从gdb运行代码时,我得到的声明变量的地址相同,但是在执行二进制文件时,我没有得到相同的地址。为什么一个局部变量的地址在执行多次时会有所不同,但在使用GDB进行调试时不会有所不同?

#include<stdio.h> 
void main() 
{ 
    int *x,q; 
    //I saw the address of the variable q in this program through gdb during the __1st__ execution. 
    //I re-compiled the program to make x to point to this address. 
    x=0x7fffffffe2bc; 
    *x=3; 
    printf("%d",(*x)); 
} 

我通过gdb运行程序,它从来没有Segfaulted。

$ gdb -q ./a.out 
Reading symbols from /home/eknath/needed2/a.out...done. 
(gdb) r 
Starting program: /home/eknath/needed2/a.out 
3 
Program exited normally. 
(gdb) q 
$ 

但是,正常执行程序总是会产生一个SEGFAULT。

$ ./a.out 
Segmentation fault 

我不知道这个问题是Is this always the address for GDB debug program?

注意重复:我还没有关闭ASLR

回答

2

在GDB下运行时,总是得到与本地变量相同的地址的原因是GDB(为了简化大多数调试场景)禁用地址空间随机化。

你可以问GDB到不是那么做set disable-address-randomization off

为了好奇,禁止当前进程的地址随机化,而不是需要任何特权,并通过调用personality(2)完成。这是添加此功能的patch

+0

很好的答案,谢谢 –

0

编辑:让我澄清一下我的观点,因为它可能没有明确的。 GDB默认禁用ASLR,因此您的变量将始终具有相同的地址(除非代码发生更改,在某些情况下添加变量或代码,在某些情况下可能会导致分配的地址发生变化并导致失败)。这样你的代码就成功了,因为硬编码地址在GDB中运行时会在同一个地方。这有助于调试,因为地址不会从调试会话更改为调试会话。

+0

如此有效地,gdb关闭ASLR? –

+0

是的,还有一些其他的东西,但对于你的问题ASLR是重要的一点。它也只允许2个并发线程(旧版本至少不能说更新的线程),还有一些其他限制。 –

+0

但我不明白它是如何做到的。我的意思是ASLR只能通过sysctl或其他特权方式设置/取消设置,对吧?没有root权限或setuid的gdb如何设法做到这一点? –

相关问题