문제

스택 오버플로를 처리하기 위해 정의된 동작이 있습니까?

프로세스를 종료하는 것 외에는 할 수 있는 일이 많지 않은 것 같습니다.C 표준이 이에 대해 무엇을 말하는지 아는 사람이 있는지 궁금합니다.

도움이 되었습니까?

해결책

표준은 스택을 사용하지 않아도되며 스택 오버플로에 대해서는 할 말이 없습니다.

다른 팁

C99 표준은 스택을 정의하지 않습니다. 초록에서 자동 또는 할당 된 스토리지에 대해서만 논의하는 반면, 오버플로 감지 기능이있는 연속 스택은 자동 저장소를 구현하기위한 메커니즘 중 하나 일뿐입니다.

표준의 7.14 절은 SIGSEGV를 발생하는 신호로 정의합니다. "스토리지에 대한 잘못된 액세스". C의 구현은 신호를 생성 할 필요가 없지만 연속성 고정 크기 스택*을 사용한 구현은 일반적으로 스택 오버플로가 감지되면 Sigsegv를 신호합니다.

SIGSEGV에 대한 신호 핸들러 기능을 등록 할 수 있지만 반환 할 수는 없습니다. [i] f 및 함수가 반환 될 때, SIG의 값이 SIGFPE, Sigill, SIGSEGV 또는 계산 예외에 해당하는 기타 구현 정의 값인 경우, 동작 [u] r은 정의되지 않습니다.".

(* 나는 고의로 C 구현을 사용하지 않았지만 다른 환경에서 성장 가능한 자동 스토리지 도메인을 구현하는 데 사용되는 일반적인 기술의 사용을 방지하는 C 표준의 어떤 것도 알지 못합니다).

C 표준은 스택을 정의하지 않으므로 스택이 오버플로 될 때 발생하는 일을 확실히 정의하지 않습니다.

여기서의 답변은 C 표준과 관련이 없다고 진술 할 때 정확하지만 "프로세스를 종료하는 것 외에도 할 수있는 일이 많이있는 것 같지 않은 것 같지 않다"는 진술은 일반성으로 - 진실.

실제로, 가상 메모리 관리 및 주문형 페이징이있는 대부분의 시스템에서 할당 된 스택은 상당히 작고 (일반적으로 현재 사용중인 것보다 4KB 더 많음) 종종 오버플로 (페이지 오류 인터럽트를 생성). OS는 단순히 다른 페이지를 추가합니다. 스레드의 스택에 메모리.

- 일반적으로 -1MB의 스택 한계는 런 어웨이 프로그램을 보호하기 위해 선택된 상당히 임의의 수치이며 일반적으로 절대 한계는 아닙니다 (인텔 프로세서 IIRC가있는 일부 메모리 모델에 있었음). 일반적으로 각 스레드에 1MB의 물리적 메모리를 할당하는 것은 의미가 없습니다.

답변에 따르면 이 질문, C 표준은 스택 오버플로는 물론 스택의 존재에 대해 할 말조차 없습니다.

나는 어떤 일이 발생하는지에 대한 세부 사항이 운영 체제에 의해 정의된다고 확신하지만, 모든 경우에 프로그램은 종료해야합니다. 스택 오버플로가 발생하면 (적어도 프로그래머로서) 할 수있는 일이 실제로 없다고 가정 할 때 정확합니다. 당신이 실제로 할 수있는 것은 처음에 그들이 일어나지 못하게하는 것입니다.

운영 체제에 달려 있습니다. 그러나 많은 운영 체제를 통해 기본 스택 크기를 덮어 쓸 수 있습니다. 예를 들어 Windows에서 사용할 수 있습니다 이 링커 플래그 스택 크기를 1MB에서 더 높은 값으로 늘립니다.

다른 사람들이 언급했듯이, 표준은 스택에 대해 아무 말도하지 않습니다.

그러나 나는 그것이 스택 오버 플로우 동작을 정의하는 것이라고 생각합니다. 표준은 정의되지 않은 동작을 초래할 것이라고 말할 것입니다.

:: Rimshot ::

일부 시스템에서는 스택 오버플로 이후에 예측 가능한 선호를 보장하면 모든 함수 호출에 상당한 오버헤드가 추가됩니다.따라서 표준에서는 스택 오버플로를 정의되지 않은 동작으로 상당히 합리적으로 간주합니다.구현이 합법적인 프로그램을 실행할 수 있는 효율성을 최대화하는 것이 목표인 경우 이는 전적으로 적절합니다.

또한 이 표준은 시스템에 함수 호출의 적지 않은 깊이를 지원하기에 충분한 스택이 있을 것을 요구하지 않습니다.일부 유용한 프로그램(특히 임베디드 시스템 세계)은 16바이트 미만의 스택으로 작동할 수 있고 반드시 그보다 더 많은 RAM을 확보할 수 없을 수도 있다는 점을 고려하면 넉넉한 스택을 요구하는 것은 "돈"이라는 철학을 위반하는 것입니다. 필요하지 않은 것에 대해서는 비용을 지불하지 마십시오."

불행하게도 프로그램이 어떤 종류의 깊이가 필요한지 말할 수 없고 어떤 종류의 스택을 사용할 수 있는지 질의할 수 없다는 사실로 인해 정의되지 않은 동작에 참여하지 않도록 보장할 수 있는 유일한 프로그램은 스택을 사용하는 프로그램입니다. 최소 보증 미만입니다.임베디드 시스템 세계 밖에서 이는 기본적으로 표준이 장난감보다 큰 프로그램에 대해 아무것도 보장하지 않는다는 것을 의미합니다.

이와 관련하여 C 표준은 모순됩니다. 다음 프로그램을 고려하십시오.

void foo(uintptr_t n)
{
    int a;
    printf("%p\n", (void *)&a);
    if (n+1) foo(n+1);
}
int main()
{
    int a;
    printf("%p\n", (void *)&a);
    foo(0);
}

이 프로그램은 완벽하게 준수하며 최소 번역 한도를 위반하지 않으며 다른 사람들이 말했듯이 스택 한도/오버플로에 대한 표준 언어에는 아무것도 없습니다. 그러나 그것은 생성됩니다 UINTPTR_MAX+2 객체 a (각 통화 수준에서), 생명 시간이 모두 겹치며 각각은 서로 다른 주소가 있습니다. 이것은 단순한 계산 논쟁으로 불가능합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top