프로그래밍 언어/C++

[게임 프로그래머 입문 올인원] 동적할당과 캐스팅 : 버그 유형과 디버깅 연습/답안 (43, 44강)

순정법사 2023.10.05

A. 버그 유형

1. 버그 유형의 종류

a. Null 크러쉬 (95%)

🌟 없는 객체에 대한 데이터 변형이 일어날 경우

 

둘 다  없는 유저의 hp값 변경하는 예제, 오류남

 

둘 다 크러쉬가 나는 코드, 왼쪽 p 포인터만 봐도 0x000000... 로 나옴

 

항상 이렇게 널 체크를 해줘야 함

 

b. 정수 오버플로우(언더플로우) (0.001%)

🌟 범위를 초과해 저장하면 일어나는 경우

 

 

이렇게 범위를 초과해서 저장하게 되면 음수값이 저장됨 

마치 옛날 문명 간디처럼,, 갑자기 폭군이 된다 

 

c. 메모리 릭 (0.1%)

🌟 메모리를 만들었는데 해제하지 않아서 일어나는 경우

 

나중에 덤프로 코드를 분석하면 돼 (몇시간 뒤 서버가 다운될지 나옴) 그나마 괜찮은? 버그

 

d. 메모리 오염

1) 캐스팅

 

🌟 가장 빈번, 잘못된 객체로 캐스팅 된 경우

 

2) 버퍼 오버플로우

 

🌟  할당한 값 보다 더 큰 메모리 공간을 사용하는 경우

 

3) Use - After - Free 

 

🌟  메모리 해제 후 다시 사용하는 경우 일어남 

 

 

 


B. 디버깅 연습

1. Exercise 1

a. 문제

 

두 번째 기사의 attack 값이 제대로 출력되지 않음

 

b. 풀이

1) 내가 푼 방식

 

원인은 기사 생성시 attack 변수를 초기화하지 않아 발생

 

생성자에서 작성하는 방법과 Knight 자체 멤버 변수에서 초기화 하는 방법이 있음

 

왼족부터 생성자 초기화, 멤버변수 초기화 방법

 

잘 나옴

 

2) 선생님이 푼 방식

 

동일

 

attack의 쓰레기값이 들어있는 모습

 

 

2. Exercise 2

a. 문제

 

exercise 1의 연장선상에 있는 문제, Knights를 10개 출력할 때 crash 가 남

 

print할 때 crash가 남 = 없는 정보를 출력하는 중!

 

b. 풀이

1) 내가 푼 방식

 

프린트할 때 문제가 발생하니 없는 정보를 출력한다고 판단했다

아니나 다를까 0~9까지 생성한 Knight를 10까지 출력해 오류가 난 것이였다

 

따라서 print하는 반복문을 수정해주면 된다

 

잘 나옴

 

2) 선생님이 푼 방식

 

동일

 

호출 스택을 보는게 가장 좋음 ➡ 어디서 문제가 발생했는지를 파악하자

 

 

 

3. Exercise 3

a. 문제

 

죽었다는 로그가 뜨지 않는 버그

 

b. 풀이

1) 내가 푼 방식

 

IsDead에 문제가 있으니 살았습니다가 나오는것이니 IsDead를 확인해봤음

 

hp 값이 0이거나, 0보다 작을 때 true를 반환해야 하는 것이므로 기호를 수정해야 함

 

잘 나옴

 

2) 선생님이 푼 방식

 

 동일

 

 

4. Exercise 4

a. 문제

 

100만번 랜덤 체력 물약을 먹었는데 죽은 모습

 

b. 풀이

1) 내가 푼 방식

 

저번처럼 IsDead가 잘못 설정되어있는건 아니니까 Knight의 hp값의 overflow를 의심

 

int값을 넘어가는 값이 hp에 저장되어 죽은걸로 판단해 double로 바꿔주니 제대로 출력!

 

잘 됨!

 

근데 이렇게 값을 변경해주기보다 100보다 높으면 추가 코드를 작성해서 최대 hp를 100으로 설정하는게 더 좋아보임

 

이 코드도 잘 된다

 

2) 선생님이 푼 방식

 

먼저 값을 추적할 수 있는 조사식을 확인한다

 

근데 이런 방식으로 하면 음수가 나올때까지 계속 돌려야함

 

따라서 브레이크 포인트에 조건을 넣어서 검사함

 

조건을 이렇게 걸어주고 F5를 누르면

 

이렇게 조건에 걸린게 나옴

 

예상대로 int의 범위 (대략 21억)를 벗어나 일어난 일!

 

 

5. Exercise 5

a. 문제

ratio를 계산할 때 문제가 발생한 모습

 

b. 풀이

1) 내가 푼 방식

 

