2011-10-11 24 views
6

Tại sao khi chạy mã từ gdb, tôi nhận được cùng địa chỉ cho các biến được khai báo, nhưng trong khi chỉ thực hiện nhị phân, tôi không nhận được cùng địa chỉ.Tại sao địa chỉ của biến cục bộ thay đổi khi thực thi nhiều lần, nhưng không phải khi gỡ lỗi với 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)); 
} 

Tôi đã chạy chương trình thông qua gdb và không bao giờ bị phân đoạn.

$ 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 
$ 

Nhưng việc thực hiện chương trình thông thường luôn tạo ra SEGFAULT.

$ ./a.out 
Segmentation fault 

Tôi không biết nếu câu hỏi này là một bản sao của Is this always the address for GDB debug program?

Chú ý: Tôi đã không tắt ASLR

Trả lời

2

Lý do bạn luôn nhận được cùng một địa chỉ cho các biến cục bộ khi chạy dưới GDB là GDB (để đơn giản hóa hầu hết các trường hợp gỡ lỗi) vô hiệu hóa ngẫu nhiên không gian địa chỉ.

Bạn có thể yêu cầu GDB không làm điều đó với set disable-address-randomization off.

Vì tò mò, vô hiệu hóa địa chỉ ngẫu nhiên cho quy trình hiện tại, không yêu cầu bất kỳ đặc quyền nào và được thực hiện bằng cách gọi personality(2). Đây là số patch đã thêm tính năng này.

+0

Câu trả lời hay, cảm ơn –

0

EDIT: Hãy để tôi làm rõ quan điểm của tôi vì nó có thể không có được rõ ràng . GDB theo mặc định vô hiệu hóa ASLR vì vậy biến của bạn sẽ luôn có cùng địa chỉ (trừ khi mã thay đổi, thêm biến hoặc mã trước hoặc thậm chí sau trong một số trường hợp có thể gây ra thay đổi trong địa chỉ được gán và khiến lỗi đó bị lỗi). Bằng cách này, mã của bạn thành công bởi vì địa chỉ được mã hóa sẽ ở cùng một vị trí trong khi chạy trong GDB. Điều này giúp gỡ lỗi vì địa chỉ sẽ không thay đổi từ phiên gỡ lỗi thành phiên gỡ lỗi.

+0

Vì vậy, hiệu quả, gdb tắt ASLR? –

+0

Vâng và một số thứ khác nữa nhưng đối với câu hỏi của bạn ASLR là bit quan trọng. Nó cũng chỉ cho phép 2 luồng đồng thời (các phiên bản cũ hơn ít nhất không thể nói về các luồng mới hơn) và có một số hạn chế khác. –

+0

Nhưng tôi không hiểu làm thế nào nó có thể làm điều đó. Tôi có nghĩa là ASLR có thể được thiết lập/unset chỉ thông qua sysctls hoặc phương tiện đặc quyền khác, phải không? Làm thế nào để gdb, không có đặc quyền root hoặc setuid, quản lý để làm điều này? –

Các vấn đề liên quan