세그멘테이션 결함은 어떻게 작동합니까?


266

"CPU의 MMU가 신호를 보낸다"와 "커널이 문제를 일으키는 프로그램으로 보내서 종료시킨다"는 것 외에는 이것에 관한 정보를 찾을 수없는 것 같습니다.

나는 아마도 신호를 쉘에 보내고 쉘은 문제를 일으키는 프로세스를 종료하고 인쇄하여 신호를 처리한다고 가정했다 "Segmentation fault". 그래서 나는 crsh (crap shell) 라고 불리는 매우 작은 쉘을 작성하여 그 가정을 테스트했습니다 . 이 쉘은 사용자 입력을 받아 system()메소드에 피드하는 것 외에는 아무것도하지 않습니다 .

#include <stdio.h>
#include <stdlib.h>

int main(){
    char cmdbuf[1000];
    while (1){
        printf("Crap Shell> ");
        fgets(cmdbuf, 1000, stdin);
        system(cmdbuf);
    }
}

그래서이 쉘을 맨 터미널에서 ( bash아래에서 실행 하지 않고) 실행했습니다. 그런 다음 segfault를 생성하는 프로그램을 계속 진행했습니다. 내 가정이 정확하면 a) crash crsh, xterm 닫기, b) 인쇄 안 함 "Segmentation fault"또는 c) 둘 다입니다.

braden@system ~/code/crsh/ $ xterm -e ./crsh
Crap Shell> ./segfault
Segmentation fault
Crap Shell> [still running]

정사각형으로 돌아가서 방금이 작업을 수행하는 것이 쉘이 아니라 그 아래 시스템이라는 것을 보여주었습니다. "세그먼트 결함"은 어떻게 인쇄 되나요? "누가"하고 있습니까? 커널? 다른 것? 신호와 모든 부작용은 하드웨어에서 프로그램의 최종 종료로 어떻게 전파됩니까?


43
crsh이런 종류의 실험에 좋은 아이디어입니다. 우리 모두와 그 배경에 대한 아이디어를 알려 주셔서 감사합니다.
Bruce Ediger

30
내가 처음봤을 때 crsh, 그것이 "충돌"이라고 발음 될 것이라고 생각했습니다. 그것이 똑같은 이름인지 확실하지 않습니다.
jpmc26

56
이것은 좋은 실험입니다 ...하지만 system()후드 아래에서 무엇을하는지 알아야합니다 . 그것은 밝혀 system()쉘 프로세스를 생성합니다! 따라서 셸 프로세스는 다른 셸 프로세스를 생성하고 해당 셸 프로세스 (아마도 /bin/sh이와 비슷한 것)가 프로그램을 실행하는 프로세스입니다 . 방법 /bin/sh또는 bash작업은 사용하는 것입니다 fork()exec()(또는 다른 함수에서 execve()가족).
Dietrich Epp

4
@BradenBest : 맞습니다. 매뉴얼 페이지를 읽고 man 2 wait,이 매크로를 포함 WIFSIGNALED()하고 WTERMSIG().
Dietrich Epp

4
@DietrichEpp 당신이 말한대로! 나는 (WIFSIGNALED(status) && WTERMSIG(status) == 11)구피 ( "YOU DUN GOOFED AND TRIGGERED A SEGFAULT")를 인쇄하도록 검사를 추가하려고 했습니다 . 에서 segfault프로그램을 실행하면 crsh정확히 인쇄되었습니다. 한편, 일반적으로 종료되는 명령은 오류 메시지를 생성하지 않습니다.
Braden Best

답변:


248

모든 최신 CPU는 현재 실행중인 기계 명령 을 중단 할 수 있습니다. 아무 일도 없었던 것처럼 나중에 실행 을 재개 할 수 있도록 충분한 상태 (일반적으로 항상 스택에있는 것은 아님)를 저장 합니다 (중단 된 명령은 처음부터 처음부터 다시 시작됨). 그런 다음 인터럽트 처리기 실행을 시작합니다. 인터럽트 처리기 는 더 많은 머신 코드이지만 CPU가 미리 어디에 있는지 알 수 있도록 특별한 위치에 배치됩니다. 인터럽트 처리기는 항상 운영 체제 커널 의 일부입니다. 가장 큰 권한으로 실행되고 다른 모든 구성 요소의 실행을 감독하는 구성 요소입니다. 1,2

