【问题标题】:Segmentation fault when trying to run custom shell尝试运行自定义 shell 时出现分段错误
【发布时间】:2017-02-28 18:22:38
【问题描述】:

制作我们自己的外壳并面临分段错误问题的学校项目。 有人可以帮忙吗?

编辑:某种运行但“退出”不会触发退出并且 execvp 无法正常运行(说:“没有这样的文件或目录”&“或 ls:invalid option -- '”

void interactive_mode();
void batch_mode(char *path);
void parse(char *str,char *delimeter,char **args);
int execute(char **args);

int main(int argc, char *argv[]){


    if(strcmp(argv[1],"-b")==0){
    batch_mode(argv[2]);

    }
    else if(strcmp(argv[1],"-i")==0){
    interactive_mode();

    }

}

我怀疑分段错误问题源于交互式 和批处理模式代码

void interactive_mode(){
        int quit_flag;
        char str[512];
        char *commands[128];
        char *args[128];

        quit_flag=0;

        while(1){
            printf("whatever> ");
            if(fgets(str,512,stdin)==NULL){
                exit(0); //error reading
            }

            int i=0;

            parse(str,";",commands);        //split the string into commands eg "ls -a ; ls -l" -> "ls -a ","ls -l"
            while(commands[i]!=NULL){
                parse(commands[i]," ",args);        //split commands into arguements eg "ls -l" -> "ls","-l"
                i++;
                quit_flag=execute(args);
            }       
        if(quit_flag==1) exit(1);
        }   
    }

// 试图从文件中读取

void batch_mode(char *path){
        FILE *fp;
        char str[512];
        char *commands[128];
        char *args[128];
        int res;

    fp=fopen(path,"r");

    if(fp==NULL){
        perror("Error opening file");
        exit(4);        //file not open
    }

    while(1){
        if(fgets(str,512,fp)==NULL) break;

        int i=0;

        parse(str,";",commands);
        while(commands[i]!=NULL){
            parse(commands[i]," ",args);
            i++;
            res=execute(args);
        }
    }

    fclose(fp);
    printf("whatever>Press Any Key to Continue\n");
    getchar();
}

//解析字符串

void parse(char *str,char *delimeter,char **args){
        char *pch;

        int i=0;
        pch=strtok(str,delimeter);
        while(pch!=NULL){
            args[i]=pch;
            i++;
pch=strtok(NULL,delimeter);
        }
        args[i]=NULL;   
    }

// 使用 fork 执行

int execute(char **args){
        char path[50];
        pid_t pid;
        int status;

        if(strcmp(args[0],"quit")==0) return 1;     //exited by quit

        strcpy(path,"/bin/");
        strcat(path,args[0]);

        if ((pid=fork())<0){
            perror("fork failed");
            exit(2);
        }
        else if (pid==0){
            if(execvp(path,args)<0){        
                perror("execvp failed");
                exit(3);
            }
        }
        else{
            while (wait(&status) != pid)       /* wait for completion  */
                   ;
        }
    }

请帮忙?

【问题讨论】:

  • parse 需要 pch=strtok(NULL,delimeter); 在 while 循环结束时。 (需要更新pch
  • 当您在没有任何命令行参数的情况下调用 shell 时,您的 strcmp() 调用具有未定义的行为。他们很可能会出现段错误。您应该使用argc 来确定是否有要测试的命令行参数。
  • 如果您使用-b 选项但没有文件名参数调用它,则类似。
  • 在没有首先检查argc 以确保命令行参数确实存在之前,不要访问argv[0] 以外的地方。如果预期的命令行参数不存在,输出一条 USAGE 消息到 stderr 然后调用exit( EXIT_FAILURE );
  • 为了便于阅读和理解,1) 请一致地缩进代码:在每个左大括号'{'之后缩进,在每个右大括号'}'之前不缩进。建议每个缩进级别使用 4 个空格。 2) 遵循公理:每行只有一个语句,并且(最多)每条语句有一个变量声明。

标签: c shell segmentation-fault


【解决方案1】:

您是否尝试过打印所有变量 argvstrcommands ... 以确保一切按预期进行?它还可以帮助您在脚本中找到段错误的位置。这需要你时间,对不起,我没有快速的答案。对于 starterprintf("%d", __LINE__) 将打印您所在的行号,不要忘记添加显式声明。
否则你可以使用 gdb。有相当长的学习曲线,但它可能对另一个项目有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-30
    • 2021-02-07
    • 1970-01-01
    • 2022-10-08
    • 1970-01-01
    • 2015-08-27
    • 2023-03-11
    • 2023-01-16
    相关资源
    最近更新 更多