引发SIGSEGV的最短代码


Answers:


113

C,5个字符

main;

这是一个变量声明- int隐式类型(从B语言复制的功能),0是默认值。执行时,这会尝试执行一个数字(数字不可执行),并导致SIGSEGV

在线尝试!


5
@Macmade:实际上是0static变量的开头是0,现在main;static,正如我在函数外部声明的那样。c-faq.com/decl/initval.html
Konrad Borowski

16
上一次我玩这个东西时,我发现发生段错误的原因不同。首先,通过调用main跳转到main的位置,而不是值,另一件事是mainint,它位于中.bss,通常函数位于中.text,当内核加载elf程序时,它会为.textand 创建一个可执行页-executable for .bss,因此通过调用main可以跳转到不可执行的页面,并且在这样的页面上执行某些操作是保护错误。
mniip 2013年

23
是的,C语言中的段错误几乎是默认设置:P
Paul Draper 2014年

1
main __attribute__((section(".text#")))=0xc3;FTFY(至少它似乎返回而不会在我的x86上崩溃)。
jozxyqk

2
@jozxyqk或更短的名称const main=195;。有趣的是它正在工作,此代码挑战的目标是使代码段出错,而不是:)。
Konrad Borowski

74

Bash,11岁      

kill -11 $$

44
以11个字符表示信号11。似乎是合法的。
nyuszika7h 2013年

12
@ nyuszika7h我要对您的评论进行投票,但您目前有11票赞成,因此我将保留该意见。:P
HyperNeutrino

3
@AlexL。其他人似乎已经宠坏了:(
–onlygusti

2
@theonlygusti是的...太糟糕了。:(哦,那么我现在可以
投票。– HyperNeutrino

2
最多42个投票,无接触者!
seadoggie01

39

汇编(Linux,x86-64),1字节

RET

此代码段错误。


7
作为MSDOS .com文件,它运行并终止而没有错误。
JB

10
我的观点是:仅指定“ assembly”不足以使其成为段错误。
JB

52
@JB:在MS DOS上,任何程序都不会产生分段错误。这是因为MS DOS在不存在内存保护的实模式下运行。
celtschk 2012年

1
@celtschk IIRC NTVDM将在不存在的地址以及未分配给MS-DOS的地址上发出信号。
–ζ

2
@celtschk:您仍然可以像这样对它进行段错误:mov bx,1000h; shr ebx,4;mov eax,[ebx]-> CPU会提高底层的SEGV(虽然AFAIK没有人可以处理)。
约书亚

26

Python 2、13

exec'()'*7**6

Windows报告错误代码c00000fd(堆栈溢出),我认为这是分段错误的子类型。

感谢Alex A.和Mego,它也被确认会在Mac和Linux系统上引起分段错误。Python是用于使程序崩溃的首选语言。


7
Segmentation fault: 11在Mac上
Alex A.

7
Segmentation fault (core dumped)在Linux上
美高

这先挂吗?
洛克人

1
@MegaMan是否需要很长时间才能完成?不,7 ** 6仅约10万,因此没有明显的延迟。
feersum

为什么这样做?在Mac OS的Python 3.6.8上似乎没有。
Max Gasner

22

pdfTeX(51)

\def~#1{\meaning}\write0{\expandafter~\string}\bye

这实际上可能是一个bug,但是在Knuth编写的原始TeX中不存在:使用tex filename.tex代替编译代码pdftex filename.tex不会产生段错误。


21

LOLCODE,4个字节

OBTW

不能在线工作,只能在C解释器中工作。


24
哈哈FANCY CODE M8 8/8 KTHXBYE
Addison

17

Python,33个字符

>>> import ctypes;ctypes.string_at(0)
Segmentation fault

来源:http//bugs.python.org/issue1215#msg143236

Python,60个字符

>>> import sys;sys.setrecursionlimit(1<<30);f=lambda f:f(f);f(f)
Segmentation fault

来源:http : //svn.python.org/view/python/trunk/Lib/test/crashers/recursive_call.py?view=markup

这是我正在测试的Python版本:

Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin

一般来说,Python解释器很难崩溃,但以上是选择性的滥用行为...


16

第四-3个字符

0 @

@是提取)


1
到目前为止,最短的版本可以在现代系统上运行。
2015年

2
哪一个?Gforth只是说:“无效的内存地址”

15

C,18

main(){raise(11);}

您是否需要在代码清单中添加#include <signal.h>?
Florian Castellane

5
@FlorianCastellane:在C90及更低版本中,对于任何在没有可见声明的情况下完成的函数调用,编译器都会将其隐式声明为int func()。即返回int未指定参数的函数。在这种情况下raise,一个函数返回一个int并接受一个int参数,因此可以解决这个问题(即使编译器抱怨了)。
Hasturkun

14

Perl(<5.14),9个字符

/(?{??})/

在5.14中,将正则表达式引擎设为可重入,以使其无法以这种方式崩溃,但是如果您尝试这样做,则5.12及更早版本将出现段错误。


我可以在Perl 5.14(Debian)和5.18(Arch Linux)上重现它。sprunge.us/RKHT
nyuszika7h 2014年

与Perl v5.20.2(Windows)一起复制
Mehi

14

W32 .com可执行文件-0字节

这看起来很奇怪,但是在32位Windows系统上,创建并执行一个空的.com文件可能会导致segfault,具体取决于...。DOS只接受它(8086没有内存管理,没有有意义的段要出错),而64位Windows拒绝运行它(x86-64没有v86模式可以在其中运行.com文件)。


13

脑干(2)

<.

是的,这取决于实现。好的编译器可能会导致SIGSEGV。


4
编译器如何隔离“良好”状态?那<要么无效,要么环绕。
nyuszika7h 2014年

12
最好立即生成违反边界的运行时错误,因为它可使程序员尽快找到并修复该错误。在崩溃前让越野车程序运行一段时间并随意破坏内存只会使问题更难以诊断。正如您所建议的那样,完全防止崩溃是最糟糕的。程序员可以使程序“运行”,然后在标准编译器和解释器上崩溃时被公开羞辱。
Daniel Cristofani 2014年

1
相反,通常不可能在运行时之前捕获边界违例,在可能的情况下也特别有用。可以产生更具描述性的运行时错误,但是让操作系统将其作为段错误来捕获是很好的,因为它没有任何速度成本。(如果不清楚,则编译器本身不会进行segfault-生成的可执行文件会在尝试越界访问内存时立即进行segfault。)
Daniel Cristofani 2014年

4
您是否可以提供产生此行为的实现,并且该实现是在发布此挑战之前创建的?如果不是,则此答案无效。
Mego

1
边界检查是特定于实现的,因此我确定其中有些会出错。但是会有SIGSEGV吗?我对此表示怀疑。尽管有很多程序依赖于左边的数组。两侧都有可增长的存储空间可能会非常方便。
captncraig '16

12

哈斯克尔(31)

foreign import ccall main::IO()

使用GHC编译并运行时,这会产生段错误。不需要扩展标志,因为外部功能接口符合Haskell 2010标准。


10

C- 11(19) 7(15) 6(14) 1个字符,AT&T x86汇编器-8(24)个字符

C版本是:

*(int*)0=0;

整个程序(不完全符合ISO,我们假设它为K&R C)长19个字符:

main(){*(int*)0=0;}

汇编程序变体:

orl $0,0

整个程序长24个字符(仅供评估,因为它实际上不是汇编程序):

main(){asm("orl $0,0");}

编辑

几个C变体。第一个使用全局指针变量的零初始化:

*p;main(){*p=0;}

第二个使用无限递归:

main(){main();}

最后一个变体是最短的一个 -7(15)个字符。

编辑2

发明了一种比以上任何一种都短的变体-6(14)个字符。它假定将文字字符串放入只读段中。

main(){*""=0;}

编辑3

我最后一次尝试-1个字符长:

P

像这样编译它:

cc -o segv -DP="main(){main();}" segv.c

3
在C中不是 主要的; 只有5个字符
Arya

1
:Linker不会检查main是否为函数。它只是将其传递给加载器并返回sigsegv
Arya

1
@FUZxxl在这种情况下main是一个零初始化的全局int变量,因此我们得到的是尝试执行一些零字节的结果。在x86中,它就像是add %al,(%rax)一条完全有效的指令,试图到达存储在中的地址处的内存%rax。有一个好的地址的可能性很小。
亚历山大·巴库林

6
当然,最后一个条目可以用于所有内容,您只需要提供正确的编译器参数即可。这应该使它成为任何代码高尔夫球比赛的自动获胜者。:-)
celtschk 2012年

