정체불명의 모모

강의 내용 정리(Section5 / 버그 유형) 본문

프로그래밍(c++)/인프런 강의 정리(C++)

강의 내용 정리(Section5 / 버그 유형)

정체불명의 모모 2024. 5. 29. 20:36

강의 중 배운 내용과 추가적으로 배워야 할 부분들을 정리한 메모장 입니다.

강의 : (인프런) 게임 프로그래머 입문 올인원 


 

버그 유형 / 메모리 릭 (memory leaks)

 

  • 메모리 릭(memory leaks / 메모리 누수) 
    : 메모리 누수(memory leaks)는 C나 C++ 프로그래밍 과정에서 발견하거나 해결하기 가장 힘든 작업 중 하나 입니다.
      시간이 지나 실행될 수록 메모리 공간을 잡아먹는다면 메모리 누수가 발생한 것 입니다.

    메모리 누수는 할당했던 메모리를 제대로 해제 하지 않을 때 발생합니다.

     간단한 예제 코드 
#include <iostream>
#include <string>

using namespace std;

class Item
{
public: 
	Item() {}
	~Item() {}
};

int main()
{
	while (true)
	{
		Item* item = new Item();	// 할당
		delete item;			// 해제
	}

	return 0;
}

 

위 처럼 할당(new) 후 해제(delete)를 잘 하게 되면 아래의 스샷과 같이
메모리가 더 이상 상승하지 않는것을 확인 할 수 있습니다.

하지만 delete(해제) 하는 코드를 제거 하게 되면

미친듯이 프로세스 메모리를 잡아 먹는것을 확인 할 수 있습니다.

 

 

 누수 체크 라이브러리 : <crtdbg.h> 라이브러리

#include <crtdbg.h> 

_CrtDumpMemoryLeaks( );

 

 

위 라이브러리와 코드를 추가 시켜주면 아래와 같이 'Detected memory leaks!'란 말이 보입니다.

그리고 왜인지 프로세스 메모리도 이전과 다르게 급경사적으로 오르는것이 아닌 안정적으로 오르는걸 알 수 있습니다.

 

그리고 정확히 어떤 부분에서 문제가 발생 했는지 알고 싶으면 아래의 전처리 처리를 해주면 됩니다.

#if _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#define malloc(s) _malloc_dbg(s,_NORMAL_BLOCK,__FILE__,__LINE__)
#endif

 

해당 코드를 넣어 주면 아래의 스샷과 같이 코드 어느 부분에 문제가 발생 했는지 친절히 알려줍니다.

 

 그외에 누수 탐지 함수들

  • CrtDumpMemoryLeaks();
  • CrtSetDbgFlag( _CRTDGB_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    : 위 두 함수는 메모리 누수 결과를 디버그 결과 창에 표시해 준다.
        - 첫 번째 함수는 메모리 문제로 인해 프로그램이 종료 되는 지점에 사용 하는데, 첫 누수 결과만 출력 한다.
           여러 군데가 있다면 군데군데서 함수를 호출해야 하는 번거로움이 있다.

       - 두 번째 함수는 프로그램의 시작 부분에 한 번 사용하면 탐지 가능한 모든 누수를 결과 창에 표시한다.
         실시간으로 프로그램에 누수 결과를 알려주는 첫 번째 함수와는 달리 프로그램이 종료 되면 문제를 알려준다.
     
  • CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG);
    :  이 함수는 결과(보고서)의 출력 방식을 설정한다. 파일에도 설정할 수 있으며 assert 처럼 경고 창으로 띄울 수도 있다.

       이 함수는 따로 사용하지 않아도 기본으로 결과 창엔 출력되기 때문에 추가로 설정 하고 싶다면 다음 링크를 참고 하자.
    https://docs.microsoft.com/ko-kr/cpp/c-runtime-library/reference/crtsetreportmode?view=vs-2019
  • CRTSetBreakAlloc( )
  • crtBreakAlloc
    : 네 번째 함수이고 다섯 번째는 매크로 인데, 둘 다 동일한 기능을 한다.
      누수 발생 시 보고서에 누수 지점의 번호가 출력 되는데, 그 번호를 해당 함수의 인자로 전달하면 그 지점에서 멈춘다.

 


 

버그 유형 / 메모리 오염 

 

메모리 오염은 사용자가 부주의하여 명확한 할당 없이 주소에 접근하여 데이터를 변경하려 하거나 잘못된 주소 위치로 접근
   하려 하는 경우를 말한다. 

 

  ㅁ 메모리 오염이 발생 하는 상황

  •  Buffer Overflow 의 경우 할당된 메모리 양 보다 더 많은 데이터를 집어 넣을때 발생 한다.
  • 할당한 배열을 초과하는 위치에 접근 하는 경우(인덱스 초과)
  • 포인터 변수로 선언한 변수에 new로 메모리를 할당하지도 않았는데 포인터 주소를 가지는 멤버 변수나 함수로
    접근 하는 경우
  • free( ) or delete 로 날려버린 변수에 접근하는 경우 ---> User-After-Free
        
          

버그 유형 / Use-After-Free    

 