인터럽트는 동기식 일 수 있습니다 . 즉, CPU 자체에서 현재 실행중인 명령에 대한 직접 응답으로 트리거되거나 비동기식 일 수 있습니다. 즉, 네트워크에 도착하는 데이터와 같은 외부 이벤트로 인해 예기치 않은 시간에 발생합니다. 포트. 일부 사람들은 비동기 인터럽트에 대해 "인터럽트"라는 용어를 예약하고 대신에 동기 인터럽트 "트랩", "오류"또는 "예외"를 호출하지만 이러한 단어는 모두 다른 의미를 가지므로 "동기 인터럽트"를 고수 할 것입니다.

이제 대부분의 최신 운영 체제에는 프로세스 개념이 있습니다 . 기본적으로 이것은 컴퓨터가 동시에 여러 프로그램을 실행할 수있는 메커니즘이지만 운영 체제가 메모리 보호를 구성하는 방법의 주요 측면이기도합니다 . 아직도 모든 ) 현대 CPU를. 그것은 가상 메모리 와 함께 간다메모리 주소와 RAM의 실제 위치 간의 매핑을 변경하는 기능입니다. 메모리 보호를 통해 운영 체제는 각 프로세스에 전용 RAM 덩어리를 제공하여 액세스 할 수 있습니다. 또한 운영 체제 (일부 프로세스를 대신하여 작동)가 RAM 영역을 읽기 전용, 실행 가능, 협력 프로세스 그룹간에 공유 등으로 지정할 수 있습니다. 또한 메모리 만 액세스 할 수있는 메모리 덩어리가 있습니다. 핵심.

각 프로세스가 CPU가 허용하도록 구성된 방식으로 만 메모리에 액세스하는 한 메모리 보호는 보이지 않습니다. 프로세스가 규칙을 어기면 CPU는 동기식 인터럽트를 생성하여 커널에게 항목을 정렬하도록 요청합니다. 프로세스가 실제로 규칙을 위반 하지 않았기 때문에 프로세스가 계속 진행되기 전에 커널 만 약간의 작업을 수행해야합니다. 예를 들어, RAM의 공간을 확보하기 위해 프로세스 메모리의 페이지를 스왑 파일로 "제거"해야하는 경우 커널은 해당 페이지를 액세스 할 수 없음으로 표시합니다. 다음에 프로세스가 프로세스를 사용하려고하면 CPU가 메모리 보호 인터럽트를 생성합니다. 커널은 스왑에서 페이지를 검색하여 원래 위치로 되돌리고 다시 액세스 가능으로 표시 한 후 실행을 재개합니다.

그러나 프로세스가 실제로 규칙을 어겼다 고 가정하십시오. RAM이 매핑되지 않은 페이지에 액세스하려고 시도했거나 머신 코드를 포함하지 않는 것으로 표시된 페이지를 실행하려고했습니다. 일반적으로 "Unix"로 알려진 운영 체제 제품군은 이 상황을 처리 하기 위해 신호 를 사용 합니다. 4 신호는 인터럽트와 유사하지만 하드웨어에 의해 생성되고 커널에 의해 필드 화되는 것이 아니라 커널에 의해 생성되고 프로세스에 의해 필드 화됩니다. 프로세스는 신호 핸들러를 정의 할 수 있습니다그들 자신의 코드로 커널에게 그들이 어디에 있는지 알려주십시오. 그런 다음 해당 신호 처리기가 실행되어 필요한 경우 정상적인 제어 흐름을 방해합니다. 신호는 모두 숫자와 두 개의 이름을 가지며, 하나는 암호 약어이고 다른 하나는 약간 덜 암호 문구입니다. 프로세스가 메모리 보호 규칙을 위반할 때 생성되는 신호는 (일반적으로) 번호 11이며 이름은 SIGSEGV"세그먼트 폴트"입니다. 5,6

신호와 인터럽트의 중요한 차이점은 모든 신호에 기본 동작 이 있다는 것입니다 . 운영 체제가 모든 인터럽트에 대한 핸들러를 정의하지 못하면 OS의 버그이며 CPU가 누락 된 핸들러를 호출하려고하면 전체 컴퓨터가 충돌합니다. 그러나 프로세스는 모든 신호에 대한 신호 처리기를 정의 할 의무가 없습니다. 커널이 프로세스에 대한 신호를 생성하고 해당 신호가 기본 동작으로 남은 경우 커널은 기본값을 그대로 유지하면서 프로세스를 방해하지 않습니다. 대부분의 신호의 기본 동작은 "아무것도하지 않음"또는 "이 프로세스를 종료하고 코어 덤프를 생성 할 수도 있습니다." SIGSEGV후자 중 하나입니다.