5
通常,除那些选择要使用的语言版本的编译器标记外,其他编译器标记都计入总数。
杰里·耶利米

9

dc-7个字符

[dx0]dx

导致堆栈溢出


是作品,但是您能详细说明吗?为什么会这样呢?
斯特凡纳·古里科

2
[dx0]将其存储dx0在堆栈上,然后d复制顶部堆栈元素,然后x弹出顶部堆栈元素(dx0)并执行它。它复制了顶层堆栈元素,并开始执行它。0为了防止这是一个尾部调用,需要在那里,因此它们都在堆积。
Ben Millwood

8

Perl,10/12个字符

一个稍微有点欺骗的解决方案是从Joey Adams的bash技巧中删除一个char :

kill 11,$$

但是,要在Perl中获得真正的段错误,unpack p是显而易见的解决方案:

unpack p,1x8

从技术上讲,这不能保证会发生段错误,因为地址0x31313131(或在64位系统上为0x3131313131313131)可能只是偶然指向有效的地址空间。但是,反对的可能性很大。另外,如果将perl移植到指针长于64位的平台,x8则需要增加。


1
这是什么1x8东西
汉尼斯·卡皮拉

@HannesKarppila这是写作的简短途径"11111111".
Ilmari Karonen

8

Python 33

import os
os.kill(os.getpid(),11)

在python中发送信号11(SIGSEGV)。


2
另外33个字符:from os import*kill(getpid(),11)
Timtech

8

OCaml,13个字节

Obj.magic 0 0