반납을 완료한 동적 할당 메모리를 참조하여 사용할 경우 발생 합니다.
   이미 반납된 메모리이므로, 다른 곳에서 할당 받아 사용할 가능성도 있으며, 이때 해당 메모리를 참조하여 값을 변경 할 경우
    메모리 오염(Memory corruption) 발생 합니다.

    동적할당(Dynamic memory allocated)된 heap을 free 하고
다시 재사용(Dynamic memory reuse) 할때 문제가 발생할 수 있다.

#include <iostream>
using namespace std;

class Monster
{
public:
	Monster() { cout << "Monster()" << endl; }
	~Monster() { cout << "~Monster()" << endl; }

public:
	int _hp = 100;
};

int main()
{
	Monster* m1 = new Monster;
	delete m1;

	cout << "메모리 오염 전 hp : " << m1->_hp << endl;
	m1->_hp = 200;
	cout << "메모리 오염 후 hp : " << m1->_hp << endl;

	return 0;
}

이미 해제한 메모리 주소에 다시 재접근하여

 

 Use-After-Free 방지 하는 방법

: UAF 취약점을 방지하기 위해서는 메모리 해제 이후에는 해당 메모리를 참조하지 않도록 주의해야 한다.

 

  - 포인터를 null로 초기 하여 해당 메모리를 참조 하지 않도록 하는 방법

  - 동적 메모리 할당 시에는 RALL(Resource Acquisition Is Initialization)등의 메모리 관리 기법을 이용하여 메모리를
     자동으로 해제 할 수 있도록 하는 것이 좋다.

 

◆  RALL(Resource Acquisition Is Initialization)
: RALL는 C++에서 스마트 포인터, 파일 핸들러, 뮤텍스 등과 같이 자원 할당 코드와 자원 해제코드를 객체의 
  생성자와 소멸자에 각각 구현함으로써 메모리 누수를 방지하는 메모리 관리 기법이다.
  이와 같은 방법을 통해 UAF 취약점을 방지 할 수 있다. 

 

메모리 해제 후 nullptr을 넣어주면 위와 같이 주소에 접근시 nullptr 이라고 접근 할 수 없게 한다.

 


버그 유형 / 버퍼 오버플로우

: 일반적으로 버퍼 오버플로우는 할당된 버퍼에 데이터를 쓰거나 읽는 작업이 버퍼 경계를 초과할 때 발생 합니다.

   버퍼 경계를 초과하여 접근한다는 것은 접근하면 안되는 메모리 위치를 읽거나 쓰는 작업을

   하게 된다는 것을 의미 합니다.

 

  • Stack Overflow
    : 스택 영역이 힙 영역을 침범하는 경우를 스택 오버 플로어라고 한다.

    - 일어나는 경우
    : 종료문이 없는 무한 재귀호출 시

  • Heap Overflow
    : 힙 영역이 스택 영역을 침범할 경우를 힙 오버플로어라고 한다.

    - 일어나는 경우
    : 동적 할당을 지정된 힙 크기 보다 많이 할당 할 때

 


참고 사이트 

https://hyo-ue4study.tistory.com/201

 

[CPP] 메모리 누수 찾기 - _CrtDumpMemoryLeaks()함수

위 코드는 빌드하면 아무런 문제도 없다고 나온다. 이대로 F5 디버그를 눌러봐도 문제는 없어서 정상적으로 실행된다. 하지만 해당 코드는 힙에 메모리를 할당(new)해주고 해제(delete)를 해주지 않

hyo-ue4study.tistory.com

https://woo-dev.tistory.com/84

 

[C++] CRT 라이브러리로 디버깅 시 메모리 누수 찾기

메모리 동적 할당 후 해제를 따로 하지 않아도 에러가 발생하지 않기에 누수 발생 여부를 알기 어렵다. 이때, CRT 라이브러리를 이용하면 다음과 같이 디버깅 시 누수 지점을 쉽게 찾을 수 있다. D

woo-dev.tistory.com

https://diehard98.tistory.com/entry/CC-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%A4%EB%A5%98%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC

 

C/C++ 메모리 오류에 대하여

C에서 가장 많이 발생하는 오류가 아마도 메모리 관련 오류가 아닌가 싶은데 이는 여러가지 원인이 존재한다. 여러개의 클래스가 겹쳐지고 상속되고 난리를 치다보면 이중해제를 하는 실수는

diehard98.tistory.com

https://shayete.tistory.com/entry/7-Use-After-Free

 

7. Use After Free

(uaf, uaf.c 바이너리, 코드 요청하셔서 올려드립니다.) 8번째 강의는 Use After Free입니다. 말 그대로 사용한 후 해제했을 때 취약점이 일어날 수 있습니다. 정확히는 heap space에서 alloc된 공간을 free하

shayete.tistory.com

https://keyme2003.tistory.com/entry/dreamhack-uafoverwrite

 

[dreamhack] uaf_overwrite

개념정리 ○ UAF Use After Free, 메모리를 해제하고 다시 이용할 때 생기는 취약점이다. Use After Free(UAF) 취약점은 메모리 할당 해제 이후에도 해당 메모리를 참조하여 사용하는 보안 취약점이다. 컴

keyme2003.tistory.com

 

Comments