오류를 읽어보면 정수가 0으로 나눠져서 발생한 예외

 

0보다 작은 경우 코드를 실행하지 않는 예외로 수정하면 끝!

 

2) 선생님이 푼 방식

 

선생님은 hp가 0이되어도 반격할 수 있게 코드를 작성함

 

 

_maxHp == 0일때는 예외적인 부분이니 그냥 damage를 리턴하도록 하고,

비율을 퍼센티지로 수정해 조건을 바꿔줌

_hp에 100을 곱한 이유는 나눈 값이 float이 되니 int로 표현하기 위해 곱해준것 (퍼센트니까)

 

 

6. Exercise 6

a. 문제

함수를 무한으로 호출하다보니 stack overflow가 발생

 

b. 풀이

1) 내가 푼 방식

 

위 코드에서 OnDamage는 재귀호출 방식으로 반격을 처리하고 있음

코드를 분석해보니 AddHp에서 체력이 처리되어서 둘 중 하나가  죽음(0)이 되어도

후처리 되지 않고 무한으로 반격을 함

 

체력 처리 후 제대로 작동!

 

2) 선생님이 푼 방식

 

데미지가 0일때와, 죽었을때 처리

 

 

7. Exercise 7

a. 문제

 

b. 풀이

1) 내가 푼 방식

 

알맞지 않은 위치의 예외로 출력되어 메모리 상에 문제가 생겼음이라고 짐작했다

Knight의 생성자와 소멸자 로그를 찍어보니 

Player의 생성, 소멸자는 제대로 출력되지만 각 직업의 소멸자는 출력되지 않음을 확인했다

 

 

이는 소멸자가 가상함수로 생성되지 않아서 일어난 일임을 확인하고 코드를 수정했다

심지어 Archer의 Pet은 메모리를 할당받고 해제받지 못해 무한으로 메모리를 잡아먹게 된다

 

virtual 키워드를 넣으니 오류는 나지 않음

 

그대신 무한 호출로 버벅거린다,,, 하핫 (원래 코드가 그럼)

 

2) 선생님이 푼 방식

 

동일

 

 

8. Exercise 8

a. 문제

 

b. 풀이

1) 내가 푼 방식 ❌

 

Pet을 생성할 때 데이터 공간을 할당하지 않고 소멸해 생긴 문제였다

 

생성시 새로운 공간을 할당해주자

 

2) 선생님이 푼 방식

 

이렇게 지역변수에 할당해서 pet을 사용하게 되면 큰 문제가 발생함 

 

 

위처럼 자동으로 생성되고 소멸될 객체의 주소를 넘기면 안된다

심지어 저렇게 생성된 데이터 영역을 delete 하는건 말도 안됨!

 

따라서 위와 같이 꼭 힙 영역에 데이터를 생성해주고 삭제까지 한 세트로 가야한다

 

 

9. Exercise 9

a. 문제

 

b. 풀이

1) 내가 푼 방식

 

펫을 두번 소멸해 발생한 일 = 더블 프리 

 

위 X를 삭제하면 끝

 

2) 선생님이 푼 방식

 

delete _pet을 한 뒤 nullptr로 밀어주지 않아서 생긴 일

 

꼭 이렇게 밀어주는 작업이 필요함

 

 

10. Exercise A (10)

a. 문제

 

b. 풀이

1) 내가 푼 방식

 

0xFFFF는 데이터가 없어서 발생하는 예외이기 때문에 화살이 죽은 적을 타겟팅 하는지 먼저 살펴봄

 

아니나 다를까 기사가 죽어도 반복문이 실행되기 때문에 예외가 발생

 

기사가 있을 때에만 실행시키도록 함

 

2) 선생님이 푼 방식

 

use-after-free 문제

 

죽은 적을 타겟팅 하더라도 주소값이 없는 경우는 아예 오류가 나니까

죽더라도 화살은 계속 갈 수 있도록 knight의 값은 남겨두고, 나중에 삭제하는 방식으로 사용

 

완전 깔끔한 방법은 아님!

 

 

 


출처 : https://www.inflearn.com/course/%EA%B2%8C%EC%9E%84-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8-%EC%9E%85%EB%AC%B8-%EC%98%AC%EC%9D%B8%EC%9B%90-rookiss#curriculum

 

[게임 프로그래머 입문 올인원] C++ & 자료구조/알고리즘 & STL & 게임 수학 & Windows API & 게임 서버 -

어디부터 시작할지 막막한 게임 프로그래밍 입문자를 위한 All-In-One 커리큘럼입니다. C++, 자료구조/알고리즘, STL, 게임 수학, Windows API, 게임 서버 입문으로 이어지는 알찬 커리큘럼으로 게임 프

www.inflearn.com