检测到堆栈粉碎错误

时间:2013-07-29 05:31:06

标签: c stack

当我尝试以下代码片段时,我收到一个名为stack smashing detect的错误。可能是这个潜在错误的原因是什么?有人可以解释一下吗?

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int glob=88;
int main()
{
    int loc=2;
    pid_t pid=vfork();
    if(pid==0)
    {
        printf("Inside child");
        glob++;
        loc++;
        printf("%d %d" ,glob,loc);
    }
    else
    {
        printf("Inside parent");
        glob++;
        loc++;
        printf("%d %d",glob,loc);
    }
}

和我运行此代码时的输出就是那样

user018@sshell ~ $ gcc one.c
user018@sshell ~ $ ./a.out
Inside child89 3Inside parent90 945733057*** stack smashing detected ***: a.out
- terminated
a.out: stack smashing attack in function <unknown> - terminated
KILLED

3 个答案:

答案 0 :(得分:1)

来自Linux man page(和POSIX):

  

vfork()函数与fork(2)具有相同的效果,但如果由vfork()创建的进程修改除用于存储返回值的pid_t类型的变量之外的任何数据,则行为未定义。 vfork(),或从调用vfork()的函数返回,或在成功调用_exit(2)或exec(3)函数系列之前调用任何其他函数。

您正在修改数据并从调用vfork的函数返回 - 这两者都会导致未定义的行为。 vfork不等同于forkvfork d孩子可以做的事情非常非常有限。它应该只在非常特殊的情况下使用,主要是当你需要在孩子身上做的唯一事情是exec时。

有关详细信息,请参阅操作系统的手册页。

答案 1 :(得分:1)

vfork()用于创建新进程,无需复制父进程的页表。因此,您无法修改子进程中的变量,因为它们不再存在。请改用fork()

还有一件事,最好在\n的末尾添加printf(),因为默认情况下stdout是行缓冲的。

答案 2 :(得分:0)

1)我肯定会添加一个“return 0”,因为你声明了“int main()”。

2)如果要禁用警告,请在编译行中使用-fno-stack-protector

3)如果要调试错误的来源,请在编译行中使用“-g”,然后从gdb运行程序(而不是运行./a.out)。

我最接近“有什么不对”的是这个关于vfork()的手册页:

  

http://linux.die.net/man/3/vfork

     

vfork()函数应该等效于fork(),除了   如果由vfork()创建的进程也未定义行为   修改除用于存储的pid_t类型的变量之外的任何数据   来自vfork()的返回值,或者从其中返回的函数返回   vfork()被调用,或者在成功之前调用任何其他函数   调用_exit()或exec系列函数之一。

对于Linux,只需使用“fork()”,我认为你会很高兴:)