디버깅
자신의 C++ 코드를 Visual Studio 디버거를 사용하여 디버깅할 수 있으며, 함수 중단점을 사용하여 소스 코드 없이도 실행을 "추적"할 수 있습니다.
로깅
문제를 해결하는 데 따라, 언리얼 로그에 로깅 정보를 기록하는 것이 Visual Studio 디버거를 사용하는 것보다 더 빠를 수 있습니다. 로깅에 대한 자세한 내용은 로깅 페이지에서 확인할 수 있습니다.
구성
Visual Studio 디버거에 대해 더 알아보려면 여기를 참고하십시오.
언리얼 엔진 디버거에 대한 Rider에 대해 더 알아보려면 여기를 참고하십시오.
모든 소스 코드가 없는 상태에서 작업이 가능하도록 하려면 디버거를 구성하여 소스 코드가 원본 버전과 정확히 일치하지 않아도 괜찮도록 해야 합니다.
Visual Studio에서는
디버그 > 옵션…
으로 이동한 다음 디버깅 > 일반
아래에서 "Require source files to exactly match the original version" 항목을 찾아 체크를 해제합니다. 스크롤 가능한 영역의 중간쯤에 위치해 있습니다.
실행 인수
특정 언리얼 엔진 실행 인수는 디버깅할 때 특히 유용할 수 있습니다.
게임을 실행 인수와 함께 시작하는 방법에 대한 내용은 FAQ 페이지에서 확인할 수 있습니다.
NoExceptionHandler
-NoExceptionHandler
인수는 Just In Time 디버깅을 사용할 수 있게 해줍니다.
이 인수가 존재하면, 메인 SEH 예외 처리기가 비활성화됩니다.
이로 인해 충돌 보고서가 SEH 예외(즉, 접근 위반)를 잡지 못하게 되고, 대신 디버거가 이를 처리할 수 있게 됩니다.
이 인수가 없으면, 연결된 디버거가 접근 위반이나 체크를 잡지 못하고, 게임이 그냥 충돌됩니다.
이 인수는 언리얼 엔진에 의해 추가되고 처리됩니다.
WaitForDebugger
-WaitForDebugger
인수를 실행 인수에 추가하면,
게임이 계속 실행되기 전에 디버거가 연결될 때까지 기다립니다.
이것은 시작 시퀀스에서 문제를 조기에 잡는 데 도움이 될 수 있습니다.
이 실행 인수는 언리얼 엔진에 의해 추가되지만, 게임의 Shipping 빌드에서는 일반적으로 작동하지 않습니다. SML은 이를 작동할 수 있도록 하는 사용자 정의 핸들러를 포함합니다. Shipping에서는 대기하는 정확한 지점이 SML 초기화입니다. SML 핸들러가 없었다면, 엔진 루프 내부에서 대기했을 것입니다.
디버거 연결
이제 선택한 디버거를 실행 중인 새티스팩토리 프로세스인 FactoryGame-Win64-Shipping.exe
에 연결해야 합니다.
편집 세션 중에 한 번 연결한 후에는 "프로세스에 다시 연결"을 사용하여 디버거를 빠르게 다시 연결할 수 있습니다.
중단점
디버거가 연결되면 C++ 코드나 소스가 있는 다른 코드에 중단점을 추가할 수 있습니다. 중단점이 발생하면 로컬 변수를 보고, 호출 스택을 확인하고, 코드를 단계별로 실행할 수 있습니다.
함수 중단점
함수 중단점을 설정하면 소스 코드가 없는 경우에도 기본 함수가 호출될 때 중단할 수 있습니다.
이를 위해 Visual Studio에서 툴바의 '디버그’를 클릭하고 '새 중단점' 위에 마우스를 올린 다음 '함수 중단점’을 클릭합니다. 그 창이 열리면 ClassName::FunctionName
형식을 사용하여 중단할 함수를 붙여넣을 수 있습니다.
함수 중단점이 대부분의 경우 작동하는 것처럼 보이지만, 예상하는 위치에서 중단되지 않는 경우가 있을 수 있습니다. 이 경우에는 운이 없다고 생각해야 합니다. 다른 함수에서 중단해 보아야 합니다. |
함수 중단점이 발생하면 로컬 변수를 보고, 호출 스택을 확인하고, 코드를 단계별로 실행할 수 있습니다. 코드를 단계별로 실행할 때 실제 코드를 볼 수는 없지만, 여러 중단점을 설정하고 호출 스택과 로컬 변수를 관찰하여 어떤 함수가 호출되는지에 대한 순서를 파악할 수 있습니다.
Assert, Ensure 및 Check
Assertion statement는 코드에서 가정이나 조건을 확인하고 검증하는 데 사용되는 도구입니다. 이 조건들은 종종 포인터가 null이 아님, 나누는 수가 0이 아님, 함수가 재귀적으로 실행되지 않음, 또는 코드가 요구하는 다른 중요한 가정들입니다. 이러한 조건을 매번 확인하는 것은 비효율적일 수 있습니다.
올바르게 사용하면 버그를 조기에 잡고 가정이 위반된 정확한 위치를 파악하여 디버깅을 쉽게 할 수 있습니다.
이 유틸리티에 대한 자세한 내용(및 사용 예제)은 관련 언리얼 엔진 문서 페이지에서 확인할 수 있습니다.
Assert 및 Check statement는 조건이 충족되지 않으면 게임을 충돌시키지만, Ensure statement는 게임이 계속 실행되도록 허용합니다.
일반적으로 언리얼의 표준 check()
대신 커피 스테인에서 구현한 맞춤 assert인 fgcheck()
를 사용하는 것이 좋습니다. fgcheck는 Shipping 빌드에서 활성화됩니다.
SML이 설치되고 디버거가 연결되면 Check 및 Ensure가 디버거에 의해 잡힙니다. 이것은 일반적으로 언리얼 엔진 게임의 Shipping 빌드에서는 발생하지 않지만, 이 동작은 SML에 의해 활성화됩니다.