세그맨테이션오류 라는게 무슨뜻인가요

jjjjrr의 이미지

안녕하세요
계속질문입니다
리눅스서버를만들어 실행시키고
윈도우즈에서 클라이언트를 만들어 접속하니
세그맨테이션오류 라고나오면서
프로그램이 종료되는것같읍니다
세그맨테이션오류 라는게 무슨뜻인가요
조언부탁드립니다

aero의 이미지

출처: http://soomsori.net/moa/moin.cgi/SegmentationFault

세그멘테이션 폴트는 수행 중인 프로그램이 메모리 상에 이상한 주소를 접근하려 할 때 발생한다. 여러분이 만든 프로그램이라면 세그멘테이션 폴트는 아마도 포인터가 뭔가 이상한 곳을 가리키고 있다는 말일 것이다. 그러나 표준 유닉스유틸리티인 경우 결국 같은 내용이겠지만 아마 프로그램에게 다룰 수 없는 이상한 입력을 준다든지 했을 것이다.

프로그램을 중단시킬 수 있는 대부분의 버그들은 ‘SegmentationFault’라는 메시지를 남긴다. 이 메시지의 ‘fault’라는 말은 결함, 실수 등의 의미임을 쉽게 생각할 수 있다. 하지만 ‘segmentation’은 무슨 의미일까?

세그먼테이션은 운영체제에서 메모리 관리(Memory Management)의 한 종류이다. 세그먼테이션을 정의한다면 완전히 머신(machine) 독립적인 주소 공간을 할당해주는 직접적인 방법이라고 할 수 있다.

예를 들어, 컴파일러가 소스를 컴파일 할 때 다음과 같은 테이블을 만들 수 있다.

텍스트 소스를 저장하는 공간(테이블)
변수의 특성, 이름 등을 저장하는 심벌 공간
정수, 부동소수 등으로 지정된 상수를 저장하는 공간
프로그램을 문법적으로 분석한 Parse tree
컴파일러가 사용한 프로시저 콜 스택
이러한 여러 가지의 테이블을 세그먼테이션 방법에서는 각각 세그먼트라는 독립된 주소 공간을 할당하게 된다. 앞의 그림은 세그먼트를 나타낸 것이다. 반면에 가상 주소(Virtual Memory-pa ging의 대표적인 방법)라는 방법에서는 일정한 크기의 주소 공간을 여러 영역으로 나눠(세그먼테이션과는 다르게 일차원적이다) 앞의 여러 가지 테이블을 저장하게 된다.

세그먼테이션을 사용할 때의 장점에는 여러 가지가 있지만 우선 각 프로시저가 주소 번지 0에서 시작되는 분리된 세그먼트를 갖기 때문에 독립된 프로시저의 연결이 단순해진다. 또한 여러 개의 프로세스가 프로시저나 데이터를 쉽게 공유할 수 있다. 이러 장점은 세그먼테이션이 가상 메모리와는 달리 그 크기가 유동적이라는 데서 기인한다.

--------------------------------------------------------------------------------

Bus error

이것은 성격상 세그먼테이션 폴트와 유사하다. 그러나 미묘한 차이가 있는데 버스에러란 커널이 스스로 문제점을 발견하지 못했다는 점에서다. 어떤 문제가 있음을 메모리 시스템(즉 하드웨어)이 발견한다. 많은 시스템에서느 이 메시지는 입출력 연산을 잘못 시도했음을 말한다. (있지도 않은 장치를 접근하려 했거나 뭔가 자연적이지 못했을때 등등)

mach의 이미지

메모리 관리
1) 세그멘테이션 : 메모리를 가변길이로 나누어 관리
2) 페이징 : 메모리를 고정크기로 나누어 관리
이렇게 2가지로 크게 나누어 볼수 있습니다.
둘다에 대한 상세한 설명은 피하기로 하고 주관심사인 segmentation fault에 대해서만 언급하겠습니다.

