2011-02-07 9 views
3

많은 운영 체제에서 스택과 힙은 프로세스의 가상 주소 공간의 반대쪽에서 시작하여 서로를 향해 증가합니다. 이렇게하면 힙을 치지 않고 가능한 한 스택을 확장 할 수 있습니다.운영 체제에서 스택 오버플로를 어떻게 감지합니까?

스택 오버플로를 유발하는 프로그램이 있다고 가정합니다. 현재 나의 이해는 스택이 제어 할 수 없게 힙쪽으로 성장하여 결과적으로 스택을 쳤다는 것입니다. 이 올바른지? 그렇다면 운영 체제가 스택 오버플로가 발생하는 것을 어떻게 감지합니까? OS가 연속 메모리 영역에 있기 때문에 스택의 일부로 힙에 할당 된 가상 메모리를 사용하려고한다는 것을 OS가 감지하지 못하는 것 같습니다.

운영체제에 따라 다르지만 이것이 발생하는 메커니즘에 대한 통찰력이 인 경우 운영 체제가 분명 도움이 될 것입니다. 이것은 잠시 나에게 괴롭혀 왔고 어떤 좋은 설명도 찾을 수없는 것 같습니다.

답변

3

OS는 스택에 약간의 공간을 할당합니다. 프로세스가 스택의 할당되지 않은 부분에 액세스하면 프로세서에서 페이지 오류를 일으키고 OS에서 캐치합니다. OS가 스택을 늘리는 것이 여전히 합리적이라면 OS는 새로운 공간을 할당하고 프로세스에 제어를 반환합니다. 합리적이지 않으면 스택 오버플로 예외가 발생합니다.

+0

@ CAFxX- 이것은 합리적인 것처럼 보이지만 후속 조치로 스택 프레임이 매우 큰 프로그램 (가상 메모리 페이지보다 큼)이 있다고 가정합니다. 그런 다음 내 프로그램이 스택에 많은 페이지를 할당 한 다음 스택 뒤의 메모리와 힙의 메모리로 "건너 뛸 수"있지 않을까요? – templatetypedef

+0

OS가 그 자리에 수표를 가지고 있습니다. 합리적이지 않으면 스택 오버플로가 발생합니다. 스택이 너무 많이 커지면 (예를 들어 실제로 많이 힙에 도달하는 경우 - 일반적으로 제한이 훨씬 엄격하고 플랫폼에 따라 다름) 의존성) OS는 스택 오버 플로우를 발생시킴으로써 당신을 멈추게 할 것입니다 - 이것은 일반적으로 Bad Things (TM)가 일어나지 않도록 프로세스를 종료합니다. – CAFxX

+1

다른 유형의 스택 오버 플로우, 즉 스택 손상을 초래하는 스택 오버 플로우에 대해 묻는 중일뿐입니다. 이것은 다르며 일반적으로 스택에 "센티넬"을 배치하여 프로세스 런타임에서 검사합니다. 센티널이 겹쳐 쓰면 스택이 손상되어 스택 오버플로/손상 예외가 발생 함을 의미합니다 (단, 일반적으로 OS가 아니라 프로세스 런타임에 의해). – CAFxX

1

이것은 직감이지만 스택이 JVM 작업과 같이 힙 소리를 방해하지 않는지 확인합니다. 스택이 힙 (붕괴되기 전에)을 덮어 쓰기 시작하도록 내 자신의 끔찍한 프로그래밍 언어를 만들 수없는 이유가 없습니다.

+0

@ WuHoUnited- 사실 인 JVM의 경우, JVM은 스택과 힙을 시뮬레이트하는 소프트웨어이므로이를 관리하는 데 훨씬 더 능동적 인 제어 기능을 제공합니다. 특히 스택 깊이 제한을 설정할 수 있습니다.OS가 모든 스택 프레임을 설정할 책임이없는 C 나 C++ 같은 언어로 네이티브 코드가 어떻게되는지 궁금합니다. – templatetypedef

+0

죄송합니다. 여기 너무 많은 자바 질문을 읽었습니다. – WuHoUnited

1

스택 오버플로는 스택에서 뒤로 이동합니다. 스택에서 이미 초기화 된 부분의 데이터를 덮어 쓰므로 스택이 아래쪽으로 커질 수 있기 때문에 가능합니다.

따라서 운영 체제는 원하는 언제든지 스택의 초기화 된 부분을 수정할 수 있으므로이 조건을 감지 할 수 없습니다.

스택 확장은 스택 공간을 사용하는 프로세스에서 작동하며 페이지가 설정되지 않았기 때문에 페이지 폴트 처리기로 트래핑합니다. 일부 OS는 "가드 페이지"에서만 이러한 액세스를 허용합니다. 즉, 현재 스택 바로 전에 페이지가 재 할당을 트리거하고, 다른 사용자는 스택 포인터 레지스터의 내용을 오류 발생 시점에서보고 이것이 스택 액세스.

1

대부분의 최신 프로세서에는 MMU (메모리 관리 장치)가 있으며 각 프로그램에 가상 주소를 적용하고 각 프로그램은 자체 메모리 공간에 존재하는 "하드웨어"장치입니다. OS가이 MMU를 처리하고 프로그램이 전용 메모리에서 주소를 읽거나 쓸 때 MMU가 인터럽트를 발생시킵니다.

http://en.wikipedia.org/wiki/Memory_management_unit

꽤 straitgfoward는 SO 감지하는 방법이다이 방법. 스택 및 힙이 연속 메모리 주소에 없습니다.

가드 단어를 사용하는 다른 접근 방식을 보았습니다. 각 프로세스에 대한 스택은 힙 및 채워진 위트 가드 워드 (0xc0cac01a와 같은 것)에 할당되었습니다. 이렇게하면 보호 단어를 세는 것만으로 각 프로세스에 대한 스택 크기를 쉽게 얻을 수있었습니다. 적어도 하나의 보호 단어가 없으면 운영 체제는 패닉을 일으켰습니다.

관련 문제