2016-11-07 2 views
0

Код, который я реализую, в котором я разделяю команду сначала на трубы, а затем пробелами.Ошибка разбиения сегментации на токены

int main(){ 
pid_t pid; 
while (1) { 
printf("$ "); 
char *cmd; 
ssize_t size=0; 
getline(&cmd,&size,stdin); 
if (cmd[strlen(cmd)-1]== '\n') {cmd[strlen(cmd)-1]='\0';} 
char** commands = splitter(cmd,"|"); 
int i=0; 
int fd[2],in=0; 
while (commands[i+1]!=NULL){ 
pipe(fd); 
char **args = splitter(commands[i]," \t"); 
    pid = fork(); 
    if (pid==-1) {exit(EXIT_FAILURE);} 
    else if (pid==0){ 
    close(fd[0]); 
    changeIO(in,0); 
    changeIO(fd[1],1); 
    execvp(args[0],args); 
    } 
    else{ 
    waitpid(pid,NULL,0); 
    close(fd[1]); 
    close(in); 
    in = fd[0]; 
    } 
i++; 
} 
char **args = splitter(commands[i+1]," \t"); 
changeIO(in,0); 
execvp(args[0],args); 
} 
} 

Здесь следует выполнение функций выше код использует

void changeIO(int oldfd,int newfd){ 
if (oldfd!=newfd){ 
    dup2(oldfd,newfd); 
    close(oldfd); 
} 
} 


char** splitter(char* stringToSplit, char* delimiter){ 
    char *token; 
    int initial_size = 300; 
    char** args = malloc(initial_size*sizeof(char*)); 
    token = strtok(stringToSplit,delimiter); 
    int index = 0; 
    while (token != NULL) { 
    args[index] = token; 
    index++; 
    if (index >= initial_size) { 
     initial_size = initial_size + 100; 
     args = realloc(args,initial_size*sizeof(char*)); 
     if (!args) exit(EXIT_FAILURE); 
    } 
    token = strtok(NULL,delimiter); 
    } 
    args[index] = NULL; 
    return args; 
} 

Ok выполнение кода я получаю ошибку сегментации, когда я вхожу в команду на входе пользователя. Испытывая различные варианты, я понял, что это имеет какое-то отношение к char** args, в котором я передаю токены каждой команды. Я не могу понять, почему это происходит, поскольку выделена память, и из того, что я понимаю, я просто указываю, что указатель аргументирует эту выделенную память. Любая помощь оценивается.

EDIT: Проверено с valgrind. Результаты ниже:

==3361== Memcheck, a memory error detector 
==3361== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==3361== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info 
==3361== Command: ./mysh3 
==3361== 
==3361== Conditional jump or move depends on uninitialised value(s) 
==3361== at 0x40AFE97: getdelim (iogetdelim.c:59) 
==3361== by 0x40ACDD1: getline (getline.c:32) 
==3361== by 0x80486C4: main (in /home/dimitris/Desktop/mysh3) 
==3361== 
$ ls 
==3361== Invalid read of size 1 
==3361== at 0x4101CAA: execvpe (execvpe.c:50) 
==3361== by 0x4101B33: execvp (execvp.c:26) 
==3361== by 0x804885F: main (in /home/dimitris/Desktop/mysh3) 
==3361== Address 0x0 is not stack'd, malloc'd or (recently) free'd 
==3361== 
==3361== 
==3361== Process terminating with default action of signal 11 (SIGSEGV) 
==3361== Access not within mapped region at address 0x0 
==3361== at 0x4101CAA: execvpe (execvpe.c:50) 
==3361== by 0x4101B33: execvp (execvp.c:26) 
==3361== by 0x804885F: main (in /home/dimitris/Desktop/mysh3) 
==3361== If you believe this happened as a result of a stack 
==3361== overflow in your program's main thread (unlikely but 
==3361== possible), you can try to increase the size of the 
==3361== main thread stack using the --main-stacksize= flag. 
==3361== The main thread stack size used in this run was 8388608. 
==3361== 
==3361== HEAP SUMMARY: 
==3361==  in use at exit: 2,520 bytes in 3 blocks 
==3361== total heap usage: 5 allocs, 2 frees, 4,568 bytes allocated 
==3361== 
==3361== LEAK SUMMARY: 
==3361== definitely lost: 0 bytes in 0 blocks 
==3361== indirectly lost: 0 bytes in 0 blocks 
==3361==  possibly lost: 0 bytes in 0 blocks 
==3361== still reachable: 2,520 bytes in 3 blocks 
==3361==   suppressed: 0 bytes in 0 blocks 
==3361== Rerun with --leak-check=full to see details of leaked memory 
==3361== 
==3361== For counts of detected and suppressed errors, rerun with: -v 
==3361== Use --track-origins=yes to see where uninitialised values come from 
==3361== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) 
Segmentation fault 
+3

Вы использовали отладчик? Если вы хотите, чтобы мы помогли, пожалуйста, предоставьте [mcve]. Мы не можем отлаживать неполный код. Например, что такое 'cmd'? – kaylum

+0

Возможно, это неинициализированный массив fd [2]. Это также может быть проблемой с самой переменной cmd, и я не вижу, как это инициализируется. Для таких ошибок мне нравится http://valgrind.org/, если вы находитесь в Linux. Однако я согласен с информацией отладчика @kaylum, действительно полезной для понимания вашей проблемы :) – PlatinTato

+0

@JacobusConradi Я собираюсь проверить это с valgrind и обновить сообщение. Благодарю. –

ответ

-1

Когда strtok() находит маркер, он изменяет характер сразу после маркеров в \ 0, а затем возвращает указатель на маркер.

+0

нашел [это] (http://www.c-howto.de/tutorial-strings-zeichenketten-stringfunktionen-zerteilen-strtok.html) образец. Он использует его в значительной степени точно так же – PlatinTato

+1

И ?? Было бы неплохо быть менее загадочным с вашим ответом и более явным объяснением того, как это относится к коду OP. – kaylum

+0

Я тестировал сплиттер(), когда я подписывался на трубы, прежде чем переходить к коду, и токены выполняются правильно, без ошибок сегментации и когда я следую точному методу со второй частью, я получаю эту ошибку.EDIT: код делителя на 100% не имеет ничего общего с упомянутой ссылкой –

0

Это индексируемый массив.

Ваш цикл цикла завершен с commands[i+1], являющимся нулевым. Затем вы передаете его splitter.

Передача commands[i] вместо.

Смежные вопросы