프로그래밍/리눅스 프로그래밍

[Segfault] 기초 편 : Linux의 Segmentation Fault(Segfault) 분석 방법

jinkwon.kim 2018. 8. 26. 03:51
728x90
반응형

[Segfault] 기초 편 : Linux의 Segmentation Fault(Segfault) 분석 방법

 

 

1. Segmentation Fault(이하:Segfault) 정의 

  - 프로그램이 동작 중 잘못된 주소를 참조할 때 발생하는 오류이다.

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

  1) 읽기 전용 메모리 영역에 데이터를 쓰려고 할 때

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

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

     Ex) NULL, -1, 등등

 

3. Segfault가 발생시 발생하는 에러 메시지

  - 화면상 내용(알 수 있는 정보가 없다)

  - Segmentation fault라고 뜬다.

  - demsg 상내용(알 수 있는 정보가 좀 더 있다).

  - 상세 분석 방법([Segfault] Core가 없을 때 dmesg로 죽은 원일 분석하기)

   [Segfault] Core가 없을 때 dmesg로 죽은 원일 분석하기

 

 

 

4. Core 파일이 없을 시 debugging을 위한 정보를 알 수 있는 방법.

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

    Ex) gcc -g -o segfault_test_gdb segfault_test.c

    (1) 장점

      - gdb로 debugging에 좀 더 유용한 정보를 얻을 수 있다. 

    (2) 단점 

      - 컴파일 후 debug를 위한 symbol 정보가 추가되었기 때문에 실행 binary 사이즈가 증가한다.

 

  2) nm 프로그램을 이용한 symbol 확인 방법 

    - symbol 정보 확인 방법

    - 이 정보는 어느 symbol에서 segmentation fault가 발생했는지 알 수 이게 해준다.

 

  3) ldd를 활용한 죽은 위치 정보 확인

    - ldd는 현재 프로그램과 연관된 shared library의 시작 주소를 보여준다.

    - 이를 통해서 segmentation fault가 내 프로그램에서 발생했는지 shared library에서 발생했는지 확인이 가능하다.

  4) compile의 -g 옵션을 이용한 debugging 활용 방법.

    - 이 방법은 –g 옵션을 사용하여 compile 하였을 때만 유용하다. –g 옵션을 않으면 아무 정보고 볼 수 가없다.

    - 일반적으로 프로그램을 배포할 때는 symbol정보를 제거하기 때문에 사용하기 쉽지 않은 방법이다.

      주로 개발 테스트에서 사용하는 방법이다.

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

      #gdb segfault_test

(gdb) r or run

 

 

5. debugging을 위해 core파일 생성하는 방법

  - 일반적으로 프로그램이 죽으면 Core파일은 생성하지 않는다. 그래서 이를 위해 특별한 처리를 해주어야 한다. 

  - 1) core 파일 이름 설정, 2) core 파일 생성 용량 설정

  1) core 파일 생성 시 표시할 이름 형식 설정

    (1) 임시 설정 

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

        core.%e.%p

    (2) 영구 설정 

      - /etc/sysctl.conf 최 하단 다음 추가

        kernel.core_pattern = core.%e.%p

      - 설정 바로 적용

        #sysctl –p

       *core파일 형식 정리 

 형식 설명 
 %p  pid
 %<NUL>  '%' is dropped
 %%  output one '%'
 %u  uid
 %g  gid
 %s  signal number
 %t  UNIX time of dump
 %h  hostname
 %e  executable filename
 %<OTHER>  both are dropped

 

  2) core파일 생성 용량 설정 방법  

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

    A. 코드 상으로 core 파일을 생성하게 해주는 코드 추가

#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;

  

    B. system상에서 core파일 사이즈 설정

       - 현재 코어 파일 사이즈 보기

         #ulimit –c

 - 현재 코어 파일 사이즈 설정

   #ulimit –c 1024

 

6. gdb로 core파일 분석 하기

    #gdb {program name} {core name}

    - compile시 -g 옵션으로 symbol 정보를 넣었을 때 보이는 화면

    - 어느 라인에서 죽었는지 확인이 가능하다.

 

    - compile시 -g 옵션으로 symbol 정보를 넣었을 때 보이는 화면

      symbol이 없기 때문에 볼 수 있는 정보가 없다.

7. core파일이 정상적으로 안보이는 경우 

이 경우 gdb를 실행하는 libc와 core 파일이 생성된 환경의 libc가 다를 경우에 발생합니다. 

이 경우 core파일이 발생한 system의 libc를 구한 후 해당 libc를 gdb가 link 할 수 있게 설정을 해주시면 됩니다.

libc란? 

[linux] libc 와 glibc 와 libstdc++ 와 gcc의 관계 정리

[linux] libc와 glibc의 차이

 

필수 필요 파일

  • core 파일이 발생한 system의 libc파일이 꼭 필요함 없으면 frame깨짐.

분석 환경 세팅 

  • lbc 링크 걸기
    • core파일을 생성한 binary가 link하고 있는 libc 파일명과 동일하게 아래 처럼 링크걸기
  • gdb 실행
    • gdb ./test ./bin/core.25862
  • shared library loading 상태 확인
    • (gdb) info sharedlibrary
  • gdb so 파일 검색 환경 세팅
    • (gdb) set solib-search-path /usr/local/test/lib

참초 사이트

https://stackoverflow.com/questions/20380204/how-to-load-multiple-symbol-files-in-gdb/55744855#55744855

 

How to load multiple symbol files in gdb

How to load multiple symbol files in gdb. I have a executable foo.out and loading a module bar.so. I have created two symbol files foo.symbol and bar.symbol. How to load both the files into gdb. ...

stackoverflow.com

* 연관 포스트

  - [Segfault] Core가 없을 때 dmesg로 죽은 원일 분석하기

728x90
반응형