2012-05-12 23 views
6

Tôi thấy rằng khi chúng tôi sử dụng nested functions, GCC yêu cầu ngăn xếp thực thi cho trampoline code. Tuy nhiên, mã sau đây, khi được biên dịch bằng gcc không hiển thị ngăn xếp thực thi. (Tôi đã sử dụng execstack để xác minh xem ngăn xếp có thể thực thi được)Ví dụ về chồng thực thi trong Linux (kiến trúc i386)

#include <stdio.h> 
#include <unistd.h> 

int main() 
{ 
     int add(int a, int b) 
     { 
       return a + b; 
     } 
     return add(2, 3); 
} 

Tại sao điều này không dẫn đến chồng thực thi? Và nếu nó không phải là nghĩa vụ, sau đó ai đó có thể đưa ra ví dụ về một mã xây dựng mà không cho một chồng thực thi?

+0

Tôi nghĩ chức năng được xác định tại địa phương không cần chồng thực thi vì mã của họ vẫn còn lưu trữ trong phần mã tương tự như các chức năng khác, chứ không phải trên cây rơm. –

Trả lời

4

Nếu hàm lồng nhau không phụ thuộc vào "cha mẹ" của nó 's chồng ở tất cả, sau đó nó chỉ là một chức năng đơn giản - làm tổ là cú pháp (và phạm vi) đường.

Và nếu bạn không lấy địa chỉ của hàm lồng nhau, thì cũng không cần mã trampoline. Vì vậy, bạn sẽ cần một cái gì đó nhiều hơn một chút tham gia để kích hoạt tất cả những điều đó.

Dưới đây là một ví dụ giả:

// file t.c 
int doit(int (*fun)(int), int x) 
{ 
    return fun(x); 
} 

int foo(int a) 
{ 
     int add(int b) 
     { 
       return a + b; 
     } 
     return doit(&add, 2); 
} 

int main(void) 
{ 
    return foo(1); 
} 
$ gcc t.c 
t.c: In function 'foo': 
t.c:8:13: warning: trampoline generated for nested function 'add' 
$ ./a.out 
$ echo $? 
3 
$ execstack a.out 
X a.out 
2

Như đã nói trong liên kết của bạn http://gcc.gnu.org/onlinedocs/gccint/Trampolines.html

Một tấm bạt lò xo là một mảnh nhỏ của mã được tạo ra tại thời gian chạy khi địa chỉ của một hàm lồng nhau được lấy. Nó thường nằm trên ngăn xếp, trong khung ngăn xếp của hàm chứa.

Trong địa chỉ mẫu của bạn về lồng nhau không được thực hiện và gcc không cần sử dụng execstack.

Dưới đây là một ví dụ về mã với tấm bạt lò xo: ​​http://www.win.tue.nl/~aeb/linux/hh/protection.html

% cat trampoline.c 
#include <stdio.h> 
int main(int ac, char **av) { 
     int localfn(int a) { 
       return a+ac; 
     } 
     int (*fptr)(int) = localfn; 

     printf("%d\n", fptr(-1)); 
     return 0; 
} 
Các vấn đề liên quan