내 세그멘테이션 오류는 어디로 사라졌나?
요약
본 글은 `entr` 명령어를 사용하여 C 프로그램을 반복 컴파일 및 실행할 때, 세그멘테이션 오류(Segmentation fault) 메시지가 사라지는 현상을 분석합니다. 이 문제는 Bash의 프로세스 최적화(`execve`)와 관련이 있으며, 부모 셸이 자식 프로세스의 종료를 감지하고 오류 메시지를 출력하는 메커니즘을 이해해야 합니다.
핵심 포인트
- 오류 메시지 출력을 위해서는 부모 셸이 남아 있어야 함.
- Bash는 명령이 하나일 경우 `execve`로 자신을 교체하여 부모 셸이 사라질 수 있음.
- 서브셸 `()` 사용이나 후속 명령어 `; true` 추가로 오류 메시지를 복원할 수 있음.
entr
로 C 프로그램을 반복 컴파일·실행하자hello
가 비정상 종료됐지만, 컴파일 출력 뒤에Segmentation fault
메시지가 나타나지 않음- 이 메시지는 충돌한 프로그램이 아니라, 자식 프로세스를 회수하며
SIGSEGV
종료를 확인한부모 셸이 출력함 bash -c
를 명시해도 남은 명령이 사실상 하나뿐이면 Bash가 새 프로세스를 만들지 않고할 수 있어 메시지를 출력할 부모 셸이 사라짐execve
로 자신을 교체- 별도 스크립트에서는 shebang으로 시작된 Bash가
./hello
를 자식으로 실행하고 기다리므로,SIGSEGV
를 확인해를 출력함Segmentation fault (core dumped)
./hello
를서브셸(./hello)
에서 실행하거나 뒤에; true
를 추가해 후속 작업을 남기면exec
최적화를 막고 오류 메시지를 확인할 수 있음
메시지가 사라진 실행 경로
다음
entr
명령으로hello.c
가 바뀔 때마다 컴파일과 실행을 반복함ls hello.c | entr -s "gcc -o hello hello.c && ./hello"
hello
가 세그멘테이션 오류로 종료됐지만Segmentation fault
메시지나 눈에 보이는 0이 아닌 종료 상태 없이아무 출력도 남지 않음 -
bash -c
로 명령을 감싸도 결과는 같았음ls hello.c | entr -s "bash -c 'gcc -o hello hello.c && ./hello'"
반면 같은 명령을
run.sh
로 옮겨 실행하면 오류가 표시됨#!/bin/bash gcc -o hello hello.c && ./hello
ls hello.c | entr -s ./run.sh ./run.sh: line 2: 104465 Segmentation fault (core dumped) ./hello
Segmentation fault
를 출력하는 주체- 충돌한 프로그램은 이미 종료된 상태이며,
부모 셸이 자식 프로세스를 회수하면서SIGSEGV
로 죽었다는 사실을 확인한 뒤 메시지를 출력함 - 따라서 메시지를 출력할 부모 셸이 남아 있지 않으면 아무것도 나타나지 않음
- Bash는
bash -c "some_command"
에서 실행할 일이 사실상 해당 명령뿐이면 새 프로세스를 포크하지 않고execve
로 자신을 교체할 수 있음 - 이 최적화는 대부분의 실행에서는 외부로 드러나지 않음
- 스크립트 방식에서는
entr
가./run.sh
를 자식으로 실행하고, shebang이 새 Bash를 시작함 - 새 Bash는
gcc
실행 후./hello
를 포크하고 기다리므로, 자식의SIGSEGV
종료를 확인해 오류 메시지를 남길 수 있음
- 충돌한 프로그램은 이미 종료된 상태이며,
부모 셸을 남기는 두 가지 방법
-
충돌하는 명령을
서브셸에서 실행하면 메시지가 다시 나타남ls hello.c | entr -s "gcc -o hello hello.c && (./hello)" hello.c: line 1: 106595 Segmentation fault (core dumped) ( ./hello ) -
괄호는
./hello
가 포크된 서브셸에서 실행되도록 강제함 - Bash가 부모 역할을 유지하므로 서브셸의
SIGSEGV
종료를 회수해 메시지를 출력할 수 있음
- 괄호는
- 충돌 명령 뒤에 실행할 작업을 남겨도
를 막을 수 있음exec
최적화ls hello.c | entr -s "bash -c 'gcc -o hello hello.c && ./hello; true'" bash: line 1: 109516 Segmentation fault (core dumped) ./hello
; true
때문에 Bash는./hello
가 끝난 뒤에도 할 일이 남아 있어 자신을 해당 프로그램으로 교체하지 않음- 별도 래퍼 스크립트 없이도 세그멘테이션 오류 메시지를 확인할 수 있음
AI 자동 생성 콘텐츠
본 콘텐츠는 RSS: GeekNews (한국어)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기