요약하자면 메모리 보호 규칙을 위반 한 프로세스가 있습니다. CPU가 프로세스를 일시 중단하고 동기 인터럽트를 생성했습니다. 커널은 해당 인터럽트를 SIGSEGV처리하여 프로세스에 대한 신호를 생성했습니다 . 의는 않은 과정을 가정 해 봅시다 하지 위한 신호 처리기를 설정을 SIGSEGV, 그래서 커널은 프로세스를 종료하는 기본 동작을 수행한다. 이것은 _exit시스템 호출 과 동일한 효과를 갖습니다 . 열린 파일이 닫히거나 메모리가 할당 해제됩니다.

이 시점까지는 사람이 볼 수있는 메시지가 인쇄되지 않았으며 쉘 (또는 더 일반적으로 막 종료 된 프로세스상위 프로세스 )은 전혀 관여하지 않았습니다. 부모가 아닌SIGSEGV 규칙을 어기는 프로세스로 이동합니다 . 그러나 순서 의 다음 단계는 상위 프로세스에 하위 프로세스가 종료되었음을 알리는 것입니다. 이것은 부모가 이미 중 하나를 사용하여,이 통지 될 때까지 대기하는 경우에 간단한이있는 여러 가지 방법에 일어날 수있는 시스템 호출 ( , , , 등). 이 경우 커널은 시스템 호출을 반환하고 상위 프로세스에 종료 상태 라는 코드 번호를 제공 합니다.waitwaitwaitpidwait4. 7 종료 상태는 부모에게 자식 프로세스가 종료 된 이유를 알려줍니다 . 이 경우 SIGSEGV신호 의 기본 동작으로 인해 자식이 종료되었음을 알게됩니다 .

그런 다음 부모 프로세스는 메시지를 인쇄하여 이벤트를 사람에게보고 할 수 있습니다. 쉘 프로그램은 거의 항상 이것을합니다. 당신은 crsh이 작업을 수행하는 코드를 포함하지 않지만 C 라이브러리 루틴이 있기 때문에, 어쨌든 발생하는 system모든 기능을 갖춘 쉘 실행 /bin/sh"후드"를. 이 시나리오 crsh에서 조부모 입니다. 부모 프로세스 알림은으로 필드 화되어 /bin/sh일반적인 메시지를 인쇄합니다. 그런 다음 /bin/sh더 이상 할 일이 없으므로 자체 종료됩니다. C 라이브러리의 구현은 해당 종료 알림 을 system수신 합니다 . 의 반환 값을 검사하여 코드에서 종료 알림을 볼 수 있습니다.system; 그러나 손자 프로세스가 segfault에서 죽었다는 것을 알 수는 없습니다. 중간 쉘 프로세스에서 사용 되었기 때문입니다.


각주

  1. 일부 운영 체제는 커널의 일부로 장치 드라이버 를 구현하지 않습니다 . 그러나 모든 인터럽트 처리기는 여전히 커널의 일부 여야하며, 하드웨어는 커널 이외 의 다른 작업을 허용하지 않기 때문에 메모리 보호를 구성하는 코드도 마찬가지 입니다.

  2. 커널보다 더 많은 권한을 가진 "하이퍼 바이저"또는 "가상 머신 관리자"라는 프로그램이있을 수 있지만이 답변의 목적 상 하드웨어의 일부로 간주 될 수 있습니다 .

  3. 커널은 프로그램 이지만 프로세스 는 아닙니다 . 도서관과 비슷합니다. 모든 프로세스는 자체 코드 외에도 때때로 커널 코드의 일부를 실행합니다. 커널 코드 실행 하는 많은 "커널 스레드"가 있을 수 있지만 여기서는 신경 쓰지 않습니다.

  4. 유닉스의 구현으로 간주 될 수없는 더 이상 처리해야 할 유일한 OS 는 물론 Windows입니다. 이 상황에서는 신호를 사용하지 않습니다. (실제로 신호 가 없으며, Windows에서는 <signal.h>인터페이스가 C 라이브러리에 의해 완전히 위조됩니다.) 대신 " 구조적 예외 처리 " 라는 것을 사용 합니다.

  5. 일부 메모리 보호 위반은 SIGBUS대신 ( "버스 오류")를 생성 SIGSEGV합니다. 둘 사이의 선이 지정되어 있지 않으며 시스템마다 다릅니다. 에 대한 핸들러를 정의하는 프로그램을 작성한 경우에 SIGSEGV대해 동일한 핸들러를 정의하는 것이 좋습니다 SIGBUS.

  6. "세그먼트 결함"은 원래 Unix 를 실행 한 컴퓨터 중 하나 ( 아마 PDP-11)에 의해 메모리 보호 위반에 대해 생성 된 인터럽트의 이름입니다 . " 세그먼트 화 "는 메모리 보호의 한 유형 이지만, 현재 "세그먼트 화 오류 " 라는 용어 는 일반적으로 모든 종류의 메모리 보호 위반을 의미합니다.

  7. 부모 프로세스에 자식이 종료되었음을 알리는 다른 모든 방법은 결국 부모 호출 wait및 종료 상태를 수신하게됩니다. 다른 일이 먼저 일어난다는 것입니다.


