我试图故意让我的程序出现段错误,但由于某种原因它不是,我有点害怕,认为配置可能有问题。
这些是我运行的程序:
int main() {
char* abc;
abc[0] = '3';
return 0;
}
和
int main() {
int try[] = {3,4,2};
printf("%d", try[10]); // this prints '0'
return 0;
}
有人可以解释为什么他们没有分段错误吗?对于上下文,我运行的操作系统是macOS Catalina。
分段错误是未定义行为 (UB( 的实例。阅读更多关于 C 的信息,特别是 C11 标准 n3337 和现代 C书籍。
关于 UB,请阅读每个 C 程序员应该知道的关于未定义行为的知识
可能发生的情况是缓冲区溢出或堆栈溢出发生在调用堆栈的现有页面上。阅读有关页面错误和虚拟内存的信息。阅读一本关于操作系统的好教科书。
无法保证分段错误始终发生或可以及早检测到。因为 ASLR、编译器优化和赖斯定理。即使是相同的可执行文件也可能在一次运行时出现段错误,而在下一次运行时则不会。
考虑使用valgrind或一些地址消毒剂。
将try[10]
替换为try[123456]
(或abc[0]
替换为abc[-456789]
...(,您可能会观察到流程的不同行为。还要查看生成的汇编程序代码(例如,如果使用最新的和真正的GCC编译器,则使用gcc -Wall -Wextra -O2 -fverbose-asm -S
获得;最近的Clang接受类似的选项,因此您可以尝试使用相同的clang -Wall -Wextra -O2 -fverbose-asm -S
C源文件进行编译(。
如果您有权访问它,请研究系统crt0的源代码。
考虑使用静态源代码分析工具,如 Frama-C 或 Clang 静态分析器。您可能有兴趣阅读此报告草案,解释一些令人惊讶的 GCC 优化。
您可以在笔记本电脑上安装一些Linux发行版,并利用其中大多数软件都是开源的事实,因此请研究它们的源代码。另请参阅 linuxfromscratch.org
MacOSX的一些源代码也是开源的(但不是GUI(。