为什么我不能导致段故障?

Bob*_*lan 18 c++ segmentation-fault

好吧,无论出于何种原因,我都遇到了导致seg故障的问题.我想制作一个,以便我可以使用它gdb来查看如何调试一个.我已经尝试过维基百科文章中的两个例子,但都没有用.

第一个:

char *s = "Hello World!";
*s = 'H';
Run Code Online (Sandbox Code Playgroud)

第二个例子:

int main(void) 
{
    main();
}
Run Code Online (Sandbox Code Playgroud)

编辑:我正在使用Ubutnu 9.10和g++我的编译器.任何人都可以告诉我一些保证段错误的代码吗?

Mar*_*ork 40

尝试并且可靠地取消引用指针是不可能的.
这是因为应用程序处理内存的方式因编译器和编译器而异,也可能在具有不同选项的相同编译器之间(调试/发布模式不同).

您可以做的是使用信号显式提升段错误:

#include <signal.h>

int main()
{
    raise(SIGSEGV);
}
Run Code Online (Sandbox Code Playgroud)

  • @ user1976:当然你可以用很多东西可靠地做到这一点.但是你不能使用未定义的行为可靠地做到这一点.未定义的行为永远不会很明确.由于在指针有效时可以很好地定义解除引用有效指针,因此可以通过这种方式崩溃.同时解除引用nullptr或无效指针是未定义的行为,因此您无法从中获得明确定义的行为.所以我的发言是立场. (2认同)

R S*_*hko 18

我的一线风味:

*(char *)0 = 0;
Run Code Online (Sandbox Code Playgroud)

  • 对于具有内存管理的平台,Linux可以访问未映射的页面,从而生成段错误.Ubuntu仅适用于具有内存管理的平台.Linux不映射页面0.在Ubuntu 9.10上,vm.mmap_min_addr默认为65535,因此您不会意外映射页面0.因此写入地址0将导致段错误.是的,如果你覆盖vm.mmap_min_addr然后mmap第0页然后写入地址0将不会导致段错误,所以我同意它不是100%保证会导致段错误.但除此之外,在提到的具体平台上,什么时候才能造成段错误. (9认同)
  • 即使这样也不能保证产生段错误.这只是未定义的行为.哪个可能有效,也可能无效. (3认同)
  • @Martin - 在所有平台上都有保证,没有.这是否会导致Ubuntu Linux出现段错误,是的. (2认同)
  • @RSamuelKlatchko 问题在于编译器知道这是一个未定义的行为,因此它可能假设它永远不会发生并且代码无法访问。一般来说,这意味着有多种可能的优化会导致上面的代码不会导致段错误,而不管 `vm.mmap_min_addr` 的值如何。 (2认同)

And*_*Dog 6

最短的段错误:

*(int*)0=0;
Run Code Online (Sandbox Code Playgroud)


小智 5

你做的两件事都会在C++中产生"未定义的行为"(好吧,实际上是禁止调用main()).无法保证它们会导致seg故障 - 这将取决于很多事情,但主要是您运行的平台,您尚未指定.

事实上,任何引起seg故障的建议方法可能会也可能不会起作用.这是因为seg错误几乎总是与C++的未定义行为概念相关联.

  • 从语言的角度来看,它是未定义的行为,但操作系统可能定义了发生分段错误的条件,您可以在C++中强制执行这些条件.(例如:`int*p = 0; while(true)*p ++ = 10;`将在某一点或另一点点击进程无法写入的内存段,并且在linux或macosx下将触发分段错误) (4认同)