운영체제가 메모리를 관리할때 여러가지 작업을 수행해야 하며 특히, 메모리 보호를 하게 되어 있습니다.
메모리 보호란, 각각의 프로세스가 자신이 소유한 메모리에 대해서만 액세스하도록 하는것입니다. 즉, 다른 프로세스(심지어는 운영체제영역)의 영역에는 침범할 수 없다는 것이지요. 마치 파일시스템에서 자기 소유가 아닌 디렉터리나 파일에는 쓰기, 읽기등이 안되거나 하는 것같은 메커니즘이지요.
A라는 프로그램이 메모리 영역 100번지에서 200번지 까지를 사용하도록 운영체제에 의해 허가되었다고 가정합시다(모든 메모리자원은 운영체제에게 할당받아 사용해야함) 그런데, A라는 프로그램내부에서 10번지나, 210번지등 자신의 메모리 영역이 아닌곳을 액세스하고자 하면, 운영체제는 해당 프로그램 즉 A를 죽여버립니다.(살벌하지요?) 왜 그러냐면 210번지를 B라는 다른 프로그램이 사용하고 있었다면, A는 B의 영역을 침범한것이 되지요? 이것을 운영체제 수준에서 막아주게 되어 있습니다. 어떻게요? 죽여버리지요.
즉, 자신의 영역이 아닌 부분을 액세스(read또는 write)하려고 했기 때문입니다.
침범하도록 허용한다면? 문제가 있겠지요? A때문에 B도 죽을 수 있기 때문입니다. 만일 B 가 운영체제라면 시스템이 다운되겠지요? 구한말의 도스처럼.

이렇게 어떤 프로그램이 자신이 운영체제로 부터 배정받지 못한 영역(메모리)에 대해 침범하는 것을 운영체제 수준에서 막아주는 것이 세그멘테이션 폴트에러입니다.
그럼 왜 이를 메모리 에러 등의 메시지로 안했냐구요? 이는 일종의 전통이라고 볼수 있습니다. 관습이랄까요? 최초 유닉스 설계자의 문구가 지금도 사용되는 것이라고 볼수 있습니다. 이를테면 core dump도 있는데, core메모리 이거 지금은 쓰는데가 있을라나? 다 RAM계열을 사용하지! 요즘 말로 이것도 바꿔본다면, 메모리덤프, 또는 RAM덤프등으로 써야 하겠지요?

또 한가지, 요즘의 마이크로프로세서(하드웨어, CPU라고 흔히불리는...)들은 대부분 기본적으로 메모리 관리 메카니즘을 내장하고 있습니다. 인텔계열의 경우 386프로세서 이상에서 부터 지원되었지만요. 이를 운영체제 만드는 사람들이 이용하면 보다 쉽게 메모리 보호등 메모리 관리 루틴을 만들 수 있지요. 하드웨어가 메모리 보호를 지원하지 않아도 구현이야 할 수 있습니다만, 프로그램 수행이 좀 (아니 아주많이) 느려지겠지요?

끝으로, 프로그래머가 세그멘테이션 폴트를 발생시키려고 하지 않았는데, 발생하는 주 이유는 무엇일까?에 대해 말씀드리겠습니다.
여러 이유가 있겠지만, 첫번째는 초기화 입니다.
char *pointer; //알수없는 번지값이 들어가 있음, 무슨 값이 들어가 있는지는 며느리도 모름

pointer = (char *)0;
이런식으로 초기화 하지 않으면, pointer라는 변수에 이상한 값(즉, 번지)이 들어가게 되고 해당 번지는 알수 없는 번지가 되지요. 그리고는 그번지를 액세스하는 순간, 에러가 발생하겠지요?

또다른 이유는 메모리 할당 성공 실패 검사입니다.
메모리할당은 유닉스의 경우 실패할 경우가 거의 없겠지만, 그래도 메모리 할당후 검사는 필수적입니다.
pointer = (char *)malloc(10);
if ( pointer == (char *)0)
{
// 메모리 할당에러
}
이런 루틴을 추가하는 것은 기본입니다.

또한가지는 할당한 메모리를 초과하는 영역을 액세스하는 경우입니다.
10바이트 할당한 포인터에 다음과 같이 하는 경우이지요.
*(pointer+100) = 'a';
당근으로 죽겠지요.

또다른 한가지는 배열에서도 발생할 수 있습니다.
int a[10];

a[100] = 8;
물론 100이라는 값을 인위적으로 쓸리는 없지만, 루프를 사용하고 100이라는 index(subscript)를 변수에 넣어 사용할때는 흔히 실수가 나오기도 합니다.
a[cnt++] = 8;
모 이런식으로 하다보면 흔히 실수하지요.

