나는 clone()에 대한 Linux 매뉴얼 페이지를 주의 깊게 읽었으며 clone() 래퍼와 "원시" 시스템 호출 간의 차이점을 이해합니다. 그러나 내가 이해하지 못하는 것은 래퍼에서 CLONE_VM이 사용되지 않는 경우에도 상위 프로세스가 하위 프로세스에 스택을 할당해야 하는 이유입니다.
CLONE_VM을 사용하지 않으면 래퍼가 스택 인수를 무시합니까? 그렇다면 왜 필요한가요? 원래 시스템 호출에서는 null이 허용되는데 이는 의미가 있지만 래퍼에 이것이 필요한 이유를 이해할 수 없습니다. 래퍼가 말하지 않아도 자식과 부모가 메모리를 공유할 수 있도록 합니까?
답변1
필수 스택 매개변수는 다음과 같습니다.fn
논쟁. 원시 커널 시스템 호출은 다음과 같이 동작하기 때문에 항상 스택을 필요로 하지 않습니다 fork
. 시스템 호출이 반환될 때 하위 항목의 실행이 시작됩니다. 그런 다음 libc 래퍼는 호출 내용을 설정해야 하며 fn
이를 수행하려면스택이 필요합니다(그리고이것은 항상 행해져 왔습니다.).
clone
따라서 시스템 호출을 통해 함수를 호출하는 코드 fn
( thread_start
glibc 코드) 에 정보를 전달 하기 위해 래퍼를 호출할 때 항상 스택이 필요합니다 .
답변2
나는 스스로 답을 찾았다고 믿는다. 복제 래퍼(clone.s)의 x86-64 소스 파일을 살펴보면 다음과 같은 흥미로운 코드를 발견했습니다.
movq %rdi,0(%rsi)
그러면 하위 프로세스 스택에 함수 포인터가 배치됩니다. 이는 복제 시스템 호출 전에 발생합니다. 내가 이해한 것이 맞다면 하위 프로세스가 래퍼에 전달된 함수로 돌아가게 됩니다. 이는 함수 주소를 넣을 수 있도록 래퍼에 스택 매개변수가 필요한 이유를 설명합니다. 이는 스택이 함수 포인터와 매개변수를 수용할 수 있을 만큼만 커야 함을 의미하는 것 같습니다. 매뉴얼 페이지에서 왜 이것을 설명하지 않거나 읽는 동안 뭔가를 놓쳤는지 잘 모르겠습니다.