2011-10-11 3 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

위대한 답변, 고마워요 Logged –

0

편집 : 분명히하지 않았을 수 있기 때문에 내 지점을 명확하게하자 . 기본적으로 GDB는 ASLR을 사용하지 않으므로 변수가 항상 동일한 주소를 갖습니다 (코드가 변경되거나, 변수 또는 코드를 추가하기 전 또는 후에 코드가 할당 된 주소에서 시프트를 일으켜 실패 할 수있는 경우가 아니면). 이렇게하면 하드 코딩 된 주소가 GDB에서 실행되는 동안 동일한 위치에 있기 때문에 코드가 성공합니다. 이는 주소가 디버깅 세션에서 디버깅 세션으로 변경되지 않기 때문에 디버깅에 도움이됩니다.

+0

이렇게 효과적으로 gdb가 ASLR을 끕니까? –

+0

그래, 그리고 다른 것들뿐만 아니라 귀하의 질문에 ASLR 중요한 비트입니다. 또한 2 개의 동시 스레드 만 허용합니다 (이전 버전에서는 새로운 스레드에 대해 최소한 말하지 않습니다). 몇 가지 다른 제한 사항이 있습니다. –

+0

하지만 어떻게 할 수 있는지 이해하지 못합니다. 나는 ASLR이 sysctls 나 다른 특권 수단을 통해서만 설정/해제 될 수 있다는 것을 의미합니까? 루트 권한이나 setuid가없는 gdb가 어떻게 관리합니까? –

관련 문제