Viết mã ngắn nhất làm tăng Phân đoạn Lỗi (SIGSEGV) bằng bất kỳ ngôn ngữ lập trình nào.
Viết mã ngắn nhất làm tăng Phân đoạn Lỗi (SIGSEGV) bằng bất kỳ ngôn ngữ lập trình nào.
Câu trả lời:
main;
Đó là một khai báo biến - int
loại được ngụ ý (tính năng được sao chép từ ngôn ngữ B) và 0
là giá trị mặc định. Khi được thực thi, điều này cố gắng thực thi một số (số không thực thi được) và nguyên nhân SIGSEGV
.
0
. static
biến bắt đầu như 0
, và main;
là static
, như tôi đã tuyên bố chức năng bên ngoài. c-faq.com/decl/initval.html
main
int, nó nằm ở đó .bss
, thường là các hàm được đặt trong .text
, khi kernel tải chương trình elf, nó tạo ra một trang thực thi cho .text
và không -có thể thực hiện được .bss
, vì vậy bằng cách gọi main, bạn chuyển đến một trang không thể thực thi và thực thi một cái gì đó trên một trang như vậy là một lỗi bảo vệ.
main __attribute__((section(".text#")))=0xc3;
FTFY (ít nhất là nó dường như quay trở lại mà không gặp sự cố trên x86 của tôi).
const main=195;
. Điều thú vị là nó hoạt động, mục tiêu của thử thách chơi gôn mã này là làm cho mã segfault, không hoạt động :).
kill -11 $$
RET
Mã này segfaults.
exec'()'*7**6
Windows báo cáo mã lỗi của c00000fd (Stack Overflow) mà tôi cho rằng đó là một kiểu con của lỗi phân đoạn.
Nhờ Alex A. và Mego, nó được xác nhận là gây ra lỗi phân đoạn trên các hệ thống Mac và Linux. Python là ngôn ngữ được lựa chọn để phá vỡ chương trình của bạn.
Segmentation fault: 11
trên Mac
Segmentation fault (core dumped)
trên Linux
\def~#1{\meaning}\write0{\expandafter~\string}\bye
Đây thực sự có thể là một lỗi , nhưng nó không có trong TeX gốc, được viết bởi Knuth: biên dịch mã tex filename.tex
thay vì pdftex filename.tex
không tạo ra một segfault.
OBTW
Không hoạt động trực tuyến, chỉ trong trình thông dịch C.
>>> import ctypes;ctypes.string_at(0)
Segmentation fault
Nguồn: http://bugs.python.org/su1215#msg143236
>>> import sys;sys.setrecursionlimit(1<<30);f=lambda f:f(f);f(f)
Segmentation fault
Nguồn: http://svn.python.org/view/python/trunk/Lib/test/crashers/recursive_call Shikview=markup
Đây là phiên bản Python tôi đang thử nghiệm trên:
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Nói chung, trình thông dịch Python khó gặp sự cố, nhưng ở trên là lạm dụng có chọn lọc ...
main(){raise(11);}
int func()
. tức là một hàm trả về int
, lấy tham số không xác định. Trong trường hợp raise
này là một hàm trả về int, lấy một đối số int, vì vậy điều này sẽ hoạt động (ngay cả khi trình biên dịch phàn nàn).
/(?{??})/
Trong 5.14, công cụ regex đã được thực hiện lại để nó không thể bị hỏng theo cách này, nhưng 5.12 và trước đó sẽ phân tách nếu bạn thử cách này.
Điều này có vẻ kỳ lạ, nhưng trên các hệ thống Windows 32 bit, việc tạo và thực thi một tệp .com trống có thể gây ra một segfault, tùy thuộc vào ... một cái gì đó. DOS chỉ chấp nhận nó (8086 không có quản lý bộ nhớ, không có lỗi phân đoạn có ý nghĩa) và Windows 64 bit từ chối chạy nó (x86-64 không có chế độ v86 để chạy tệp .com).
<.
Vâng, điều này phụ thuộc vào việc thực hiện. SIGSEGV là kết quả có khả năng từ một trình biên dịch tốt.
<
hoặc không có tác dụng hoặc bao quanh.
foreign import ccall main::IO()
Điều này tạo ra một segfault khi được biên dịch với GHC và chạy. Không cần cờ mở rộng, vì Giao diện chức năng nước ngoài nằm trong tiêu chuẩn Haskell 2010.
Phiên bản C là:
*(int*)0=0;
Toàn bộ chương trình (không hoàn toàn tuân thủ ISO, giả sử đó là K & R C) dài 19 ký tự:
main(){*(int*)0=0;}
Biến thể lắp ráp:
orl $0,0
Toàn bộ chương trình dài 24 ký tự (chỉ để đánh giá, vì nó không thực sự là trình biên dịch):
main(){asm("orl $0,0");}
CHỈNH SỬA :
Một vài biến thể C. Cái đầu tiên sử dụng khởi tạo không của biến con trỏ toàn cục:
*p;main(){*p=0;}
Cái thứ hai sử dụng đệ quy vô hạn:
main(){main();}
Biến thể cuối cùng là một ký tự ngắn nhất - 7 (15).
EDIT 2 :
Phát minh thêm một biến thể ngắn hơn bất kỳ ký tự nào ở trên - 6 (14) ký tự. Nó giả định rằng các chuỗi chữ được đưa vào một phân đoạn chỉ đọc.
main(){*""=0;}
EDIT 3 :
Và lần thử cuối cùng của tôi - dài 1 ký tự:
P
Chỉ cần biên dịch nó như thế:
cc -o segv -DP="main(){main();}" segv.c
main
này là biến int toàn cục được khởi tạo bằng 0, vì vậy những gì chúng ta nhận được là kết quả của việc cố gắng thực thi một số byte bằng không. Trong x86 add %al,(%rax)
, đó là một hướng dẫn hoàn toàn hợp lệ, cố gắng tiếp cận bộ nhớ tại địa chỉ được lưu trữ %rax
. Cơ hội có một địa chỉ tốt là tối thiểu.
[dx0]dx
gây ra tràn ngăn xếp
[dx0]
lưu trữ dx0
trên ngăn xếp, sau đó d
sao chép phần tử ngăn xếp trên cùng, sau đó x
bật phần tử ngăn xếp trên cùng ( dx0
) và thực thi nó. Sao chép phần tử ngăn xếp trên cùng và bắt đầu thực thi nó ... 0
cần phải ở đó để ngăn chặn đây là một cuộc gọi đuôi, vì vậy tất cả chúng đều được xây dựng.
Một giải pháp hơi gian lận là loại bỏ một trò lừa bịp của Joey Adams :
kill 11,$$
Tuy nhiên, để có được một segfault thực sự trong Perl, unpack p
là giải pháp rõ ràng:
unpack p,1x8
Về mặt kỹ thuật, điều này không được đảm bảo cho segfault, vì địa chỉ 0x31313131 (hoặc 0x313131313131313131 trên các hệ thống 64 bit) chỉ có thể chỉ đến không gian địa chỉ hợp lệ. Nhưng tỷ lệ cược chống lại nó. Ngoài ra, nếu perl được chuyển đến các nền tảng nơi con trỏ dài hơn 64 bit, thì x8
sẽ cần phải tăng lên.
1x8
cái gì
"11111111".
Obj.magic 0 0
Điều này sử dụng chức năng Obj.magic
, mà không ép buộc bất kỳ hai loại. Trong trường hợp này, nó ép buộc 0 (được lưu dưới dạng giá trị ngay lập tức 1, do bit thẻ được sử dụng bởi GC) thành một loại hàm (được lưu dưới dạng con trỏ). Vì vậy, nó cố gắng hủy đăng ký địa chỉ 1, và điều đó tất nhiên sẽ segfault.
it coerces 0 (stored as the immediate value 1)
- tại sao 0 được lưu dưới dạng 1?
Obj.magic()0
là một char ngắn hơn :)
Chơi gôn
. $0
Đệ quy bao gồm các kịch bản vào chính nó.
Giải thích
Hoạt động "nguồn" đệ quy (.) Cuối cùng gây ra tràn ngăn xếp và vì Bash không tích hợp với libsigsegv , điều này dẫn đến SIGSEGV.
Lưu ý rằng đây không phải là một lỗi, mà là một hành vi dự kiến, như được thảo luận ở đây .
Kiểm tra
./bang
Segmentation fault (core dumped)
⌠[]+⌡9!*.
Nếu ở trên không gặp sự cố, hãy thử tăng số (số có nhiều chữ số được chỉ định trong Thực tế với dấu hai chấm đầu)
Làm hỏng trình thông dịch bằng cách khai thác một lỗi trong python liên quan đến các itertools.chain
đối tượng lồng nhau sâu , mà thực sự sử dụng để thực hiện +
toán tử.
System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr.Zero);
unsafe{int i=*(int*)0;}
Phải biên dịch với / không an toàn để cái này hoạt động. Vì một số lý do tôi không hiểu, *(int*)0=0
chỉ cần ném NullReferenceException, trong khi phiên bản này cung cấp vi phạm quyền truy cập phù hợp.
int i=*(int*)0;
về một NullReferenceException cho tôi.
*(int*)-1=0
và vi phạm quyền truy cập.
*(int*)0=0
ném một ngoại lệ có thể là do tối ưu hóa. Cụ thể, để tránh chi phí kiểm tra null
, trình tối ưu hóa có thể loại bỏ kiểm tra null, nhưng khi xảy ra lỗi segfault, nó có thể điều chỉnh lại nó như một cách thích hợp NullReferenceException
.
$ pil
: ('0)
Segmentation fault
Đây là hành vi dự định. Theo mô tả trên trang web của họ:
Nếu một số ngôn ngữ lập trình tự xưng là "Con dao lập trình của quân đội Thụy Sĩ", thì PicoLisp có thể được gọi là "Con dao lập trình": Sắc bén, chính xác, nhỏ và nhẹ, nhưng cũng nguy hiểm trong tay người thiếu kinh nghiệm.
real,pointer::p(:)=>null()
p(1)=0.
end
Tổng hợp:
gfortran segv.f90 -o segv
Chấp hành:
./segv
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7FF85FCAE777
#1 0x7FF85FCAED7E
#2 0x7FF85F906D3F
#3 0x40068F in MAIN__ at segv.f90:?
Erreur de segmentation (core dumped)
Nguyên vật liệu:
gfortran --version
GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
main(a){*(&a-1)=1;}
Nó làm hỏng giá trị địa chỉ trả về của hàm chính, do đó, nó nhận được SIGSEGV khi trả về main
.
(điều này đang trở thành một chủ đề với tôi, có lẽ bởi vì đó là ngôn ngữ duy nhất tôi biết mà không ai khác ở đây làm.)
inc(r0)
Tăng các byte đơn được đánh địa chỉ theo giá trị ban đầu của r0 [xảy ra là 05162 theo trình gỡ lỗi simh] khi bắt đầu chương trình.
0000000 000407 000002 000000 000000 000000 000000 000000 000000
0000020 005210 000000
Và, như mọi khi, các byte ngoại lai ở cuối có thể được loại bỏ bằng dải.
Tôi đã thực hiện một vài nỗ lực để rút ngắn nguồn, nhưng cuối cùng luôn bị lỗi cú pháp hoặc SIGBUS.
Trả lời câu hỏi của tôi, Amro đã đưa ra cách giải quyết này:
S = struct();
S = setfield(S, {}, 'g', {}, 0)
clear()
Xóa tất cả mọi thứ, không chỉ phạm vi hiện tại mà rõ ràng gây ra rất nhiều nút, điều này dẫn đến việc JS nổ tung và phân tách
j1Z
Đây sẽ là phần mà tôi giải thích làm thế nào tôi đưa ra câu trả lời này, ngoại trừ tôi hợp pháp không có manh mối . Nếu bất cứ ai có thể giải thích điều này cho tôi, tôi sẽ biết ơn.
Đây là một thông dịch viên trực tuyến.
Giải trình
j
bình phương cơ sở và gọi chính nó đệ quy cho đến khi cơ sở ít nhất bằng số lượng. Vì cơ sở là 0 , điều đó không bao giờ xảy ra. Với giới hạn đệ quy cao, bạn sẽ có được một segfault.
j
trên 1
và 0
, mà cố gắng để chuyển đổi 1
thành cơ sở 0
. Tại sao lại có sự phân biệt đó, tôi không biết ...