简体   繁体   English

Linux C Shell,子进程抛出分段错误

[英]Linux C Shell, segmentation fault thrown by child process

I've been trying to pick up C for a homework assignment that says to create a C shell. 我一直在尝试为作业写一个C,说要创建一个C shell。 One requirement is that all the commands should be executed from a child process. 一个要求是所有命令应从子进程执行。 The problem seems to be that my child process dies way too early, and I never get to the part of the code that actually executes the command. 问题似乎是我的子进程死得太早了,而我从没有真正执行命令的那部分代码。 My code: 我的代码:

parseCommand.h parseCommand.h

char *parseCommand(char str[]) {
    char * token;
    //get size of the input array. divide memory amount allocated to array by the size of the 1st element (which should be representative of other elements)
    size_t n = sizeof(str) / sizeof(str[0]); 
    char *args = malloc(n);
    printf("Splitting string \"%s\" into tokens:\n", str);
    token = strtok(str, " \n");
    int i = 0;
    while (token != NULL) {
        printf(":: %s\n", token);
        args[i++] = token;
        token = strtok(NULL, " \n");
    }
    printf("after while loop");
    args[i]=(char *) 0;
    return args;

}

main.c main.c

//I probably don't need all these
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>

//Custom Libraries
#include "parseCommand.h"

char *parseCommand(char str[]);

int main() {

    char path[10] = "/bin/";//path to bash scripts
    int should_run = 1;
    while (should_run) {
        printf("yazan_shell>> ");
        fflush(stdout); //force the prompt to the output immediately
        char *cmdStr = (char *)malloc(40); //allocate space for array
        fgets(&cmdStr, 40, stdin); //save user input to cmdStr
        pid_t pid = fork(); //create 
        if (pid == 0) {
            printf("==> Child received: %s command. Executing...\n", &cmdStr);
            char *cmd = parseCommand(&cmdStr);//split user input by space
            printf("cmd: %s", &cmd);
            execvp(strcat(path, cmd[0]), cmd);//excecute the input cmd
        } else {
            int returnStatus;
            waitpid(pid, &returnStatus, 0); //parent waits for child process
            printf("==> Parent is silent!! PID: %d\n", pid);
            should_run = 0;
        }
        free(cmdStr); //deallocate cmdStr
    }
}

Output 1 输出1

yazan_shell>> ls -l
==> Child received: ls -l
 command. Executing...
Splitting string "ls -l
" into tokens:
:: ls
:: -l
==> Parent is silent!! PID: 5500

RUN FINISHED; Segmentation fault; core dumped; real time: 3s; user: 0ms; system: 0ms

I just started learning C a couple days ago, but I google'd segmentation errors in C and it seems that I am either dereferencing a non-initialized pointer or trying to access freed memory. 我几天前才刚开始学习C,但是我用google搜索了C中的分段错误,看来我在取消引用未初始化的指针,还是试图访问释放的内存。 So I tried commenting out the 所以我尝试注释掉

free(cmdStr);

line and the output then looks like: 行,然后输出如下所示:

yazan_shell>> ls -l
==> Child received: ls -l
 command. Executing...
Splitting string "ls -l
" into tokens:
:: ls
:: -l
==> Parent is silent!! PID: 5601

RUN FINISHED; exit value 33; real time: 1s; user: 0ms; system: 0ms

I also tried moving the print statement in the while loop in parseCommand.h but the output seems to not change either. 我也尝试在parseCommand.h的while循环中移动print语句,但是输出似乎也没有改变。 I've asked a couple of C++ professors who were available, but none of them were able to pinpoint the error(s). 我已经问过几个C ++教授,但他们都无法指出错误。 Is anyone here able to give me some pointers (hehe) about my mistake? 这里有人可以给我一些有关我的错误的提示吗?

Thank you very much in advance! 提前非常感谢您!

There are several problems - 有几个问题-

1. In main - 1.main -

char *cmdStr = (char *)malloc(40);  // don't cast it
fgets(&cmdStr, 40, stdin);        // don't pass address of cmdStr it is already a char *

Just this is fine - 就这样-

char *cmdStr =malloc(40); 
fgets(cmdStr, 40, stdin); 

2. also here- 2.也在这里-

char *cmd = parseCommand(&cmdStr);//split user input by space
printf("cmd: %s", &cmd);      //cmd is already a char * don't pass its address

write like this - 这样写-

printf("cmd: %s", cmd); 

3. In your function char *parseCommand(char str[]) when you calculate number of elements - 3.在您的函数char *parseCommand(char str[])当您计算元素数时-

size_t n = sizeof(str) / sizeof(str[0]); 

this wont work as expected . 这不会按预期工作。 So calculate n in main and then pass it to your function 因此,在main计算n ,然后将其传递给您的函数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM