我正在测试GCC堆栈保护器.当我使用不安全的strcpy()函数溢出缓冲区时,堆栈保护程序检测到我正在做什么并抛出以下异常:
*** stack smashing detected ***: ./a.out terminated
Aborted (core dumped)
当我使用不安全的gets()函数做同样的事情时,我会得到一个分段错误.
segmentation fault: 11
为什么会这样?这两种情况有什么区别?这是我一直在使用的示例代码
gets()示例
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>
void say_hello (void);
int main (){
printf("Enter your name\n");
say_hello();
return 0;
}
void say_hello (void) {
char name[5];
gets(name); //this is a unsafe function to use. Results in stack overflow
printf("Hello %s\n", name);
}
strcpy()示例
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv){
char buffer [5];
strcpy(buffer,argv[1]);
return 0;
}
最佳答案 根据文档,strcpy()可能导致溢出错误,因为没有检查数据在新数组中的适合位置.这种溢出的结果可能有时从未被注意到,这完全取决于数据的写入位置.但是,常见的结果是堆和/或内存损坏.
strcpy()的一个安全替代方法是使用strcpy_s(),它也需要数组的大小.
这对于gets()或fgets()都是有效的,任何结果都是可能的:
- No visible affect what-so-ever
- Immediate program termination (a crash)
- Termination at a later point in the programs life time (maybe 1 second later, maybe 15 days later)
- Termination of another, unrelated program
- Incorrect program behaviour and/or calculation … and the list goes on. This is the problem with “buffer overflow” bugs, you just can’t
tell when and how they’ll bite you.
你可以阅读更多here.但是如果你有许多嵌套调用另一个函数(比如你的第一种情况),那么粉碎堆栈的几率会增加.
总而言之,在您的情况下恰好是这样,因为当发生溢出时它们的未定义行为.