Home Minishell ④ 에러 처리
Post
Cancel

Minishell ④ 에러 처리

구현 과정

  • readline 함수의 컴파일 에러

    Untitled

    • 원인 : readline 헤더를 stdio.h 헤더보다 먼저 include해서 발생.

    Untitled

    • 순서를 변경하니 정상적으로 컴파일 됨
  • execve 가 실패하면 wait에 exit code가 13으로 오는 문제가 있음.
    • 역변수를 사용해야 해결됨.
  • wait 과정에서 status를 확인할 때 매크로 함수 사용 관련 이슈
    • 매크로 대신 직접 비트 연산을 사용하여 해결
  • export test=====가 들어오는 경우 에러 발생.
    • export, env, declare의 차이에 대해 공부할 것.
  • echo $$의 처리방법?
    • 허용된 함수 안에서 pid를 받는 방법은 없음. 구현 불가.
  • 시그널 관련
    • ctrl+Dreadline에서 NULL을 받는 경우 exit하도록 구현
    • ctrl+C 누르면 ^C 뜨는 문제는 termiosc_lflagECHOCTL를 꺼줌으로써 해결 가능.

프로그램 실행 과정

파싱 에러

  • 입력이 처음 들어오면 parsing error, 두번째는 segfault 발생

    Untitled

    • 연결리스트의 노드를 뒤에 잇는 함수가 ** 가 아닌 * 로 헤드 노드의 주소를 받아서 생기는 문제.
    • 헤드 노드의 주소의 주소를 넘겨서 해결함
  • expansion 후에 $포함된 문자가 사라지는 문제

    Untitled

    Untitled

    • 저장할 문자열의 시작 인덱스를 잘못 지정함
  • ctrl+D 눌렀을 때 exit이 새 줄에 출력됨
    1
    2
    
      ft_putstr_fd("\033[1A", 2);
      ft_putstr_fd("\033[12C", 2);
    
    • 위의 두 문자열들을 먼저 출력해주어 해결.
  • a>b가 하나의 토큰이 되는 문제

    Untitled

    • 토큰화 과정에서 whille문의 조건문에 >,<,가 아닌 경우도 추가해주어 해결

    Untitled

  • relocate redirection 과정에서 무한루프 걸림

    Untitled

    • 노드를 다시 잇는 과정에서 before_node->next가 아닌 before_node로 값을 잘못 저장함

    Untitled

  • 입력한 key에 해당되는 환경변수가 없는 경우 malloc 발생

    Untitled

    • 환경 변수가 존재하지 않는 경우 빈문자열 반환하여 해결.
  • heredoc 입력 중 ctrl+D를 눌렀을 때 segfault 발생.

    Untitled

    • 같은 상황에서 bash는 입력을 끝내고 명령어를 실행시킴.

      Untitled

    • 입력을 끝내는 조건에 readline의 반환값이 NULL인 경우도 추가하여 해결.

  • 엔터를 치는 경우 파싱 오류

    Untitled

    • 빈문자열을 받더라도 파싱 과정을 거치도록 해서 발생.

    Untitled

    • 받은 input이 빈문자열인 경우 새 프롬프트를 띄우도록 함.

메모리 누수

  • 체크 방법
    • while true; do leaks minishell ;sleep 3; done
    • 새로운 터미널에서 위 내용을 입력한 후에 기존 터미널에서 입력을 하면 3초마다 leak 체크가 가능함.
  • 트리 파싱 이후에 메모리 leak

    Untitled

    • 토큰 리스트를 사용한 후에 해제하지 않아서 발생.
    • 트리 파싱을 마친 이후에 해제해주어 해결.
  • 변수 확장 단계를 거치면 leak 발생 '$a'도 마찬가지

    Untitled

    • 할당한 문자열을 strjoin의 인자로 넘겨주고 메모리를 해제하지 않아서 발생.
    • strjoin_free라는 별도의 함수를 사용하여 해결.
  • 따옴표가 들어오면 leak

    Untitled

    • quote removal 과정에서 quote가 있는 index를 저장하기 위해 할당한 메모리를 해제하지 않아서 발생하였음.
  • 문법적 오류가 발생하면 leak 발생

    Untitled

    • 문법적 오류가 발생하면 token을 free하지 않고 함수를 빠져나가서 발생한 문제
  • 기존에 존재하는 환경변수를 export하게되면 누수 발생

    Untitled

    • key 문자열을 복제한 후에 이미 key가 존재하는 경우에 value, initial_line만 저장하고 key는 해제하지 않아서 발생.

    Untitled

  • 입력에 따옴표가 하나만 들어오는 경우 릭 발생

  • cd 로 존재하지 않는 경로 이동 시 발생

    Untitled