这使用函数Obj.magic,该函数不安全地强制使用任何两种类型。在这种情况下,它将强制0(由于GC使用的标记位而存储为立即数1)为函数类型(存储为指针)。因此,它尝试取消对地址1的引用,这当然会出现段错误。


1
it coerces 0 (stored as the immediate value 1)-为什么0被存储为1?
斯凯勒2015年

1
@Skyler看到编辑
Demi

1
Obj.magic()0是一个短字符:)
Ben Millwood'Nov

8

Bash,4个字节

打高尔夫球

. $0

递归地将脚本包含到自身中。

讲解

递归的“源”(。)操作最终导致堆栈溢出,并且由于Bash不与libsigsegv集成,因此会产生SIGSEGV。

请注意,这是不是一个错误,但预期的行为,如讨论在这里

测试

./bang 
Segmentation fault (core dumped)

在线尝试!



7

C#-62

System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr.Zero);

编辑:23

unsafe{int i=*(int*)0;}

必须使用/ unsafe进行编译,此代码才能正常工作。由于某种原因,我不明白,*(int*)0=0只是抛出了NullReferenceException,而此版本给出了正确的访问冲突。


int i=*(int*)0;回报我一个NullReferenceException。
彼得·奥尔森

您可以尝试访问否定位置,例如*(int*)-1=0并获得访问冲突。
彼得·奥尔森

唯一的例外就是clr封装的例外,并且是微不足道的。在所有这些情况下,os本身实际上都会产生seg错误。
captncraig 2012年

*(int*)0=0引发异常的原因可能是由于优化。具体来说,为了避免检查的开销null,优化器可以删除空检查,但是当发生段错误时,它可以适当地将其重新抛出NullReferenceException
Konrad Borowski

7

PicoLisp-4个字符

$ pil
: ('0)
Segmentation fault

这是预期的行为。如其网站上所述:

如果某些编程语言声称是“瑞士编程刀”,那么PicoLisp可能被称为“编程刀”:敏锐,准确,小巧,轻巧,但对于没有经验的人也很危险。


7

F90-39字节

real,pointer::p(:)=>null()
p(1)=0.
end

汇编:

gfortran segv.f90 -o segv 

执行:

./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)

材料:

gfortran --version
GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4

1
不错的第一篇文章。
Rɪᴋᴇʀ

6

C语言中的19个字符

main(a){*(&a-1)=1;}

它破坏了主函数的返回地址值,因此在返回时得到SIGSEGV main


它取决于堆栈框架的布局,因此在某些体系结构中它可能不会失败。
亚历山大·巴库林


5

Cython,14岁

这通常在调试时很方便。

a=(<int*>0)[0]

5

Unix PDP-11汇编,18字节二进制,7字节源

(这正成为我的主题,也许是因为它是我所知道的唯一一种语言,这里没有其他人可以使用。)

inc(r0)

在程序启动时,递增由r0的初始值寻址的单个字节[根据simh调试器,它的初始值为05162]。

0000000 000407 000002 000000 000000 000000 000000 000000 000000
0000020 005210 000000

而且,和往常一样,末尾的多余字节可以用strip删除。

我做了几次尝试来缩短源代码,但总是最终遇到语法错误或SIGBUS。


5

Matlab-是的,有可能!

在回答我的一个问题时,Amro提出了这个怪癖:

S = struct();
S = setfield(S, {}, 'g', {}, 0)

请提供Matlab版本-R2015B(和2016B也只是抛出错误):使用setfield时出错(第56行)至少需要一个索引。
Florian Castellane

@FlorianCastellane现在无法尝试所有版本,但是已经确认它可以在许多版本中提供段错误,最新版本为2014b,最早的为2012a。
丹尼斯·贾赫鲁丁

5

JavaScript Shell,7个字节

clear()

清除所有内容,而不仅仅是清除当前范围,这显然会导致大量错误,从而导致JS崩溃和出现段错误


根据MDN(document.clear)的说法,这仅应在Mozilla的较旧版本中执行某些操作,即使如此,您的体验中真正存在哪些段错误?
tomsmeding

@tomsmeding这是window.clear,FF直接没有显示出来,它是内置的蜘蛛猴
Downgoat

5

Pyth,3个字符

j1Z

这将是我解释如何得出此答案的部分,除非我完全不知道。如果有人能为我解释这一点,我将不胜感激。

它在在线翻译中。

说明

j将基数平方并递归调用自身,直到基数至少与数字一样大。由于基数为0,因此永远不会发生。具有足够高的递归限制,您会遇到段错误。

- 丹尼斯♦


想通了!通过浏览Pyth的源代码,我发现此代码j1and上执行0,并且试图转换1为base 0。为什么会发生段错误,我不知道...
NoOneIsHere

1
这里j将基数平方并递归调用自身,直到基数至少与数字一样大。由于基数为0,因此永远不会发生。具有足够高的递归限制,您会遇到段错误。
丹尼斯

@Dennis IDEone
NoOneIsHere

@SeeRhino Pyth解释器将递归限制设置为100,000。至少在TIO上,这足以构成段错误。
丹尼斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.