2011-03-10 98 views
4

我已经使用具有CLONE_VM和CLONE_FILES集的clone()系统调用编写了一个程序。 我无法理解输出显示分段错误的原因。有人可以纠正我的代码,并告诉我相同的原因。分段错误的原因

#include<stdio.h> 
#include<unistd.h> 
#include<fcntl.h> 
#include<sys/types.h> 
#include<sys/stat.h> 
#include<sched.h> 
#include<stdlib.h> 

int variable, fd; 

int do_something() { 
    // sleep(100); 
    variable = 42; 
    close(fd); 
    _exit(0); 
} 

int main(int argc, char *argv[]) { 
    void **child_stack; 
    char tempch; 

    variable = 9; 
    fd = open("test.file", O_RDONLY); 
    child_stack = (void **) malloc(16384); 
    printf("The variable was %d\n", variable); 

    clone(do_something, child_stack, CLONE_VM|CLONE_FILES, NULL); 
// sleep(100); 

    printf("The variable is now %d\n", variable); 
    if (read(fd, &tempch, 1) < 1) { 
     perror("File Read Error"); 
     exit(1); 
    } 
    printf("We could read from the file\n"); 
    return 0; 
} 
+0

你确认'malloc'不返回NULL吗? – littleadv 2011-03-10 04:15:18

+0

我怀疑这是你的问题,但'do_something'应该带'void *'参数。我不相信它是必需的,但它仍然是很好的风格。 – 2011-03-10 06:16:46

回答

4

您需要知道处理器上堆栈增长的方向,并且您需要知道堆栈的哪一端必须传递给clone()。

man clone

Stacks grow downwards on all processors that run Linux (except the 
HP PA processors), so child_stack usually points to the topmost 
address of the memory space set up for the child stack. 

您是通过最上面的地址,要传递的最底部地址,你是不是(我猜)在HP-PA。

修复:

child_stack = (void **) malloc(16384) + 16384/sizeof(*child_stack); 

附:我惊讶明显错误的非答案在这里。

  • 没有,靠近无效文件描述符 做任何UNIX 崩溃和 Linux系统中存在。
  • 不,void*void**没有任何关系。
  • 不,你不需要需要一个do_something的地址,编译器会自动为你做。

最后,是:调用close_exit,或在clone()d线程任何其他的libc例程潜在不安全的,虽然它不会在这里产生的问题。

-1

以固定方式是使儿童实际堆栈在堆栈上..即

炭child_stack [16384];

我怀疑堆栈指针不能指向数据段或某事像那......

即使如此..它的工作原理与-g ..但与-O崩溃!

+0

为什么我们不能使用动态内存分配? – pradeepchhetri 2011-03-10 04:37:44

+0

这是一个完全虚假的答案。 – 2011-03-13 06:00:25

相关问题