종합

  • segfault 발생

    Untitled

    • signal 함수의 리턴값을 잘못 처리해서 발생.
  • 트리가 제대로 파싱이 안되는 문제

    Untitled

    • 트리 파싱 과정에서 n_cmd 노드를 만드는 중 argv의 인덱스를 증가시키지 않아서 발생한 문제였음.
  • 존재하지 않는 명령어 입력 시 NULL을 참조하는 문제가 생김

    Untitled

  • export로 변수 설정을 하고 echo $a를 하면 아무것도 출력되지 않는 문제

    Untitled

    • 함수를 정리하는 도중 인덱스를 잘못 설정해서 발생한 문제였음.
  • exit을 입력해서 종료하면 segfault 발생

    Untitled

    • ms_exit에 인자가 1개만 들어온 경우의 조건이 없어서 추가해서 해결.
  • echo $?exit code 확인이 안됨.

    Untitled

    • 확장하는 과정에서 조건을 추가해서 해결함

    Untitled

  • 명령어를 최소 1회 실행하고 나면 SIGINT가 무시되는 문제

    Untitled

  • 문법 에러가 발생해 exit code가 수정된 뒤에 입력을 정상적으로 실행해도 0으로 변경되지 않는 문제

    Untitled

  • ctrl+c를 입력하면 ^C가 출력되는 문제

    Untitled

    • tcgetattr로 터미널 속성을 받아온 뒤에 구조체의 c_lflagECHOCTL 플래그를 끈 후에 tcsetattr로 터미널 속성을 적용한다.
    • 터미널을 종료할 때 다시 플래그를 켜준다.

    Untitled

  • 리다이렉션이 여러개 들어오는 경우 무한루프 발생

    Untitled

  • 환경 변수 확장에서 word split을 진행하는 경우 순서가 뒤바뀌는 문제

    Untitled

    • word split 과정의 함수를 쪼개는 과정에서 curr_node를 직접 바꿔주지 않아서 발생함.

    Untitled

  • export로 값을 설정한 환경변수 리스트를 바꾼 뒤에 셸을 실행시켰을 때 설정한 변수가 그대로 출력됨

    Untitled

    • 실행단계에서 환경변수 연결 리스트를 이차원배열로 만들어서 인자로 넣어주어서 발생한 당연한 결과였음
  • export로 이미 존재하는 변수의 값을 변경해도 nested shell에서는 반영이 안되는 문제. 초기 값만 저장?

    Untitled

    Untitled

    • export 빌트인 함수에서 initial line을 수정하지 않은 채 이차원 배열을 만들고 nested shell에 넘겨줘서 발생한 문제

    Untitled

    • echo ‘hello 와 같이 따옴표가 한개만 들어온 경우에 아무것도 출력되지 않음.
    • echo로 명령어를 출력하고 새 프롬프트가 뜨지 않음. exit code도 바뀌지 않음

      Untitled

    • cat < 없는파일 일때 exit code가 잘못 설정됨. (원래: 1)
    • 틸드(~) 확장 에러
    • 리다이렉션이 여러개 있는 경우 뒤쪽 토큰이 사라짐

      Untitled

      • 리다이렉션 재배치 하는 과정에서 발생. 재배치를 하지 않고 트리 파싱 과정에서 리다이렉션을 직접 찾는것으로 변경
  • SHLVL이 unset된 경우 nested shell에서 SHLVL을 확인할 수 없는 문제
    • 없는 경우 nested shell에서 해당 노드를 새로 만들어주어 해결
  • 명령을 실행한 이후에 파이프가 닫히지 않는 문제

    Untitled

    • 파이프를 닫기 위한 조건문을 수정하여 해결.
  • $(변수) 사이에 있는 문자들이 사라지는 문제

    Untitled

    • expr $?+$? 와 같이 붙어서 들어온 경우 bash는 n+n 형태로 출력하는 반면 미니셸은 nn형태로 출력함
    • 확장 전에 직전까지의 문자들을 join해주어 해결
  • cat이 시그널로 종료되면 exit_code 128 + signo로 설정되지 않는 문제

    Untitled

    • waitpid 이후에 status를 확인하는 부분을 수정하여 해결.
  • 따옴표 처리가 제대로되지 않음

    Untitled

    • 각 종류의 따옴표를 문자열 끝까지 다 찾는것이 아닌, 한 종류가 2개가 될때까지만 찾는 것을 반복하여 해결함.

    Untitled

평가 과정

파싱 부분

입력 과정

  • 공백 문자(스페이스, 탭 등)가 여러개 들어온 경우

따옴표 제거

  • "$USER a"와 같이 들어온 경우 뒤에 문자가 두번 출력되고 따옴표 제거가 안되는 문제.

    Untitled

    • 동일한 입력을 여러번 반복하게 되면 segfault 발생
  • 따옴표 안에 확장되는 문자열이 들어오면 crash 발생

    Untitled

    Untitled

    Untitled

    • 따옴표가 존재하는 위치를 1, 아닌 위치를 0으로 갖는 문자열을 만들었는데 메모리를 할당한 공간 밖에다가 값을 저장하려고 해서 발생한 문제.
    • 문자열 끝까지 이동하면서 따옴표가 있을 때만 1로 값을 설정해주어 해결함.

토큰화

  • echo "hello와 같은 따옴표 에러에 대해 에러 메시지를 출력하지 않았음. 에러 발생 시 leak도 발생

Here Document

  • fork를 하고 시그널 설정을 바꿔줘야 cat << abc 하고 시그널 입력시에 heredoc만 끌 수 있음
    • SIGINT가 문제
    • heredoc 입력받는 중에 SIGINT를 받으면 입력 종료하고 새 프롬프트 띄워야 함. exit code 1.
    • 명령어는 실행되면 안됨.
    • 파이프 뒤에 히어독 또 있어도 무시.

실행 부분

exit

  • 인자가 여러개 들어온 경우 첫번째 인자의 문자 여부에 따라 에러메시지를 출력하고 exit

cat

  • cat을 SIGINT한 경우 exit code가 130가 되어야 함.
  • cat 입력하고 SIGQUIT 한 경우 cat이 꺼져야 함.
  • cat이 여러개 들어온 경우 lsof를 입력하면 파일이 계속 열려있음.
  • 파이프가 닫히지 않는 문제
  • cat | cat | cat | ls
    • 이렇게 하면 입력을 3번 받아야 함
  • SIGPIPE를 사용하면 위 문제들을 해결할 수 있음.

unset

  • path를 unset하고 ls등의 명령어를 입력하면 segfault 발생하는 문제.
This post is licensed under CC BY 4.0 by the author.

Minishell ③ 구현 과정

C++ 개념 정리 : namespace