일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- radare2
- 프로그래밍
- Bandit
- css
- kernel
- 시스템해킹
- Leviathan
- 리버싱
- write up
- wargame
- 리눅스 커널
- 워게임
- 알고리즘
- 컴퓨터구조
- pwn.college
- Pwnable.kr
- 커널
- 시그널
- 어셈블리어
- pwncollege
- 취약점
- 리눅스커널
- 시스템 프로그래밍
- 리눅스
- 시스템
- px4
- C언어
- 드론
- C++
- 시스템프로그래밍
- Today
- Total
Computer Security
#30 프로그램 실행과 종료처리 본문
프로세스를 fork한 이후, 새로운 프로그램을 실행시키는 exec계열의 API와 프로세스를 생성한 이후에 child process가 종료될 때, parent process에서 child process를 처리할 수 있는 API를 알아보자.
1. 하나의 프로세스(parent process)가 fork 하면 child process가 생긴다.(parent process 랑 동일한내용복제)
2. exec() API를 호출하게 되면 원래는 parent process와 동일한 코드나 데이터를 가지고 있었는데, 내용이 전부 없어지고 새로운 내용으로 채워진다.
exec APIs
int execl(const char *path, const char *arg, .../* (char *) NULL */);
int execlp(const char *file, const char *arg, .../* (char *) NULL */);
int execle(const char *path, const char *arg, .../* (char *) NULL, char *
const envp[] */);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int ececvpe(const char *file, char *const argv[], char *const envp[]);
execl : list based arguments
execv : vector(char pointer array) based arguments
suffix 'p' : $PATH에서 경로 찾음
suffix 'e' : 새로운 환경 변수 설정
반환 값 : 실패시에만 -1 리턴
프로세스 종료 - exit()
void exit(int status);
파라미터
- status : exit status
- 0 : 성공
- non-zero : 실패
좀비 프로세스
- 종료 처리 중 멈춰있는 상태의 프로세스
- 자식 프로세스가 종료되었지만 부모 프로세스가 해당 프로세스의 종료에 대해 처리하지 않아 커널 프로세스 테이블에 남아있는 상태의 프로세스
- 좀비 프로세스가 생성되면 커널 프로세스 테이블을 점유 -> 시스템 리소스 장악
- 좀비 프로세스를 만들지 않으려면 -> 부모 프로세스가 자식 프로세스에 대해 종료 처리를 해야한다.
자식 프로세스 종료 시그널 - SIGCHLD
언제 : 자식 프로세스가 종료 되었을 때
누구 : 부모 프로세스에게
무엇을 : SIGCHLD 시그널
어떻게 : signal 전송
부모 프로세스는 SIGCHLD에 대해 수신 대기
SIGCHLD를 수신하면 자식 프로세스 상태 확인 -> 종료된 자식 프로세스 처리
자식 프로세스 종료 대기 - wait()
pid_t wait(int *wstatus);
파라미터
- wstatus : child process의 종료 상태
반환 값
- 성공 시 : terminated 된 자식 프로세스의 pid
- 실패 시 : -1
1. blocking을 하면서 자식 프로세스들 중 누군가가 종료되길 기다린다.
2. 종료된 프로세스의 정보를 wstatus에 상태를 받아온다.
3. 처리한다.
wstatus 값을 이용해서 여러가지 정보를 추출할 수 있는 매크로
WIFEXITED (wstatus) : child프로세스가 정상적으로 종료되었는지 확인한다.(if예외처리)
WEXITSTATUS (wstatus) : 정상적으로 종료될 때 value 리턴(if예외처리)
WIFSIGNALED (wstatus) : 프로세스가 종료될 때 시그널을 받아서 종료된 경우
WTERMSIG (wstatus) : 시그널 번호를 알려주는 매크로
WCOREDUMP (wstatus) : 코어덤프 파일을 생성했으면, true 리턴
WIFSTOPPED (wstatus) : child프로세스가 stop 된경우 true 리턴
WSTOPSIG (wstatus) : stop을 시킨 시그널이 무엇인지 리턴
WIFCONTINUED (wstatus) : 중단되었다가 다시 continue 된 경우를 확인 할 수 있는 매크로
자식 프로세스 종료 대기 - waitpid()
pid_t waitpid(pid_t pid, int *status, int options);
파라미터
- pid : 종료 대기할 프로세스의 pid
- status : 자식 프로세스의 종료 코드
- options
- WNOHANG : 해당 pid가 살아있는경우 바로 리턴
- WUNTRACED : chlid프로세스가 STOP이 된 경우에도 리턴 해주도록 하는 옵션
- WCONTINUED : SIGCONTINUE를 받으면 다시 시작을 하는데, 그때도 리턴 해주도록 하는 옵션
반환 값
- 양수 : 상태가 바뀐 child process의 pid
- 0 : WNOHANG 지정시
- -1 : 실패
자식 프로세스 종료 대기 - wait4()
pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
파라미터
- pid : 종료 대기할 프로세스의 pid
- status : 자식 프로세스의 종료 코드
- options
- WNOHANG : 해당 pid가 살아있는경우 바로 리턴
- WUNTRACED : chlid프로세스가 STOP이 된 경우에도 리턴 해주도록 하는 옵션
- WCONTINUED : SIGCONTINUE를 받으면 다시 시작을 하는데, 그때도 리턴 해주도록 하는 옵션
- rusage : 리소스 사용량
반환 값
- 양수 : 상태가 바뀐 child process의 pid
- 0 : WNOHANG 지정시
- -1 : 실패
sturct rusage
'리눅스 시스템 프로그래밍' 카테고리의 다른 글
#32 CPU 구조 (2) | 2022.10.07 |
---|---|
#31 프로그램 실행과 종료처리 (실습) (2) | 2022.10.06 |
#29 프로세스 개념, 프로세스 생성(실습) (2) | 2022.10.04 |
#28 프로세스 개념, 프로세스 생성 (0) | 2022.10.03 |
#27 I/O Multiplexing : epoll (실습) (0) | 2022.10.02 |