@zvol : ad 2) CPU가 프로세스에 대해 아무것도 알고 있다고 말하는 것이 옳지 않다고 생각합니다. 제어를 전달하는 인터럽트 핸들러를 호출한다고 말해야합니다.
user323094

9
@ user323094 최신 멀티 코어 CPU는 실제로 프로세스에 대해 상당히 알고 있습니다. 이 상황에서는 메모리 보호 결함을 트리거 한 실행 스레드 만 일시 중단 할 수 있습니다. 또한 저수준의 세부 정보를 얻지 않으려 고했습니다. 사용자 공간 프로그래머의 관점에서, 2 단계에서 이해해야 할 가장 중요한 것은 메모리 보호 위반을 감지 하는 하드웨어 라는 것입니다. "불쾌한 프로세스"를 식별 할 때 하드웨어, 펌웨어 및 운영 체제 간의 정확한 인력 분담이 줄어 듭니다.
zwol

순진한 독자를 혼란스럽게 할 수있는 또 다른 미묘한 점은 "커널이 문제를 일으키는 프로세스에 SIGSEGV 신호를 보냅니다"입니다. 일반적인 전문 용어를 사용하지만 실제로는 커널이 프로세스 바에서 신호 foo를 처리하도록 지시 합니다 (즉, 신호 처리기가 설치되어 있지 않은 한 사용자 랜드 코드는 커널에 의해 해결되는 문제가 아닙니다). 나는 때때로 그런 이유로 "프로세스에서 SIGSEGV 신호를 발생시킨다" 를 선호한다 .
dmckee

2
SIGBUS (버스 오류)와 SIGSEGV (세그먼트 결함)의 중요한 차이점은 다음과 같습니다. SIGSEGV는 CPU 주소에 액세스하지 않아야한다는 것을 알고 외부 메모리 버스를 요청하지 않을 때 발생합니다 . SIGBUS는 CPU가 외부 주소 버스에 요청을 한 후 주소 지정 문제 만 발견하면 발생합니다. 예를 들어, 버스의 아무 것도 응답하지 않는 물리적 주소를 요청하거나 잘못 정렬 된 경계 (하나 대신에 두 개의 물리적 요청이 필요함)에서 데이터를 읽도록 요청하는 경우
Stuart Caie

2
@StuartCaie 인터럽트 의 동작을 설명하고 있습니다 . 실제로, 많은 CPU가 개요를 구분합니다 (일부는 그렇지 않지만 둘 사이의 선은 다양합니다). 신호 SIGSEGV와 SIGBUS 그러나,되어 있지 확실 두 CPU 레벨 조건에 매핑. POSIX에서 SIGSEGV가 아닌 SIGBUS를 요구하는 유일한 조건 mmap은 파일보다 큰 메모리 영역에 파일을 넣은 다음 파일 끝을 넘어 "전체 페이지"에 액세스하는 경우입니다. (POSIX는 SIGSEGV / SIGBUS / SIGILL 등이 언제 발생하는지에 대해 매우 모호합니다.)
zwol

42

쉘은 실제로 그 메시지와 관련이 있으며 crsh간접적으로 쉘을 호출합니다 bash.

나는 항상 결함을 세분화하는 작은 C 프로그램을 작성했습니다.

#include <stdio.h>

int
main(int ac, char **av)
{
        int *i = NULL;

        *i = 12;

        return 0;
}

기본 쉘에서 실행 zsh하면 다음과 같이 나타납니다.

4 % ./segv
zsh: 13512 segmentation fault  ./segv

