简体   繁体   中英

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. 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

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

//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

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. 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. I've asked a couple of C++ professors who were available, but none of them were able to pinpoint the error(s). 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 -

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-

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 -

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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