Tại sao hạt nhân Linux tạo ra một segfault trên tràn ngăn xếp? Điều này có thể thực hiện gỡ lỗi rất khó xử khi alloca trong c hoặc fortran tạo ra các mảng tràn tạm thời. Chắc chắn nó có thể được điều chỉnh cho thời gian chạy để tạo ra một lỗi hữu ích hơn.Segfault trên ngăn xếp tràn
Trả lời
"hạt nhân" (thực ra không phải hạt nhân đang chạy mã của bạn, đó là CPU) không biết mã của bạn tham chiếu đến bộ nhớ mà nó không được phép chạm vào. Nó chỉ biết rằng bạn đã cố gắng để làm điều đó.
Mã:
char *x = alloca(100);
char y = x[150];
có thể không thực sự được đánh giá bởi các CPU như bạn cố gắng truy cập vượt quá giới hạn của x.
Bạn có thể nhấn địa chỉ chính xác cùng với:
char y = *((char*)(0xdeadbeef));
BTW, tôi sẽ không khuyến khích việc sử dụng alloca kể từ khi chồng có xu hướng hạn chế hơn nhiều so với đống (sử dụng malloc thay).
Lỗi tràn ngăn xếp là lỗi phân đoạn. Như trong bạn đã phá vỡ giới hạn nhất định của bộ nhớ mà bạn ban đầu được phân bổ. Chồng của kích thước hữu hạn, và bạn đã vượt quá nó. Bạn có thể đọc thêm về nó tại wikipedia
Ngoài ra, một điều tôi đã thực hiện cho các dự án trong quá khứ là viết trình xử lý tín hiệu của riêng mình để phân đoạn (xem tín hiệu trang người đàn ông (2)). Tôi thường bắt được tín hiệu và viết ra "Đã xảy ra lỗi nghiêm trọng" cho bảng điều khiển. Tôi đã làm một số công cụ hơn nữa với cờ checkpoint, và gỡ lỗi.
Để gỡ lỗi segfaults, bạn có thể chạy chương trình trong GDB. Ví dụ, chương trình C sau đây sẽ segfault: # segfault.c #include #include
int main()
{
printf("Starting\n");
void *foo=malloc(1000);
memcpy(foo, 0, 100); //this line will segfault
exit(0);
}
Nếu tôi biên dịch nó như vậy:
gcc -g -o segfault segfault.c
và sau đó chạy nó như vậy:
$ gdb ./segfault
GNU gdb 6.7.1
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) run
Starting program: /tmp/segfault
Starting
Program received signal SIGSEGV, Segmentation fault.
0x4ea43cbc in memcpy() from /lib/libc.so.6
(gdb) bt
#0 0x4ea43cbc in memcpy() from /lib/libc.so.6
#1 0x080484cb in main() at segfault.c:8
(gdb)
Tôi tìm hiểu từ GDB rằng có lỗi phân đoạn trên dòng 8. Tất nhiên có nhiều cách xử lý phức tạp hơn ck tràn và các lỗi bộ nhớ khác, nhưng điều này sẽ đủ.
Chỉ cần sử dụng Valgrind. Nó sẽ chỉ ra tất cả các lỗi phân bổ bộ nhớ của bạn với độ chính xác tuyệt vời.
Bạn thực sự có thể bắt tình trạng tràn ngăn xếp bằng cách sử dụng trình xử lý tín hiệu.
Để làm điều này, bạn phải làm hai việc:
Thiết lập một xử lý tín hiệu cho SIGSEGV (segfault) sử dụng sigaction, để làm điều này đặt cờ SO_ONSTACK. Điều này hướng dẫn hạt nhân sử dụng một chồng thay thế khi cung cấp tín hiệu.
Gọi sigaltstack() để thiết lập ngăn xếp thay thế mà trình xử lý cho SIGSEGV sẽ sử dụng.
Sau đó, khi bạn tràn ngăn xếp, hạt nhân sẽ chuyển sang ngăn thay thế của bạn trước khi gửi tín hiệu. Khi ở trong bộ xử lý tín hiệu của bạn, bạn có thể kiểm tra địa chỉ gây ra lỗi và xác định xem đó có phải là tràn ngăn xếp hay lỗi thường xuyên.
Lỗi tràn ngăn không nhất thiết gây ra sự cố. Nó có thể âm thầm thùng rác dữ liệu của chương trình của bạn nhưng vẫn tiếp tục thực hiện.
Tôi sẽ không sử dụng bộ xử lý SIGSEGV mà thay vào đó khắc phục sự cố ban đầu.
Nếu bạn muốn trợ giúp tự động, bạn có thể sử dụng tùy chọn -Wstack-protector của gcc, điều này sẽ phát hiện một số lỗi tràn vào thời gian chạy và hủy chương trình.
valgrind là tốt cho lỗi phân bổ bộ nhớ động, nhưng không phải cho lỗi ngăn xếp.
Một số nhận xét hữu ích, nhưng vấn đề không phải là lỗi phân bổ bộ nhớ. Đó là không có sai lầm trong mã. Nó khá phiền toái trong fortran, nơi thời gian chạy phân bổ các giá trị tạm thời trên stack. Vì vậy, một lệnh như ghi (fp) x, y, z có thể kích hoạt là segfault không có cảnh báo. Sự hỗ trợ kỹ thuật cho trình biên dịch Fortran intel nói rằng không có cách nào mà thư viện thời gian chạy có thể in một thông điệp hữu ích hơn. Tuy nhiên, nếu Miguel là đúng hơn điều này nên có thể như ông đề nghị. Cảm ơn rất nhiều Câu hỏi còn lại sau đó là làm thế nào để trước tiên tôi tìm thấy địa chỉ của lỗi seg và con số ra nếu nó đến từ một tràn ngăn xếp hoặc một số vấn đề khác.
Đối với những người khác tìm thấy sự cố này, có một lá cờ trình biên dịch đặt các chênh lệch tạm thời trên một kích thước nhất định trên heap.
- 1. Lỗi tràn ngăn xếp bảo vệ fread
- 2. AppDomain.FirstChanceException và ngoại lệ tràn ngăn xếp
- 3. Ngoại lệ tràn ngăn xếp — tại sao?
- 4. Kích thước ngăn xếp còn lại cho đến khi tràn ngăn xếp xảy ra
- 5. Lỗi tràn ngăn xếp Java - cách tăng kích thước ngăn xếp trong Eclipse?
- 6. Tôi không hiểu lỗi tràn ngăn xếp với DispatchMessageW lặp lại trong ngăn xếp cuộc gọi
- 7. Làm thế nào để tràn ngăn xếp mà không cần đẩy khung ngăn xếp mới?
- 8. Lỗi tràn ngăn xếp trong C# set/get
- 9. Tràn ngăn xếp khi sử dụng mô hình System.Net.Sockets.Socket.AcceptAsync
- 10. Tiêm tài sản với Unity gây tràn ngăn xếp
- 11. Thẻ câu hỏi tràn ngăn xếp Hộp văn bản
- 12. Lỗi tràn ngăn xếp khi nhập WSDL vào Delphi 7
- 13. Ngăn xếp ngăn xếp là gì?
- 14. C# bắt một ngoại lệ tràn ngăn xếp
- 15. Chức năng đệ quy gây tràn ngăn xếp
- 16. Quá tải nhà khai thác gây ra tràn ngăn xếp
- 17. Làm thế nào để bẫy tràn ngăn xếp với pthread?
- 18. Ngăn xếp tràn từ đệ quy sâu trong Java?
- 19. Làm thế nào để tránh tràn ngăn xếp trong Haskell?
- 20. Làm thế nào để ngăn chặn tràn ngăn xếp bằng cách theo dõi kích thước ngăn xếp?
- 21. Sự khác biệt giữa tràn ngăn xếp và tràn bộ đệm là gì?
- 22. Gọi lại không được quản lý khiến ngăn xếp tràn tràn
- 23. onSharedPreferenceThay đổi đang gây ra tràn ngăn xếp trên một số thiết bị Android
- 24. Kích thước ngăn xếp tối đa, ulimit -s, segfault 11 - cách thức hoạt động?
- 25. Ngăn xếp ngăn xếp lạ?
- 26. URL ngăn xếp ngăn xếp hoạt động như thế nào?
- 27. C++ Ngăn xếp ngăn xếp Visual Studio với mảng 2D
- 28. Chức năng đệ quy, Ngăn xếp ngăn xếp và Bộ kết hợp Y
- 29. miễn phí() trên bộ nhớ ngăn xếp
- 30. Tạo đối tượng trên ngăn xếp/heap?
Mặc dù stackspace nhanh hơn rất nhiều cho thao tác trên nền cứng. Chỉ cần sử dụng một cách tiết kiệm. Ngoài ra, hãy kiểm tra "Getrlimit" trước khi thực hiện bất kỳ alloca nào. Hãy chắc chắn rằng bạn có đủ không gian còn lại! –