디버깅

자신의 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에 의해 활성화됩니다.