C 创建新流程时出现分段错误(堆芯转储)
首先,由于我发布的另一个问题是一个小阴影,我要求删除该线程,并有点想用这个线程替换它 我可以从解释我的程序应该做什么开始: 程序应该创建几个运行printenv、grep[inputarray]、sort、less的进程,然后这些进程应该使用管道来传输数据,如下所示: printenv->pipe1->grep->pipe2->sort->pipe3->less->stdout 现在我通过调用函数“createProcesswithPipe”递归地完成了这项工作。。 我相信这个计划背后的理论是正确的 现在如果你看一下代码,你会看到C 创建新流程时出现分段错误(堆芯转储),c,segmentation-fault,C,Segmentation Fault,首先,由于我发布的另一个问题是一个小阴影,我要求删除该线程,并有点想用这个线程替换它 我可以从解释我的程序应该做什么开始: 程序应该创建几个运行printenv、grep[inputarray]、sort、less的进程,然后这些进程应该使用管道来传输数据,如下所示: printenv->pipe1->grep->pipe2->sort->pipe3->less->stdout 现在我通过调用函数“createProcesswithPipe”递归地完成了这项工作。。 我相信这个计划背后的理论是正
printf("point: %d" , pointer);
每次输入函数时打印指针的值。。现在的问题是,如果程序按原样运行,它永远不会打印出来。有什么想法吗
但如果我要进一步删除递归调用:
createProcesswithPipe(++pointer, executes, execute);
程序在得到相同的错误之前打印出“点:0”:分段错误(堆芯转储)
也不要介意瑞典语的评论!如果你有任何问题,请提问!我有点迷路了:)
/*digenv.c-dig(ta reda på)env(环境变量)*/
#包括
#包括
#包括
#包括
#包括
#包括
#定义管道读取侧(0)
#定义管道写入侧(1)
pid_t childpid;/*för child processens PID vid fork()*/
void createProcesswithPipe(int指针,int执行,char*执行[])
{
printf(“点:%d”,指针);
int pipe_filedesc[2];/*för Fildesktriptorer från管道(2)*/
int return_value;/*för returvärden från systemanrop*/
return_value=pipe(pipe_filedesc);/*skapa en pipe*/
if(-1==返回_值){perror(“无法创建管道”);exit(1);}/*om pipe()misslyckades*/
childpid=fork();/*skapa första child processen*/
如果(0==childpid)
{
返回值=dup2(管道文件描述[管道读取侧],标准文件号);
如果(-1==返回_值){perror(“Cannot dup”);退出(1);}
/*这是一个很好的参考,直到管道被安装在里面*/
返回值=关闭(管道文件描述[管道读取侧]);
如果(-1==返回_值){perror(“无法关闭读取端”);退出(1);}
/*这根管子只能读*/
返回值=关闭(管道文件描述[管道写入侧]);
如果(-1==返回_值){perror(“无法关闭写入端”);退出(1);}
如果(指针)尝试将printf(“点:%d”,指针);
更改为printf(“点:%d\n,指针);
。额外的\n
(换行符)应该会导致缓冲区刷新。(我猜它在刷新缓冲区之前崩溃。)这非常有用:)现在它打印:Point:0 Point:1 Point:2 Point:3 Point:4实际上它不是一个指针,它是一个名为pointer的int,因为我来自java,我就是这么做的:PYou应该使用调试器,只依赖printfs进行调试要困难得多。就像@Étienne所说的,你真的应该使用调试器。我只是想快速解释一下为什么你需要eren没有得到任何输出。假设您使用的是gcc
,如果您通过gdb
运行程序,您可以使用backtrace
命令来确定SEGFAULT来自哪一行,检查堆栈,等等。您可以查看。您也可以用瑞典语找到一个。谢谢,我会查看它:)
/* digenv.c - dig (ta reda på) env (enviroment variablar) */
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define PIPE_READ_SIDE ( 0 )
#define PIPE_WRITE_SIDE ( 1 )
pid_t childpid; /* för child-processens PID vid fork() */
void createProcesswithPipe(int pointer, int executes, char* execute[])
{
printf("point: %d" , pointer);
int pipe_filedesc[ 2 ]; /* för fildeskriptorer från pipe(2) */
int return_value; /* för returvärden från systemanrop */
return_value = pipe( pipe_filedesc ); /* skapa en pipe */
if( -1 == return_value ) {perror( "Cannot create pipe" ); exit( 1 );} /* om pipe() misslyckades */
childpid = fork(); /* skapa första child-processen */
if( 0 == childpid )
{
return_value = dup2( pipe_filedesc[ PIPE_READ_SIDE], STDIN_FILENO );
if( -1 == return_value){perror( "Cannot dup" ); exit( 1 );}
/* TA BORT GAMLA REFERENSEN TILL PIPE BEHÖVER INTE HA 2st!!!!!!! */
return_value = close( pipe_filedesc[PIPE_READ_SIDE] );
if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}
/* THIS PIPE SHOULD ONLY READ */
return_value = close( pipe_filedesc[PIPE_WRITE_SIDE] );
if( -1 == return_value ){perror( "Cannot close write end" ); exit( 1 );}
if(pointer <= 3){
createProcesswithPipe(++pointer, executes, execute);
}
else if(3 == pointer && executes < 4){
return_value = dup2( STDOUT_FILENO, pipe_filedesc[ PIPE_WRITE_SIDE] );
if( -1 == return_value){perror( "Cannot dup" ); exit( 1 );}
/* TA BORT GAMLA REFERENSEN TILL PIPE BEHÖVER INTE HA 2st!!!!!!! */
return_value = close( pipe_filedesc[ PIPE_WRITE_SIDE ] );
if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}
(void) execlp( execute[executes], execute[executes], (char *) 0 );
}
else
{
return_value = dup2( STDOUT_FILENO, pipe_filedesc[ PIPE_WRITE_SIDE] );
if( -1 == return_value){perror( "Cannot dup" ); exit( 1 );}
/* TA BORT GAMLA REFERENSEN TILL PIPE BEHÖVER INTE HA 2st!!!!!!! */
return_value = close( pipe_filedesc[ PIPE_WRITE_SIDE ] );
if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}
char* execute2[executes-4];
int i;
for(i = 1;i<executes-4;i++){
execute2[i] = execute[i+3];
}
(void) execlp( execute[executes], execute[executes], (char *) execute2 );
}
}
else
{
if( -1 == childpid ){ perror( "Cannot fork()" ); exit( 1 );} /* fork() misslyckades */
return_value = dup2( pipe_filedesc[ PIPE_WRITE_SIDE], STDOUT_FILENO );
if( -1 == return_value){perror( "Cannot dup" ); exit( 1 );}
/* Kommer vi hit i koden så är vi i parent-processen
och fork() har fungerat bra. */
/* THIS PIPE SHOULD ONLY WRITE */
return_value = close( pipe_filedesc[ PIPE_READ_SIDE ] );
if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}
/* TA BORT GAMLA REFERENSEN TILL PIPE BEHÖVER INTE HA 2st!!!!!!! */
return_value = close( pipe_filedesc[ PIPE_WRITE_SIDE ] );
if( -1 == return_value ){perror( "Cannot close read end" ); exit( 1 );}
(void) execlp( execute[executes], execute[executes], (char *) 0 );
/* exec returnerar bara om något fel har uppstått
och om exec returnerar så är returvärdet alltid -1 */
perror( "Cannot exec &execute[executes]" );
exit( 1 );
}
}
int main( int argc, char * argv[] )
{
char* execute[3+argc-1];
execute[0] = "printenv";
execute[3+argc-3] = "sort";
execute[3+argc-2] = "less";
int i;
for(i = 3;i<(3+argc-1);i++)
{
if(!(strcmp(argv[i-3], "more"))){
execute[3+argc-2] = "more";
}
else{
execute[i] = argv[i-3];
}
}
createProcesswithPipe(0, (3+argc-1), execute);
exit( 0 ); /* Avsluta parent-processen på normalt sätt */
}