===========
폴트에 대해 얘기가 빠졌네요.
Fault란 무엇일까?
사전적의미로 봐서는 안되고요. 용어로 보시면됩니다.
Exception에는 Trap, Fault, Abort가 있습니다.
1)trap : 현재 명령라인에서 다른 수행루틴을 호출
2)fault : 현재 명령라인이 실패하면, 폴트처리루틴(fault handler)을 수행한후, 이전라인으로 복귀
3)abort : 현재 명령라인이 실패하면 중지

세그멘테이션 폴트 즉, 다른 프로세스 영역에 쓰기를 시도했다면, 쓰고 나서 죽어서는 안되겠지요? 쓰기 이전상태로 메모리는 보전되어야 하고, 그 후 죽거나 어떤 처리를 수행해야 겠지요? 그래서 폴트라는 것을 사용합니다.
참고로, 폴트는 가상메모리(Virtual Memory Management)에서도 사용되는 메커니즘입니다.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

ㅎㅇㅎ의 이미지

이분한테 내 모든 프로그래밍 지식 배우고싶다 그럼 꿀잼일텐데,,,

호호이의 이미지

학생인데 이 글 읽고 많은 걸 배웠습니다. 감사히 잘 배워갑니다!

kimyh의 이미지

답변은 아닙니다.
저도 Xconfigurator를 실행하면 윈도우 설정 초기화면이 나오고
ok 버튼을 클릭하면 다음화면이 나오는게 아니라 Segmentation fault 라고 한줄 딱 나오고 텍스트 모드로 되돌아가 버립니다.
도대체 뭐가 잘못된것일까요.

살며 그리고 사랑하며...
정보는 공유할때 그 가치가 있는것.....
나의 조그만 지식공유는 남에게 엄청난 기쁨을 안겨 준다.

mach의 이미지

kimyh wrote:
답변은 아닙니다.
저도 Xconfigurator를 실행하면 윈도우 설정 초기화면이 나오고
ok 버튼을 클릭하면 다음화면이 나오는게 아니라 Segmentation fault 라고 한줄 딱 나오고 텍스트 모드로 되돌아가 버립니다.
도대체 뭐가 잘못된것일까요.

여기 게시판에는 성격상 안맞는 주제같지만, 프로그램이 소위 깨진거 같습니다.
실행 파일에 문제가 있는거처럼 보이네요. 적어도 그래픽모드 전단계까지는
가야 정상인듯한데요. "설치 및 활용 QnA"게시판에 다시 물어보세요.

*컥 ~ 그런데, 제가 이 주제에 대해 이런 글을 쓴적도 있었네요. :shock:

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

지리즈의 이미지

kimyh wrote:
답변은 아닙니다.
저도 Xconfigurator를 실행하면 윈도우 설정 초기화면이 나오고
ok 버튼을 클릭하면 다음화면이 나오는게 아니라 Segmentation fault 라고 한줄 딱 나오고 텍스트 모드로 되돌아가 버립니다.
도대체 뭐가 잘못된것일까요.

Xconfigurator가 모르는 장치(모니터 포함)가 있을 경우 세그폴트나는 경우가
있습니다. Xconfigurator를 업그레이드 하면 되는 경우가 있거나...
XF86Conifg가 뭔가하는 좀 귀찮은 놈으로 설정하거나...
편집기로 직접 일일이 sh script나 다른 것들을 고쳐줘야 하는 경우도 있지요.

There is no spoon. Neo from the Matrix 1999.

espereto의 이미지

jjjjrr wrote:
안녕하세요
계속질문입니다
리눅스서버를만들어 실행시키고
윈도우즈에서 클라이언트를 만들어 접속하니
세그맨테이션오류 라고나오면서
프로그램이 종료되는것같읍니다
세그맨테이션오류 라는게 무슨뜻인가요
조언부탁드립니다

윈도에서의 Access Violation Error와 같은 에러입니다.

할당되지 않은 메모리 영역을 접근하거나 할당된 양을 초과해서 쓰는 경우, 그리고 이런 경우 운 좋게 에러가 안 났지만 문제가 된 메모리 영역을 free 나 delete를 하는 경우 등에 발생합니다.

클라이언트가 주고 받는 데이터와 서버가 주고 받는 데이터를 로그로 남겨서 분석해보면 무엇이 문제가 된 건지 찾으실 수 있을 듯 합니다.

만일 데이터 길이를 전송하고 그 값만큼 메모리를 할당한 후에 데이터를 받아서 저장하는 작업을 하는 부분이 있다면, 데이터 길이가 잘못 전송되었을 가능성이 있습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.