Happy to visit my research note ^^

Segmentation fault 본문

카테고리 없음

Segmentation fault

Liam Lim 2023. 12. 11. 17:44
728x90

 

 


 

 

segmentation fault는 프로그램이 메모리에 access하려고 할 때, 해당 메모리에 대한 올바르지 않은 access를 시도할 때 발생한다. -> 프로그램의 비정상적으로 종료 / 안정성 저하

 

즉, 잘못된 메모리 참조, 한 program이 자신이 OS로부터 할당받지 못한 memory 영역에 침범할 때 이것을 OS-level에서 막아준다. ( debugging하기 힘든 메모리 버그를 알려주는 역할 )

 

segmentation fault의 원인

1. null 값을 가리키는 포인터에 접근했을 때

2. 할당 받은 메모리 공간을 넘어서 쓸 경우

3. 예를들어 free처리 된 memory 영역을 가리킬 경우

4. read-only memory 영역에 쓰려고 할때

 

 

segmentation fault는 잘못된 메모리 참조 때문에 발생한다.

segmentation fault에서 debug를 실행할 때, error는 건드리지 말아야 할 메모리를 건드렸을 때가 아니라, 할당받은 메모리를 해제할 때 에러가 발생한다는 점이다.

int *ptr = new int[5];
ptr[5] = 6;
delete ptr;

 

2번 코드에서는 error가 발생하지 않는다.

3번에서 memory를 해제할 때 error가 발생한다.

gcc나 g++의 경우는 compile할 때 option을 지정해주지 않으면 release mode로 컴파일이 되기 때문에 잘못된 메모리를 건드릴 때 에러가 발생한다.

 

  할당받은 메모리 이외에 공간을 건드릴 수 있다는 것은 C/C++이 포인터를 사용할 수 있기 때문에 발생하게 되는데, 위의 경우처럼 명시적으로 포인터를 사용했을 때 발생하는 에러야 쉽게 잡히는데, 간혹, 예를들어 STL을 사용할 때처럼 내부적으로 pointer로 구현되어 있는 기능을 사용하다가 발생할 수도 있다.

 

std::vector<int> a;
a.push_back(1);
int sum = std:asccumulate(a.begin(), a.begin() + 5.0);	// 여기서 에러 발생

 

  위 코드같이, a의 begin 위치에서 5 번째 요소까지의 위치값(이 값이 포인터이다.)까지 값을 더하고자할 경우, 아직 5번째 요소는 할당되지 않았기 때문에 저 경우 에러가 발생한다. pointer를 사용하는 것처럼 보이는 곳이 없을 수도 있다.

 

  이외에도 잘못된 메모리를 건드리는 경우는 수도 없이 많다

  중요한 것은 segmentation fault가 일어났을 때는 에러가 난 곳과 memory가 할당된 곳 사이에 반드시 건드리지 말아야할 곳을 건드리는 부분이 존재한다는 것이다.

  release로 실행시킬 경우, segmentation falut가 난 곳에서 메모리를 건드릴 경우가 많고, debug로 실행할 경우는 그렇게 건드릴 때는 에러가 안 나고 그 메모리를 해제할 때 에러가 날 수 있다.

 

참고로 이런 경우도 주의

int *ptr = new int[size];
int pos = ...;
...
ptr[pos] = some_value;	// 이 때, pos는 반드시 [0, size-1]에 속해야 한다.
delete p;	// 여기서 error

 

pos가 음수의 값이나, size 이상의 값을 갖는 경우 -> memory 영역을 넘은 다른 부분을 가리키므로 segmentation fault 발생

 


 

 

지금부터는 segmentation fault를 해결 하는 방법

 

대표적인 Segmentation Fault (Segfault) 발생 조건

1) read-only memory 영역에 데이터를 쓰려고 할 때

2) OS memory 영역 또는 보호된 메모리 데이터를 쓰려고 할 때

3) 잘못된 메모리 영역을 접근하려고 할 때

    ex) NULL, -1 , etc...

 

 

Linux system 상에서 segmentation fault (Segfault)가 발생하면 error message로는

 

 

이렇게 뜨거나 좀더 자세하게 보고싶다면 dmesg 명령어를 이용해서 볼수있다.

 

 

해당 error를 분석해보면 

trace_replay[1192] - 프로그램 이름

segfault - 프로그램이 죽은 원인

4000002d1 - 죽었을 때 참조한 주소

00007f70afeb2aab - 죽었을 때 실행된 명령어 주소

00007ffc5d84e210 - 죽었을 때 스택 주소

error 4 - error code

[7f70afeaf000+11000] - offset 정보

 

 

Core file이 없을 시 debugging을 위한 정보를 알 수 있는 방법

 

  먼저, core file은 linux와 unix-based OS에서 발생한 process의 비정상 종료나 crash시에 생성되는 debug file이다.

이 file은 process의 memory dump(memory 내용)를 저장하고, process가 왜 비정상적으로 종료되었는지 분석하고 디버깅하는 데 도움이 된다. ( core file은 주로 program의 버그나 예외 상황을 디버그하고 수정하는 데 사용됨 )

 

1) -g 옵션을 이용한 compile 방법

gcc -g -o segfault_test_gdb segfault_test.c

 

장점으로는 -gdb로 debugging에 좀 더 유용한 정보를 얻을 수 있고, 단점으로는 컴파일 후 debug를 위한 symbol 정보가 추가되었기 때문에 실행 binary 사이즈가 증가한다.

 

2) nm program을 이용한 symbol 확인 방법 (nm은 instance file 이나 exec file의 symbol table을 보여주는 도구이다.)

 

3) ldd

" ldd " (List Dynamic Dependencies) 는 linux/unix based system에서 사용되는 cli tool로, exec file이나 shared library가 어떤 동적 의존성을 갖고 있는지를 나열해주는 역할을 한다. 이를 통해 exec file이 실행되기 위해 필요한 공유 라이브러리들을 확인할 수 있다.

 

4) gdb에서 직접 실행시키기

gdb benchmark.out

(gdb) run / r

 

 

debugging을 위해 core file 생성하는 방법

 

일반적으로 program이 죽으면 core 파일은 생성하지 않는다. 그래서 이를 위해서 특별한 처리를 해야함

1) core file 이름 설정, 2) core file 생성 용량 설정

 

    (1) 임시 설정

      - vi /proc/sys/kernel/core_pattern 수정

        core.%e.%p

    (2) 영구 설정

      - /etc/sysctl.conf 최 하단에 추가

        kernel.core_pattern = core.%e.%p

      - 설정 바로 적용

        sysctl -p

core file 형식 정리

 

2) core file 생성 용량 설정 방법

  - 다음 2가지 중 하나의 처리를 하여야만 필요 가능하다.

   

#include <sys/time.h>
#include <sys/resource.h>

static int core(){
    struct rlimit core_limits;
    
    core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
    setrlimit(RLIMIT_CORE, &core_limits);
    
    return 0;
}

 

 

 

 

References

[1] segmentation fault의 원인 : https://adnoctum.tistory.com/387

[2] [Segfault] 기초 편 : Linux의 Segmentation Fault(Segfault) 분석 방법 : https://doitnow-man.tistory.com/98

 

728x90
Comments