2011-10-11 6 views
6

Dlaczego podczas uruchamiania kodu z gdb otrzymuję te same adresy dla zadeklarowanych zmiennych, ale podczas wykonywania binarnego nie mam tych samych adresów.Dlaczego adres zmiennej lokalnej zmienia się podczas wykonywania wiele razy, ale nie podczas debugowania go za pomocą 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)); 
} 

Uruchomiłem program przez gdb i nigdy 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 
$ 

Ale normalna realizacja programu zawsze daje SEGFAULT.

$ ./a.out 
Segmentation fault 

ja nie wiem, czy to pytanie jest duplikatem Is this always the address for GDB debug program?

UWAGA: Nie wyłączony ASLR

Odpowiedz

2

Powodem, dla którego zawsze uzyskuje się ten sam adres dla zmiennych lokalnych podczas działania w GDB, jest to, że GDB (w celu uproszczenia większości scenariuszy debugowania) wyłącza randomizację przestrzeni adresowej.

Możesz poprosić GDB o nie zrobić to z set disable-address-randomization off.

Dla ciekawych, wyłączenie randomizacji adresów dla bieżącego procesu wymaga , a nie wymaga żadnego przywileju i jest wykonywane przez wywołanie personality(2). Oto patch, który dodał tę funkcję.

+0

Świetna odpowiedź, dziękuję –

0

EDIT: Pozwól mi wyjaśnić mój punkt widzenia, gdyż nie mogło być jasne . GDB domyślnie wyłącza ASLR, więc twoje zmienne zawsze będą miały ten sam adres (chyba że kod zostanie zmieniony, dodanie zmiennych lub kodu przed lub nawet po, w niektórych przypadkach może spowodować zmiany w przypisanych adresach i spowodować, że się nie powiedzie). W ten sposób twój kod się powiedzie, ponieważ zakodowane adresy będą w tym samym miejscu podczas działania w GDB. Pomaga to w debugowaniu, ponieważ adresy nie zmieniają się z debugowania sesji do sesji debugowania.

+0

Tak skutecznie, gdb wyłącza ASLR? –

+0

Tak i kilka innych rzeczy, ale na twoje pytanie, ASLR to ważny kawałek. Pozwala również tylko na 2 równoczesne wątki (starsze wersje przynajmniej nie mogą mówić o nowszych) i ma kilka innych ograniczeń. –

+0

Ale nie rozumiem, jak to możliwe. Chodzi mi o to, że ASLR można ustawić/wyłączyć tylko poprzez sysctl lub inne uprzywilejowane sposoby, prawda? W jaki sposób gdb, bez uprawnień roota lub setuid, potrafi to zrobić? –

Powiązane problemy