본문 바로가기

C++

Segmentation fault 사례3

[1. 개요]

힙 메모리 관련 하여, SIGSEGV 시그널 발생 사례 중...

free(): invalid pointer 오류 발생하는 경우가 있음.

 

구체적인 상황은

  1. new[] 를 이용하여, 동적 길이의 배열을 생성
  2. 해당 배열을 사용
  3. delete[] 를 이용하여 리소스 해제 => 이 때 오류가 발생하는데...

문제는 gdb 를 통해서 delete[] 한 메모리 주소가 오염되었는지 확인해보았는데,

  • 최초 할당 시, 받은 주소였고,
  • 심지어, 해당 메모리에 접근하여 배열 내 값도 정상적으로 확인 할 수 있었음.

즉, 아래와 같은 상황은 아니라는 것이다.

  • double free 를 시도한다 던가...
  • new[] 로 할당한 메모리를 단순히 delete 로 해제한다 던가...

[2. 원인]

위 상황에 대한 원인은 다른 힙 메모리에 발생한 overflow 에 있었다.

#include <iostream>

int main()
{
        int * arr0 = new int[5];
        int * arr1 = new int[6];
        int * arr2 = new int[7];

        arr0[0] = 123;
        arr1[0] = 456;
        arr2[0] = 789;

        std::cout << "alloc!!!" << std::endl;
        std::cout << "arr0: " << arr0 << std::endl;
        std::cout << "arr1: " << arr1 << std::endl;
        std::cout << "arr2: " << arr2 << std::endl;

        arr0[6] = 99;

        std::cout << "dealloc!!!" << std::endl;

        delete []arr1;

        std::cout << "terminate..." << std::endl;

        return 0;
}

 

실행 결과

 

먼저, glibc 에서 힙 구현은 각 할당 블록 앞뒤에 size, flags, next 등의 정보를 유지한다.

  • 이 정보는 개발자가 직접 확인 할 수 는 없어 보이는데..

즉, 해당 메모리 블록의 해제하는  free() 나 delete 시 이러한 메타데이터를 확인해야 하는데,

이 메타데이터가 오염되어있기 때문에 오류가 발생하는 것이다.


[3. 해결]

이러한 heap 메모리에 대한 buffer overflow 를 찾기 위해서, gdb 를 활용해도 되고,

컴파일 시, -fsanitize=address 옵션을 사용해서 조금 더 쉽게 찾을 수 있다.

  • -g 옵션도 추가해서, 심볼 정보도 포함해야 한다.

실제 실행하면, heap-buffer-overflow 가 발생한 구간을 소스코드와 라인 수를 포함하여 알려준다.


[4. cmake 적용]

현재는 리눅스에서만 적용 가능하고, (윈도우도 가능은 하나 visual studio 2019 이상 부터 가능하긴 함.  #clang? )

set(SANITIZE_FLAGS "-fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}")

[5. 참고 사항]

void* 에 대한 delete 연산은 위험한 동작이다.

아래 오류(or 문구)가 발생하는 경우 void* 에 대한 delete 연산이 있는지 확인해보도록 한다.

  • AddressSanitizer: alloc-dealloc-mismatch (operator new [] vs operator delete)

 

 

'C++' 카테고리의 다른 글

구조체 대입 연산  (0) 2025.04.15
Segmentation fault 사례4  (0) 2025.04.14
Segmentation fault 사례2  (0) 2025.04.01
STL priority_queue  (0) 2021.10.28
가변인자 템플릿  (0) 2021.10.27