我正在测试GCC堆栈保护器。当我使用不安全的strcpy()函数溢出缓冲区时,堆栈保护程序检测到我正在做的事情并引发以下异常:
*** stack smashing detected ***: ./a.out terminated
Aborted (core dumped)
当我使用不安全的gets()函数做同样的事情时,我得到了一个分段错误。
segmentation fault: 11
为什么会这样?这两种情况有什么区别?这是我一直在使用的示例代码
获取()示例
#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;
}
答案 0 :(得分:2)
根据文档,strcpy()
可能导致溢出错误,因为没有检查数据在新数组中的适合位置。这种溢出的结果可能有时从未被注意到,这完全取决于数据的写入位置。但是,常见的结果是堆和/或内存损坏。
strcpy()
的一个安全替代方法是strcpy_s()
的使用,它也需要数组的大小。
同样适用于gets()
或fgets()
,任何结果都是可能的:
- 没有明显的影响,所以
- 立即终止程序(崩溃)
- 在节目生命时间的晚些时候终止(可能是1秒后,也许是15天后)
- 终止另一个不相关的计划
- 程序行为和/或计算不正确......列表继续。这是“缓冲区溢出”错误的问题,你就是不能 告诉他们什么时候以及如何咬你。
您可以阅读更多here。但是,如果您对其他函数进行了多次嵌套调用(例如在第一种情况下),那么粉碎堆栈的几率会增加。
总而言之,在你的情况下恰好是这样,因为当发生溢出时它们的未定义行为。