Nor*_*sey 6 c linux segmentation-fault waitpid
我正在测试用于检测子进程何时进行segfaulted的代码.想象一下,当这段代码并不总是段错误时,我感到很惊讶:
#include <stdio.h>
int main() {
char *p = (char *)(unsigned long)0;
putchar(*p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在Debian Linux 2.6.26内核下运行; 我的shell是ksh93来自Debian ksh软件包的AT&T ,版本M 93s + 2008-01-31.有时这个程序会出现段错误,但除此之外它只是以非零退出状态静默终止但没有消息.我的信号检测程序报告如下:
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
Run Code Online (Sandbox Code Playgroud)
在pure下运行ksh表明segfault也很少见:
Running...
Running...
Running...
Running...
Running...
Running... Memory fault
Running...
Run Code Online (Sandbox Code Playgroud)
有趣的是,bash每次都能正确检测到段错误.
我有两个问题:
谁能解释这种行为?
任何人都可以建议一个简单的C程序,它会在每次执行时可靠地进行段错误吗 我也尝试过kill(getpid(), SIGSEGV),但是得到了类似的结果.
编辑:jbcreix有答案:我的segfault探测器坏了.我被骗了,因为ksh有同样的问题.我试过bash并且bash每次都正确.
我的错误是,我路过WNOHANG到waitpid(),在那里我应该已经传递零.我不知道我能想到什么!人们想知道问题是什么ksh,但这是一个单独的问题.
Hea*_*utt 12
写于NULL将可靠段错误或总线错误.
有时,OS会将只读页面映射到零地址.因此,您有时可以阅读NULL.
尽管C将NULL地址定义为特殊地址,但该特殊状态的"实现"实际上由操作系统的虚拟内存(VM)子系统处理.
WINE和dosemu需要映射页面以NULL获得Windows兼容性.请参阅mmap_min_addrLinux内核以重建无法执行此操作的内核.
mmap_min_addr 目前是一个热门话题,因为相关的漏洞利用以及来自Theo de Raadt的Linus(显然是Linux成名)的公开火焰,OpenBSD的努力.
如果您愿意以这种方式对孩子进行编码,您可以随时致电: 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.