에서 실행할 때 bash귀하의 질문에 언급 한 내용을 얻습니다.

bediger@flq123:csrc % ./segv
Segmentation fault

내 코드에서 신호 처리기를 작성 거라고, 그때는 것을 깨달았다 system()에서 사용하는 라이브러리 호출 crsh간부는, 쉘의 /bin/sh에 따라 man 3 system. 그것은 /bin/sh확실히 "세그먼트 결함"을 출력하고 crsh있습니다.

프로그램을 실행 crsh하기 위해 execve()시스템 호출 을 사용하도록 다시 쓰면 "세그먼트 결함"문자열이 표시되지 않습니다. 에 의해 호출 된 쉘에서 온다 system().


5
나는 이것을 Dietrich Epp와 논의했습니다. 나는 함께 해킹 사용 crsh의 버전을 execvp, 그것이 않고 쉘이 여전히 충돌하지 않는 동안 (의미 SIGSEGV가 쉘에 전송되지 않습니다) 것을 찾기 위해 테스트를 다시 한 없습니다 "분할 오류"를 인쇄 할 수 있습니다. 아무것도 인쇄되지 않습니다. 이것은 쉘이 자식 프로세스가 종료되는시기를 감지하고 "세그먼트 결함"(또는 그 변형)을 인쇄하는 역할을하는 것으로 나타납니다.
Braden Best

2
@BradenBest-나는 똑같은 일을했다. 내 코드는 코드보다 더 빠르다. 나는 아무런 메시지도 얻지 못했고, 심지어 더 뾰족한 껍질은 아무것도 인쇄하지 않습니다. waitpid()각 포크 / 실행에 사용 했으며, 상태가 0 인 프로세스와 세그먼트 화 결함이있는 프로세스에 대해 다른 값을 리턴합니다.
Bruce Ediger

21

"CPU의 MMU가 신호를 보낸다"와 "커널이 문제를 일으키는 프로그램으로 보내서 종료시킨다"는 것 외에는 이것에 관한 정보를 찾을 수없는 것 같습니다.

이것은 약간의 요약입니다. 유닉스 신호 메커니즘은 프로세스를 시작하는 CPU 특정 이벤트와 완전히 다릅니다.

일반적으로 잘못된 주소에 액세스하거나 읽기 전용 영역에 쓰거나 실행 불가능한 섹션을 실행하려고 시도하는 경우 CPU는 일부 CPU 관련 이벤트를 생성합니다 (기존의 비 VM 아키텍처에서는 각 "세그먼트"(전통적으로 읽기 전용 실행 파일 "텍스트", 쓰기 가능 및 가변 길이 "데이터"및 전통적으로 메모리의 반대쪽 끝에있는 스택)에 고정 된 범위의 주소가 있기 때문에 세그먼테이션 위반이라고합니다. 최신 아키텍처에서는 페이지 매핑 (매핑되지 않은 메모리의 경우) 또는 액세스 위반 (읽기, 쓰기 및 실행 권한 문제의 경우) 일 가능성이 높으며 나머지 답변을 위해 이에 중점을 둘 것입니다).

이제이 시점에서 커널은 몇 가지 작업을 수행 할 수 있습니다. 유효하지만로드되지 않은 메모리 (예 : 스왑 아웃 또는 mmapped 파일 등)에 대해 페이지 결함이 생성되며,이 경우 커널은 메모리를 맵핑 한 후 사용자 프로그램을 오류. 그렇지 않으면 신호를 보냅니다. 신호 처리기를 설치하는 프로세스가 다르고 프로그램이 인터럽트 처리기 설치를 시뮬레이트 할 것으로 예상되는 경우와 비교하여 신호 처리기를 설치하는 프로세스가 다르고 대부분 아키텍처에 독립적이기 때문에 이것은 정확하게 "원래 이벤트를 문제의 프로그램으로 전달"하지 않습니다.

사용자 프로그램에 신호 처리기가 설치되어 있으면 스택 프레임을 만들고 사용자 프로그램의 실행 위치를 신호 처리기로 설정하는 것입니다. 모든 신호에 대해 동일한 작업이 수행되지만, 세그먼테이션 위반의 경우에는 일반적으로 신호 처리기가 반환하면 오류를 일으킨 명령이 다시 시작되도록 정렬됩니다. 사용자 프로그램이 오류를 수정했습니다. 예를 들어 메모리를 문제가있는 주소에 매핑하여 가능합니다. 아키텍처에 따라 다릅니다. 신호 처리기는 프로그램의 다른 위치로 이동하여 (일반적으로 longjmp 를 통해 또는 예외를 발생시켜) 잘못된 메모리 액세스를 유발 한 작업을 중단 할 수 있습니다.

