비주얼 스투디오 c# 디버그와 릴리스 빌드의 차이와 주의할 점

릴리스 빌드를 한 때 주의할 점

디버그 빌드는 말 그대로 디버그를 하기 위한 거고 릴리스 빌드는 배포를 위한 거다. 디버그 빌드와 릴리스 빌드 사이에는 큰 차이가 없다. 비주얼 스투디오에서 디버그를 실행하는 거와 릴리스 빌드 사이에 큰 차이가 있을 뿐이다. 아래에 다루는 내용은 디버그 빌드가 아니라 비주얼 스투디오에서 디버그를 하는 경우다.

프로그램을 만들다 보면 대부분의 경우 의도와 다르게 작동한다. 디버그를 하는 동안 컴파일러가 제대로 컴파일을 할 수 없는 엉뚱한 상황에 처하게 되면 디버거는 그 상황을 ‘판단’하고 예외 상황으로 처리하여 프로그래머에게 알린다. 그런데 이 판단하는 과정에 비교적 큰 부하가 걸린다. 따라서 디버그는 릴리스 빌드에 비해 느리고 자원을 많이 점유이들 둘은 결국 같은 말이다한다.

아래 코드는 List.RemoveRange에 틀린 아규먼트를 입력하여 예외 상황을 만드는 예제다. RemoveRange는 리스트의 아이템들을 한꺼번에 지우는 메떠드인데 지우기 시작할 인덱스와 지울 개수를 패러미터로 받는다. 아래 예제에서는 count를 음수인 -1로 입력했다.

List<int> Ints = new();

private void button1_Click(object sender, EventArgs e)
{
    Task task = new(Method1);

    task.Start();
}

void Method1()
{
    Ints.RemoveRange(0, -1);
}

이 예제를 디버그하면 당연히 ArgumentOutOfRangeException이 던져지지만 디버그 빌드나 릴리스 빌드를 하면 아무 일도 일어나지 않는다. 새로운 뜨레드에서 실행하지 않고 메인 뜨레드에서 실행하면 디버그/릴리스 빌드에서도 예외 윈도우가 만들어진다. 이렇게 빌드를 하고 빌드된 프로그램을 실행하면 예외 상황에 대한 처리가 엄격하거나 일관되지 않다. 어떨 땐 아무런 오류 알림도 없이 애플리캐이션이 종료되어 개발자의 mental이 collapsing하는 situtation이 벌어지기도 한다. 그러나 차라리 이렇게 소리 소문 없이 조용히 사라지는 경우는 차라리 다행인 것이 이런 경우에는 윈도우가 이벤트로 기록하기 때문이다. 위 예제처럼 천연덕스럽게 아무 일도 하지 않는 경우야 말로 충공깽이다.

빌드를 하면 이렇게 문제 상황에 대한 대처가 힘들지만 대신 빠르다. 실행 속도가 디버그를 하는 때와 5배 정도 차이가 나기도 한다. 따라서 디버그를 하여 충분히 테스트를 한 뒤 릴리스 빌드로 배포를 하고 릴리스 빌드에서 오류가 일어나면 그 상태에서 문제를 해결하려 들 게 아니라 디버그를 할 수 있는 상황으로 빠르게 전환하여 대처해야 한다. 배포해서 디버그가 안 되요 뭐 이런 소리하고 있으면 안 된다.

애플리캐이션이 알림 없이 다운된 경우 이벤트 뷰어로 원인 찾기

애플리캐이션이 예외 윈도우를 만들지 않고 다운되어 조용히 사라진 경우 그 원인을 알려면 우선 당황하지 말고 정신줄을 부여잡은 뒤 이벤트 뷰어라는 걸 실행한다. 윈도우즈 시작 키를 누르고 이름을 입력하면 된다. 실행하면 왼쪽에 메뉴가 보이는데 거기에서 윈도우즈 로그 > 응용 프로그램을 고른다. 응용 프로그램 아닌 시스템에서는 암만 찾아봐도 없으니 주의한다. 거기에서 대충 시간으로 찾아보면 예를 들어 아래와 같은 오류가 확인될 거다.

Description: The process was terminated due to an unhandled exception.
Exception Info: System.ArgumentOutOfRangeException: Non-negative number required. (Parameter ‘count’)
at System.Collections.Generic.List`1.RemoveRange(Int32 index, Int32 count)
at WinFormsApp1.Form2.Conditions(Object unknownBlock) in D:\data\Documents\client\…\새 폴더\WinFormsApp1\WinFormsApp1\Form2.cs:line 1072

디버거가 예외로 처리한 것과 같은 내용이 친절하게 기록되어 있다. 심지어 오류가 일어난 코드의 위치까지 저장되어 있다.