首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么删除(char*)0的Linux程序并不总是分段错误?

为什么删除(char*)0的Linux程序并不总是分段错误?
EN

Stack Overflow用户
提问于 2009-11-14 19:35:27
回答 3查看 1K关注 0票数 6

我正在测试设计用于检测子进程何时出现分段错误的代码。想象一下,当这段代码并不总是分段错误时,我感到惊讶:

代码语言:javascript
运行
复制
#include <stdio.h>

int main() {
  char *p = (char *)(unsigned long)0;
  putchar(*p);
  return 0;
}

我是在DebianLinux2.6.26内核下运行的;我的外壳是来自Debian ksh包的AT&T ksh,版本M 93s+ 2008-01-31。有时,这个程序是分段错误的,但否则它只是以非零的退出状态而不是消息默默地终止。我的信号检测程序报告如下:

代码语言:javascript
运行
复制
segfault terminated by signal 11: Segmentation fault
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 11: Segmentation fault
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 53: Real-time signal 19

在纯ksh下运行表明,分段错误也很少见:

代码语言:javascript
运行
复制
Running... 
Running... 
Running... 
Running... 
Running... 
Running... Memory fault
Running... 

有趣的是,bash 每次都能正确地检测到分段故障。

我有两个问题:

  1. 有人能解释一下这种行为吗?
  2. 有人能建议一个简单的C程序,在每次执行时都能可靠地分割故障吗?我也尝试过kill(getpid(), SIGSEGV),但是我得到了类似的结果。

编辑:jbcreix的答案是:我的分段故障检测器坏了。我被愚弄是因为ksh也有同样的问题。我和bash试过了,bash每次都做得对。

我的错误是我把WNOHANG传递给了waitpid(),在那里我应该传递零。我不知道我会怎么想!人们想知道ksh是怎么回事,但这是另外一个问题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-11-14 19:43:08

写入NULL将可靠地分割故障或总线错误。

有时,操作系统会将只读页映射到零地址。因此,您有时可以从NULL中读取。

尽管C将NULL地址定义为特殊地址,但该特殊状态的“实现”实际上是由操作系统的虚拟内存(VM)子系统处理的。

为了实现Windows兼容性,葡萄酒和多斯莫需要在NULL上映射页面。请参阅Linux内核中的mmap_min_addr,以重新构建不能这样做的内核。

mmap_min_addr目前是一个热门话题,这是因为OpenBSD的一个相关的开发和对Linus (显然是Linux名声)的公开攻击。

如果您愿意以这种方式对子程序进行编码,则始终可以调用:raise(SIGSEGV);

此外,您还可以从:int *ptr_segv = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS, -1, 0);获得一个有保证的分段错误指针。

其中,PROT_NONE是保留无法访问的内存的关键。对于32位Intel Linux,PAGE_SIZE是4096.

票数 12
EN

Stack Overflow用户

发布于 2009-11-14 19:41:26

我不知道为什么它没有一致的行为。我想这不像读书那样挑剔。或者诸如此类的事情,尽管我可能完全错了。

试着用空写。这对我来说似乎是一致的。我不知道你为什么要用这个。:)

代码语言:javascript
运行
复制
int main()
{
    *(int *)0 = 0xFFFFFFFF;
    return -1;
}
票数 1
EN

Stack Overflow用户

发布于 2009-11-14 19:49:32

维基百科的第二个问题的答案是:

代码语言:javascript
运行
复制
 int main(void)
 {
     char *s = "hello world";
     *s = 'H';
 }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1735349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档