2011-10-11 57 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如何設法做到這一點? –

相關問題