스택과 힙이 충돌 할 때 일어나는 일
스택과 힙이 충돌 할 때 어떤 일이 발생하는지 궁금합니다. 누군가 이것을 만났다면 시나리오를 설명해 주시겠습니까?
미리 감사드립니다.
현대 OS에서 실행되는 현대 언어에서, 당신은 스택 오버 플로우 중 (만세!)를 얻거나 것 malloc()또는 sbrk()또는 mmap()당신이 힙을 확장하려고 할 때 실패합니다. 그러나 모든 소프트웨어가 현대적인 것은 아니므로 실패 모드를 살펴 보겠습니다.
스택이 힙으로 커지면 일반적으로 C 컴파일러가 자동으로 힙의 데이터 구조를 덮어 쓰기 시작합니다. 최신 OS 에는 스택이 무한정 커지는 것을 방지하는 하나 이상의 가상 메모리 가드 페이지 가 있습니다. 가드 페이지의 메모리 양이 최소한 증가하는 절차의 활성화 레코드 크기만큼 크면 OS는 세그 폴트를 보장합니다. MMU가없는 컴퓨터에서 DOS를 실행하고 있다면 아마도 푹 빠졌을 것입니다.
힙이 스택으로 커지면 운영 체제는 항상 상황을 인식해야하며 일종의 시스템 호출이 실패합니다. 의 구현은
malloc()거의 확실하게 실패를 인식하고 반환합니다NULL. 그 후에 일어나는 일은 당신에게 달려 있습니다.
저는 항상 컴파일러 작성자가 OS가 스택 오버플로를 방지하기 위해 가드 페이지를 배치하기를 희망하는 것에 놀랐습니다. 물론,이 트릭은 각각 자체 스택이있는 수천 개의 스레드를 가질 때까지 잘 작동합니다.
이것은 플랫폼에 따라 다릅니다. 많은 플랫폼에서 실제로는 전혀 발생하지 않습니다 (힙과 스택은 서로 다른 페이지에 할당되며 둘이 만나게 될 것입니다.
힙은 위로 성장하고 스택은 아래로 성장한다는 아이디어는 개념적 일뿐입니다. 매우 작은 시스템 (CP / M을 실행 한 이전 8 비트 마이크로)과 일부 PIC 및 기타 플랫 메모리 모델 시스템 (MMU 나 다른 가상 또는 보호 메모리 지원이없는 시스템)에서 힙과 스택은 실제로 이 방식으로 구현되었습니다. 이 경우 동작은 정의되지 않을 것입니다 ...하지만 코드가 손상된 스택의 맨 위에있는 주소로 돌아가거나 힙의 한 부분에서 다른 부분으로 간접 포인터를 따르려고하면 거의 확실하게 충돌이 발생합니다. ..
어떤 경우에도 최신 범용 워크 스테이션이나 서버에서는 볼 수 없습니다. 리소스 제한에 도달하고 malloc 오류가 발생하거나 가상 메모리가 발생하여 결국 시스템이 "빨간색 스위치를 누르십시오"라는 떨리는 더미에 빠져들 것입니다.
그런 시대에는 에곤 스펜 글러 박사의 현명한 말로 돌아갈 때입니다 ....
- 에곤 스펜 글러 박사 : 제가 잊은 말이 아주 중요합니다.
- 피터 벤크 만 박사 : 뭐?
- 에곤 스펜 글러 박사 : 힙이 스택과 충돌하지 않도록하십시오.
- 피터 벤크 만 박사 : 왜요?
- 에곤 스펜 글러 박사 : 나쁠 것입니다.
- Peter Venkman 박사 : 여기서 "좋은 / 나쁜"전체에 대해 약간 모호합니다. "나쁘다"니 무슨 소리 야?
- Egon Spengler 박사 : 모든 생명체가 순간적으로 멈추고 신체의 모든 분자가 빛의 속도로 폭발하는 것을 상상해보십시오.
- Ray Stantz 박사 : 완전한 양성자 반전!
- 피터 벤크 만 박사 : 안 됐군요. 괜찮아. 좋아, 중요한 안전 팁. 고마워, 에곤.
운이 좋으면 메모리 부족 예외 또는 스택 예외가 발생합니다. 운이 좋지 않으면 프로그램이 잘못된 메모리로 이동하고 잘못된 메모리 예외가 발생합니다. 당신이 극도로 운이 좋지 않다면, 프로그램은 계속해서 그것을 수행하고 그것을 폐기해서는 안되며 당신은 당신의 프로그램이 실패한 이유를 결코 알 수 없습니다.
마지막으로 우주가 깨질 수도 있습니다.
스택 / 힙 오버플로가 발생하면 세그멘테이션 오류 또는 메모리 할당 오류가 발생합니다. 다음은 예입니다.
void recursiveFun ()
{
static int i;
// char *str= (char *)malloc (100);
printf ("%d\t", i++);
recursiveFun ();
// free (str);
}
위의 함수를 호출한다고 가정하면 스택이 부족 해지고 프로그램이 충돌합니다. 이제 주석 처리 된 줄을 제거하고 함수를 다시 호출하면 세분화 오류가 이전 버전보다 짧은 시간에 더 적은 재귀로 발생 함을 알 수 있습니다. [내 테스트 환경에서 스택 오버플로는 첫 번째 경우 5237765 재귀 후에 발생했지만 두 번째 시나리오에서는 2616325 재귀 후에 발생했습니다.]
스택 오버플로 오류가 발생합니다. 또는 malloc ()과 같은 새로운 힙 메모리 할당 기능이 실패합니다.
참조 URL : https://stackoverflow.com/questions/1334055/what-happens-when-stack-and-heap-collide
'Program Club' 카테고리의 다른 글
| MIN 또는 MAX에 null 값을 포함하려면 어떻게해야합니까? (0) | 2021.01.06 |
|---|---|
| TSQL 날짜 시간 ISO 8601 (0) | 2021.01.06 |
| XPath로 XML 노드를 선택할 때 네임 스페이스를 무시하는 방법 (0) | 2021.01.05 |
| 자바 스레드가 완료 될 때까지 기다립니다. (0) | 2021.01.05 |
| XML 레이아웃에서 "탭 순서"를 설정할 수 있습니까? (0) | 2021.01.05 |