Tulis kode terpendek yang memunculkan Kesalahan Segmentasi (SIGSEGV) dalam bahasa pemrograman apa pun.
Tulis kode terpendek yang memunculkan Kesalahan Segmentasi (SIGSEGV) dalam bahasa pemrograman apa pun.
Jawaban:
main;
Ini adalah deklarasi variabel - int
jenis tersirat (fitur disalin dari bahasa B) dan 0
merupakan nilai default. Ketika dieksekusi ini mencoba untuk mengeksekusi angka (angka tidak dapat dieksekusi), dan menyebabkan SIGSEGV
.
0
. static
variabel mulai sebagai 0
, dan main;
adalah static
, seperti yang saya menyatakan fungsi luar. c-faq.com/decl/initval.html
main
int, itu terletak di .bss
, biasanya fungsi terletak di .text
, ketika kernel memuat program elf itu membuat halaman yang dapat dieksekusi untuk .text
dan non -dieksekusi untuk .bss
, jadi dengan memanggil utama, Anda melompat ke halaman yang tidak dapat dieksekusi, dan mengeksekusi sesuatu pada halaman tersebut adalah kesalahan perlindungan.
main __attribute__((section(".text#")))=0xc3;
FTFY (setidaknya tampaknya kembali tanpa menabrak x86 saya).
const main=195;
,. Yang menarik adalah bahwa itu berfungsi, tujuan dari tantangan golf kode ini adalah untuk membuat kode segfault, bukan bekerja :).
kill -11 $$
RET
Kode ini segfault.
exec'()'*7**6
Windows melaporkan kode kesalahan c00000fd (Stack Overflow) yang saya anggap sebagai subtipe dari kesalahan segmentasi.
Berkat Alex A. dan Mego, dipastikan menyebabkan kesalahan segmentasi pada sistem Mac dan Linux. Python adalah bahasa pilihan untuk crash program Anda.
Segmentation fault: 11
di Mac
Segmentation fault (core dumped)
di Linux
\def~#1{\meaning}\write0{\expandafter~\string}\bye
Ini sebenarnya mungkin bug , tetapi tidak ada dalam TeX asli, yang ditulis oleh Knuth: kompilasi kode dengan tex filename.tex
bukannya pdftex filename.tex
tidak menghasilkan segfault.
OBTW
Tidak bekerja online, hanya di C juru bahasa.
>>> import ctypes;ctypes.string_at(0)
Segmentation fault
Sumber: http://bugs.python.org/issue1215#msg143236
>>> import sys;sys.setrecursionlimit(1<<30);f=lambda f:f(f);f(f)
Segmentation fault
Sumber: http://svn.python.org/view/python/trunk/Lib/test/crashers/recursive_call.py?view=markup
Ini adalah versi Python yang saya uji pada:
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Secara umum interpreter Python sulit untuk crash, tetapi di atas adalah kekerasan selektif ...
main(){raise(11);}
int func()
. yaitu fungsi yang mengembalikan int
, mengambil parameter yang tidak ditentukan. Dalam hal ini raise
adalah fungsi mengembalikan int, mengambil argumen int, jadi ini berhasil (bahkan jika kompiler mengeluh).
/(?{??})/
Di 5.14, mesin regex dibuat reentrant sehingga tidak bisa crash dengan cara ini, tetapi 5.12 dan sebelumnya akan segfault jika Anda mencoba ini.
Ini akan terasa aneh, tetapi pada sistem Windows 32 bit, membuat dan mengeksekusi file .com kosong dapat menyebabkan segfault, tergantung pada ... sesuatu. DOS hanya menerimanya (8086 tidak memiliki manajemen memori, tidak ada segmen yang berarti untuk kesalahan), dan Windows 64 bit menolak untuk menjalankannya (x86-64 tidak memiliki mode v86 untuk menjalankan file .com).
<.
Ya, ini tergantung pada implementasi. SIGSEGV kemungkinan merupakan hasil dari kompiler yang baik.
<
seharusnya tidak memiliki efek atau membungkus.
foreign import ccall main::IO()
Ini menghasilkan segfault ketika dikompilasi dengan GHC dan dijalankan. Tidak ada bendera ekstensi yang diperlukan, karena Antarmuka Fungsi Asing ada dalam standar Haskell 2010.
Versi C adalah:
*(int*)0=0;
Seluruh program (tidak cukup sesuai dengan ISO, mari kita asumsikan K&R C) adalah 19 karakter:
main(){*(int*)0=0;}
Varian Assembler:
orl $0,0
Seluruh program panjangnya 24 karakter (hanya untuk evaluasi, karena sebenarnya bukan assembler):
main(){asm("orl $0,0");}
EDIT :
Beberapa varian C. Yang pertama menggunakan nol-inisialisasi variabel pointer global:
*p;main(){*p=0;}
Yang kedua menggunakan rekursi tak terbatas:
main(){main();}
Varian terakhir adalah yang terpendek - 7 (15) karakter.
EDIT 2 :
Diciptakan satu varian lagi yang lebih pendek daripada yang di atas - 6 (14) karakter. Diasumsikan bahwa string literal dimasukkan ke dalam segmen read-only.
main(){*""=0;}
EDIT 3 :
Dan percobaan terakhir saya - 1 karakter:
P
Kompilasi saja seperti itu:
cc -o segv -DP="main(){main();}" segv.c
main
adalah variabel int global diinisialisasi nol, jadi apa yang kita dapatkan adalah hasil dari mencoba mengeksekusi beberapa byte nol. Di x86 itu akan menjadi sesuatu add %al,(%rax)
yang merupakan instruksi yang benar-benar valid yang mencoba untuk mencapai memori di alamat yang disimpan %rax
. Peluang memiliki alamat yang bagus ada sedikit.
[dx0]dx
menyebabkan stack overflow
[dx0]
menyimpan dx0
di stack, lalu d
menduplikasi elemen tumpukan atas, lalu x
muncul elemen tumpukan atas ( dx0
) dan menjalankannya. Yang menduplikasi elemen tumpukan atas, dan mulai menjalankannya ... 0
perlu ada di sana untuk mencegah ini menjadi panggilan ekor, sehingga mereka semua membangun.
Solusi yang sedikit curang adalah mencukur satu char dari trik bash Joey Adams :
kill 11,$$
Namun, untuk mendapatkan segfault nyata di Perl, unpack p
adalah solusi yang jelas:
unpack p,1x8
Secara teknis, ini tidak dijamin untuk segfault, karena alamat 0x31313131 (atau 0x313131313131313131 pada sistem 64-bit) mungkin saja menunjuk ke ruang alamat yang valid secara kebetulan. Tetapi kemungkinan besar menentangnya. Juga, jika perl pernah porting ke platform di mana pointer lebih panjang dari 64 bit, maka x8
perlu ditingkatkan.
1x8
?
"11111111".
Obj.magic 0 0
Ini menggunakan fungsi Obj.magic
, yang memaksa dua jenis dengan tidak aman. Dalam hal ini, ia memaksa 0 (disimpan sebagai nilai langsung 1, karena bit tag yang digunakan oleh GC) ke tipe fungsi (disimpan sebagai pointer). Dengan demikian, ia mencoba untuk merujuk alamat 1, dan itu tentu saja akan segfault.
it coerces 0 (stored as the immediate value 1)
- mengapa 0 disimpan sebagai 1?
Obj.magic()0
satu karakter lebih pendek :)
Golf
. $0
Secara rekursif memasukkan skrip ke dalam dirinya sendiri.
Dijelaskan
Operasi "sumber" (.) Rekursif akhirnya menyebabkan stack overflow, dan karena Bash tidak berintegrasi dengan libsigsegv , ini menghasilkan SIGSEGV.
Perhatikan bahwa ini bukan bug, tetapi perilaku yang diharapkan, seperti yang dibahas di sini .
Uji
./bang
Segmentation fault (core dumped)
⌠[]+⌡9!*.
Jika hal di atas tidak macet, coba tambah angkanya (angka multi-digit ditentukan dalam Sebenarnya dengan tanda titik dua)
Hancurkan interpreter dengan mengeksploitasi bug dalam python yang melibatkan itertools.chain
objek bersarang dalam , yang sebenarnya digunakan untuk mengimplementasikan +
operator.
System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr.Zero);
unsafe{int i=*(int*)0;}
Harus dikompilasi dengan / tidak aman agar yang ini berfungsi. Untuk beberapa alasan saya tidak mengerti, *(int*)0=0
hanya melempar NullReferenceException, sementara versi ini memberikan pelanggaran akses yang tepat.
int i=*(int*)0;
kembali NullReferenceException bagi saya.
*(int*)-1=0
dan mendapatkan pelanggaran akses.
*(int*)0=0
melempar pengecualian kemungkinan karena optimasi. Khususnya, untuk menghindari biaya pemeriksaan null
, pengoptimal dapat menghapus cek nol, tetapi ketika segfault terjadi, pengemasan ulang mungkin dianggap tepat NullReferenceException
.
$ pil
: ('0)
Segmentation fault
Ini adalah perilaku yang dimaksudkan. Seperti yang dijelaskan di situs web mereka:
Jika beberapa bahasa pemrograman mengklaim sebagai "Pisau Pemrograman Swiss Army", maka PicoLisp mungkin disebut "Pisau Bedah Pemrograman": Tajam, akurat, kecil dan ringan, tetapi juga berbahaya di tangan yang tidak berpengalaman.
real,pointer::p(:)=>null()
p(1)=0.
end
Kompilasi:
gfortran segv.f90 -o segv
Eksekusi:
./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)
Bahan:
gfortran --version
GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
main(a){*(&a-1)=1;}
Ini merusak nilai alamat pengirim fungsi utama, sehingga mendapat SIGSEGV saat kembali dari main
.
(Ini menjadi tema bagi saya, mungkin karena itu satu-satunya bahasa yang saya tahu tidak ada orang lain di sini.)
inc(r0)
Menambah byte tunggal yang dialamatkan oleh nilai awal r0 [yang kebetulan 05162 menurut simh debugger] pada saat program dimulai.
0000000 000407 000002 000000 000000 000000 000000 000000 000000
0000020 005210 000000
Dan, seperti biasa, byte asing di bagian akhir dapat dihapus dengan strip.
Saya melakukan beberapa upaya untuk mendapatkan sumber yang lebih pendek, tetapi selalu mendapatkan kesalahan sintaks atau SIGBUS.
Menanggapi pertanyaan saya, Amro mengajukan pertanyaan aneh ini:
S = struct();
S = setfield(S, {}, 'g', {}, 0)
clear()
Membersihkan segalanya, bukan hanya lingkup saat ini yang jelas menyebabkan banyak borks yang mengakibatkan JS meledak dan tersegmentasi
j1Z
Ini akan menjadi bagian di mana saya menjelaskan bagaimana saya mendapatkan jawaban ini, kecuali saya tidak memiliki petunjuk . Jika ada yang bisa menjelaskan ini untuk saya, saya akan berterima kasih.
Ini dia dalam juru bahasa online.
Penjelasan
j
kuadratkan pangkalan dan menyebut dirinya secara rekursif sampai pangkalan setidaknya sama besar dengan jumlahnya. Karena basisnya 0 , itu tidak pernah terjadi. Dengan batas rekursi yang cukup tinggi, Anda mendapatkan segfault.
j
aktif 1
dan 0
, yang mencoba mengubahnya 1
menjadi basis 0
. Mengapa segfaults, saya tidak tahu ...