linux execve, ошибка сегментации (strcmp_sse42)

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

void main(){
   int x,y,status, i;
   int cnt = 0;
   int flag = 0;
   char buf[50];
   char str[50];
   char * argv[10];
   char * ptr;


   for(i=0; i<10; i++){
    printf("$");
    gets(buf);
    strcpy(str, buf);

    ptr = strtok(buf, " ");

    while(ptr != NULL){
      argv[cnt] = ptr;
      cnt++;
      ptr = strtok(NULL," ");
    }



    if(!strcmp(argv[cnt-1], "&")) {
      argv[cnt-1] = 0;
      flag = 1;
    }
    else {
        argv[cnt] = 0;
    }



    if(!strcmp(argv[cnt-1], "exit")) exit(0); 

    x=fork();

    if (x==0){
        sleep(1);
        printf("I am child to execute %s\n", str);
        y=execve(argv[0], argv, 0);

        if (y<0){
           perror("exec failed");
           exit(1);
        }

    }
    else {
      if(flag == 0) { 
          wait(&status); 
      }
    }


    flag = 0;
    cnt = 0;
   }
}

затем запустите этот код в Linux, сегментируйте фалут (дамп ядра)

также при использовании gdb,

==========================================================

Программа получила сигнал SIGSEGV, Ошибка сегментации. 0x0000003b6572fa96 в __strcmp_sse42 () из /lib64/libc.so.6

==========================================================

почему не работает?

если я наберу / bin / ls -al (что-нибудь без '&'), хорошо работает

тип buf / bin / ls -al & ошибка


person JongSeokKim    schedule 13.05.2018    source источник
comment
ОТ: Не используйте gets(buf)! Вместо этого используйте fgets(buf, 50, stdin).   -  person alk    schedule 13.05.2018
comment
независимо от того, что позволяет визуальная студия, единственный допустимый тип возврата из main() - это int, а не void   -  person user3629249    schedule 01.06.2018


Ответы (1)


Если вы введете &, переменная argv[cnt-1] будет установлена ​​в NULL, поэтому в if(!strcmp(argv[cnt-1], "exit")) первый аргумент функции strcmp будет NULL, что приведет к сбою приложения ...

Более того, ваш код не проверяет переполнение буфера, выход индекса за пределы ... Этот код довольно "опасен"

Это означает, что:

  • вам не следует использовать gets, см. https://stackoverflow.com/a/1694042/808101
  • Убедитесь, что массив argv (примечание: это имя переменной, возможно, не очень хорошее, argv очень часто является аргументом самой программы) достаточно велик при вставке в него элемента
person benjarobin    schedule 13.05.2018
comment
@JongSeokKim Я улучшил свой ответ. Если мой ответ помог решить вашу проблему, подтвердите его. - person benjarobin; 13.05.2018