gcc를 사용하여 프로그램을 컴파일하고 bash 쉘에서 실행하려고 하면 bash가 이를 실행하는 단계의 정확한 순서는 무엇입니까?
나는 그것이 fork()
, , , , (및 다른 것들)과 관련되어 있다는 것을 알고 있지만 누군가가 정확한 단계 순서와 적절한 읽기 참고 자료를 제공할 수 있습니까 execve()
?loader
dynamic linker
편집하다:
답변을 보면 이 질문에는 많은 가능성이 담겨 있는 것 같습니다. 간단한 사례로 범위를 좁히고 싶습니다.
(test.c는 hello world를 인쇄합니다)
$ gcc test.c -o test
$ ./test
위 상황( )의 단계는 무엇입니까 ./test
? 특히 로드, 링크 등을 위한 일부 하위 프로세스에서 bash 프로그램을 시작합니까?
답변1
/usr/libexec/foo
글쎄요, 실제 프로그램을 실행하기 전에 먼저 확장/해석되는 쉘 별칭이나 함수가 있을 수 있고, 그 다음 정규화된 파일 이름( )과 전체에서 찾아볼 파일 이름 사이에 차이가 있을 수 있기 때문에 정확한 순서는 다를 수 있습니다. 디렉토리 환경 PATH
변수(그냥 foo
). 더욱이, 실행의 세부 사항은 foo | bar | zot
쉘이 이와 유사한 것보다 더 많은 작업( 물론 일부 , fork(2)
및 기타 시스템 호출)을 수행하도록 요구하여 상황을 복잡하게 만들 수 있습니다 . 이는 쉘이 자신을 호출하기 때문에 훨씬 적은 작업이 필요합니다. 새로운 프로그램(즉, 그렇지 않음 ). 또한 프로세스 그룹(특히 포그라운드 프로세스 그룹, 누군가가 매싱을 시작할 때 모든 PID를 가져옴 ) , 세션 및 작업이 백그라운드에서 실행될지, 모니터링될지( ) 또는 무시될지() 가 중요합니다. 배경 . /O 리디렉션 세부 정보는 표준 입력이 shell()에 의해 닫히는지 여부 또는 파일이 stdin()으로 열리는 지 여부 와 같은 사항도 변경합니다 .dup(2)
pipe(2)
exec foo
fork
SIGINT
CtrlCfoo &
foo & disown
foo <&-
foo < blah
strace
또는 이와 유사한 것들은 이 프로세스 중에 수행된 특정 시스템 호출에 대한 정보를 제공하며 각 호출에 대한 매뉴얼 페이지가 있어야 합니다. 적합한 시스템 수준 읽기는 Stevens의 "UNIX 환경의 고급 프로그래밍"에 있는 장 중 하나이며, 쉘 책(예: "Bash에서 Z 쉘까지")에서는 쉘 측면을 더 자세히 다룹니다.
답변2
코드 명확성을 위해 교과서 예제 셸이 이미 실행 중이라고 가정하면(따라서 동적 링커가 완성됨) 언급한 명령을 사용하려면 셸에서 다음 시스템 호출을 수행해야 합니다.
- 읽기: 이 경우 다음 명령 gcc를 가져옵니다.
- 포크: 두 개의 프로세스가 필요합니다. 상위 프로세스의 pid는 500이고 하위 프로세스는 설명에 사용됩니다.
- 상위 프로세스는 wait(501)를 호출하고 하위 프로세스는 exec를 호출합니다. 이 시점에서 쉘은 더 이상 PID 501에서 실행되지 않습니다. gcc는 적어도 열기, 닫기, 읽기, 쓰기, chmod, 포크, 실행, 대기 및 종료를 포함하여 많은 수의 시스템 호출을 수행합니다.
- gcc가 exit를 호출하면 wait가 반환되고 write를 호출하여 프롬프트를 표시한 다음 프로세스를 반복합니다.
물론 더 복잡한 명령은 이 기본 시퀀스의 복잡성을 증가시킵니다. 기본 복잡성의 두 가지 간단한 예는 기본 io 리디렉션입니다. 여기서는 열기, 닫기, dup 시퀀스가 포크와 exec 사이에 삽입되고 백그라운드 프로세스에서는 대기를 건너뜁니다(그리고 또 다른 대기가 sigchld 처리기에 추가됩니다).
답변3
섹션을 읽는 것이 좋습니다8.4.6 fork와 execve를 사용하여 프로그램 실행하기
존재하다 http://www.groupes.polymtl.ca/inf2610/documentation/ComputerSystemBook.pdf