사용자 프로그램에 신호 처리기가 설치되어 있지 않으면 종료됩니다. 일부 아키텍처에서는 신호가 무시되면 명령이 반복해서 다시 시작되어 무한 루프가 발생할 수 있습니다.


+1, 수락 된 항목에 추가하는 내용 만 응답합니다. "세분화"기록에 대한 훌륭한 설명. 재미있는 사실 : x86에는 실제로 32 비트 보호 모드 (페이징 (가상 메모리)를 사용하거나 사용하지 않음)에서 세그먼트 제한 이 여전히 있으므로 메모리에 액세스하는 명령어는 #PF(fault-code)페이지 오류를 생성 하거나 #GP(0)( "메모리 피연산자 유효 주소가 CS 외부에있는 경우, DS, ES, FS 또는 GS 세그먼트 한도. "). 64 비트 모드는 OS가 페이징을 대신 사용하고 사용자 공간을위한 플랫 메모리 모델을 사용했기 때문에 세그먼트 제한 검사를 중단합니다.
Peter Cordes

실제로 x86의 대부분의 OS는 세그먼트 페이지 매김을 사용합니다. 평평한 페이지 주소 공간 안에 큰 세그먼트가 있습니다. 이것은 커널 메모리를 각 주소 공간에 보호하고 매핑하는 방법입니다. 링 (보호 수준)은 페이지가 아닌 세그먼트에 연결됩니다.
Lorenzo Dematté

또한 NT에서는 (그러나 대부분의 유닉스에서 동일한 지 알고 싶습니다!) "세그먼트 폴트"는 매우 자주 발생할 수 있습니다. 사용자 공간의 시작 부분에 64k 보호 세그먼트가 있으므로 NULL 포인터를 참조하면 a가 발생합니다. (적절한?) 세분화 오류
Lorenzo Dematté

1
@ LorenzoDematté 예, 거의 모든 현대 유닉스는 NULL 역 참조를 포착하기 위해 주소 공간의 시작 부분에 영구적으로 매핑되지 않은 주소 덩어리를 남겨 둡니다. 64 비트 시스템에서 실제로는 4 기가 바이트 일 수 있으므로 32 비트에 대한 포인터의 우연한 절단이 즉시 포착 될 수 있습니다. 그러나 엄격한 x86 의미의 세분화 는 거의 사용되지 않습니다. 사용자 공간을위한 하나의 플랫 세그먼트와 커널을위한 하나의 플랫 세그먼트가 있으며, FS와 GS를 사용하는 것과 같은 특별한 트릭을위한 몇 가지가있을 수 있습니다.
zwol

1
@ LorenzoDematté NT는 신호보다는 예외를 사용합니다. 이 경우 STATUS_ACCESS_VIOLATION입니다.
Random832

18

세그먼테이션 결함은 허용되지 않는 메모리 주소에 대한 액세스입니다 (프로세스의 일부가 아니거나 읽기 전용 데이터를 쓰거나 실행 불가능한 데이터를 실행하려는 경우). MMU (현재 CPU의 일부인 메모리 관리 장치)에 의해 인터럽트가 발생합니다. 인터럽트는 커널에 의해 처리되며, 커널 은 문제를 일으키는 프로세스에 SIGSEGFAULT신호 ( signal(2)예 : 참조) 를 보냅니다 . 이 신호의 기본 핸들러는 코어를 덤프하고 (참조 core(5)) 프로세스를 종료합니다.

껍질에는 절대 손이 없습니다.


3
따라서 데스크탑의 glibc 와 같은 C 라이브러리 는 문자열을 정의합니까?
drewbenn

7
SIGSEGV 처리 / 무시할 있다는 점도 주목할 가치가 있습니다 . 따라서 종료되지 않는 프로그램을 작성할 수 있습니다. Java Virtual Machine은 여기에 언급 된 바와 같이 다른 목적으로 SIGSEGV를 내부적으로 사용하는 대표적인 예입니다. stackoverflow.com/questions/3731784/…
Karol Nowak

2
마찬가지로 Windows에서 .NET은 대부분의 경우 널 포인터 검사를 추가하지 않고 액세스 위반 (segfault와 동일) 만 포착합니다.
immibis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.