디버그 코드를 항상 그대로 유지해야합니까, 아니면 버그가 발견되었을 때 디버깅 및 제거시에만 추가해야합니까?


35

우선 버그를 찾으려고 할 때 디버그 코드 (예 : print 문) 만 추가합니다. 일단 발견하면 디버그 코드를 제거하고 해당 버그를 구체적으로 테스트하는 테스트 사례를 추가합니다. 나는 그것이 실제 코드를 어지럽히고 있다고 생각하므로 디버깅하지 않는 한 거기에 아무 것도 없습니다.

어떻게합니까? 디버그 코드를 제자리에 두거나 사용하지 않을 때 제거하십시오 (있는 경우 판단하기 어려울 수 있음)?

답변:


30

디버그 인쇄 명령문을 제거해야합니다. 그러나 프로덕션 문제점을 디버그하기 위해 추가해야하는 경우 로깅 프레임 워크에 충분한 정보가 있는지 고려할 가치가 있습니다. 매개 변수, 오류 조건 등에 대한 정보는 다음 버그가 나타날 때 나중에 유용 할 수 있습니다. 디버그 또는 추적 로그 메시지를 동적으로 설정할 수있는 좋은 로깅 프레임 워크를 사용하면 매우 유용 할 수 있습니다.


5
+1 주로 적절한 디버깅 프레임 워크가 있다고 언급합니다. 이것이 초기에 존재하고 다양한 디버그 레벨이있는 ​​경우, 고가의 디버그 루틴을 호출하지 않고도 프로덕션 코드가 희망적으로 실행될 수 있으며, 개발 코드는 원하는 수준의 정밀한 조사로 실행될 수 있으며, 원하는 방식으로 원하는대로 로그인 할 수 있습니다.
Orbling

1
Orbling에 동의하십시오. 또한 성능에 영향을 주거나 생산에 적합하지 않은 다른 정보 만 표시하는 디버그 코드의 경우. (예 : 기능 결과에 대한 Assert (예 : 정렬 결과 확인)) 두 가지 빌드 대상 모드를 고려할 수 있습니다. 디버그 모드 및 릴리스 모드.
Zekta Chan

16

디버깅을 위해 특별히 추가 된 코드는 프로덕션 소프트웨어에서 제거해야합니다.

이것이 완전히 제거되었는지 또는 조건부 컴파일 섹션 (C / C ++ / C #에서와 같이)에 들어가는 지 여부는 사용자와 코딩 표준에 달려 있습니다.

이에 대한 여러 가지 이유가 있습니다.

  1. 이 코드가 실행되거나 누군가가 해당 코드의 출력에 액세스 할 수있는 경우 보안에 영향을 줄 수 있습니다.
  2. 응용 프로그램 속도가 느려질 수 있습니다.
  3. 6 개월 동안 코드를 보거나 실제로는 다른 개발자들에게는 혼란 스러울 수 있습니다.

조건부 컴파일의 경우 +1이지만 주석 블록은이를 지원하지 않는 언어로 작동합니다. 컴파일 된 버전으로 컴파일 된 상태로 두어서는 안되지만 릴리스 빌드를 삭제하려고 할 때마다 완전히 삭제하는 것은 너무 비효율적입니다.
Bill

1
프로덕션 코드를 디버깅하거나 코어 덤프를 검사해야하는 경우 C / C ++ 코드가 항상 디버그 옵션으로 컴파일 된 환경에서 작업했습니다. 때로는 항상 디버그 위임 준비가 완료되어 디버그 명령문을 남겨 두어야 코드를 다시 컴파일하지 않고 플래그로 설정할 수 있습니다. JVM 옵션이 설정된 경우 Java는 항상 디버깅을 허용하므로 나중에 디버깅하는 데 필요한 준비 작업이 상대적으로 적습니다.
Michael Shopsin

16

ChrisFAlaric은 모두 유효한 포인트를 가지고 있습니다. 그들을 위해 +1. 내가 사용하는 적어도 다섯 가지 유형의 디버그 코드를 식별 할 수 있습니다.

  1. 로그를 사용하여 특정 시점에서 시스템 상태를 덤프합니다.

    void function(...)
    {
        ...dump everything i know about.
    }
    
  2. 실행 검사 점에 로그 사용

    void function(...)
    {
        ...got here 1
        ...got here 2
    }
    
  3. 실제로 특정 조건을 강제로 적용하지만 정상적인 동작을 중단시키는 코드입니다. 예:

    • 오류에 관한 로그가 있지만 문제를 재현 할 수 없다고 가정하십시오. 특정 변수가 로그의 정보와 일치하는 특정 값을 갖도록하는 코드 작성을 시도 할 수 있습니다.
  4. 검증 로깅-알고리즘의 개별 단계를 검증하는 것과 같이 프로덕션에 포함되어서는 안되는 소프트웨어의 정확성을 검증하는 데 사용할 수있는 자세한 로깅으로 이것을 분류합니다.

  5. 작업 로깅 -Alaric의 게시물을 참조하십시오 . 이것이 바로 "작업 로깅"이라는 의미입니다.

1, 2 및 3은 완전히 꺼내야합니다. 4와 같은 코드는 아마도 조건부로 코드에서 컴파일 할 것입니다. 5 년 동안 Alaric 은 동적으로 로그를 끌 수 있다는 점에 주목 했습니다. 그것은 대부분의 경우 ChrisF가 두 번째 글 머리 기호로 지적 할 수 있습니다 .


1
이것은 좋은 요약입니다. 그러나 1)…를 1.… 로 바꾸고 (마크 다운 형식이 목록으로 선택하도록) 예제 코드를 8 개의 공백으로 들여 쓰면 (예 : Markdown이 예제로 선택함으로써) 올바른 형식을 지정할 수 있다면 더 좋습니다 . 목록 내의 코드).
Konrad Rudolph

@ Konrad Rudolph : 완료.
gablin

3

코드가 수행하는 작업에 따라 다릅니다. 디버깅에 사용되는 일부 코드는 그대로 유지 될 수 있으며 일부 코드는 제거해야합니다.

메소드에서 매개 변수의 온 전성을 검증하는 코드는 코드가 올바르게 작동하면 항상 유용하지는 않지만 코드가 계속 제대로 작동하는지 확인해야합니다.

때로는 값을 계산하고 로컬 변수에 넣은 다음 코드를 쉽게 디버그하기 위해 코드를 다르게 작성하는 경우 다음 줄에 변수를 사용하여 단일 스테핑시 계산 결과를 쉽게 확인할 수 있습니다. 코드를 통해. 계산 된 값을 직접 사용하도록 코드를 다시 작성할 수는 있지만 로컬 변수를 사용하는 비용이 너무 적어서 코드를 다시 작성할 이유가 거의 없습니다. 또한 코드를 테스트 한 후에는 코드를 변경하지 않은 채로 두어야 할 점이 있습니다. 코드를 변경할 때 버그가 발생할 위험은 항상 적습니다.

특정 버그를 추적하기 위해 추가 한 코드는 버그를 찾은 후에 종종 제거 될 수 있습니다.


2

옛날 옛적에 나는 많은 디버깅 코드를 사용했다. 나는 거의 전적으로 Windows를 목표로 삼았으므로 더 이상 철자를 쓰는 방법을 기억하지 못하는이 디버그 문자열 출력 함수가 많았으므로 특정 프로그램으로 추적을 캡처 할 수있었습니다.

일부 디버그 코드, 특히 호출의 중첩을 제공하기위한 것입니다. 그러나 디버그 문자열은 대부분 프로덕션 시스템에서 볼 수 없지만 조건부 컴파일 하에서 모두 수행되었습니다.

그러나 실제로는 모든 디버그 코드가 디버거를 사용하여 다른 방식으로 이상적으로 처리되는 무언가에 많은 노력을 기울 였다는 것입니다. 당시 저는 Borland C ++ 디버거에 깊은 인상을받지 못했습니다. 도구가 있었지만 너무 잘못된 결과를 낳았으며 IDE가 아닌 디버거 (필요한 경우)를 사용하면 바로 가기 키를 암기 할 수있었습니다.

내가 찾은 유일한 디버깅 경험은 명령 줄 GDB입니다.

물론 매일 사용하는 도구에 대한 전문가가되는 것이 중요합니다. 그러나 디버깅은 매일하는 일이 아닙니다. 디버거를 너무 자주 사용하면 수십 가지 명령 및 / 또는 키보드 단축키를 배우면 괜찮습니다.

하지만 Visual Studio 7에서 작업 할 때는 디버깅이 매우 실용적이고 효과적 일 수있었습니다. Visual Studio (Express Edition 포함)에서 디버깅을 수행 할 수 있으면 디버깅이 매우 쉽습니다. 올바른 GUI / IDE 프론트 엔드를 찾을 수 있다면 의심의 여지없이 GDB도 쉽고 효과적이지만 아직 검색하지 않았습니다.

gcov를 사용한 커버리지 분석을 통해 단위 테스트에 대해 언급해야 할 사항도 있습니다. 라이브러리의 동작에 대한 확신이 많을수록 디버깅의 깊이는 줄어들고 디버거는 덜 필요합니다. 단위 테스트를 작성하는 것은 대부분의 날에해야 할 일입니다.

예기치 않게 중요한 도구 = cmake는 다른 것들 중에서도 GCC와 VC ++의 빌드를 쉽게 전환 할 수있는 빌드 도구입니다. 따라서 GCC를 사용하여 단위 테스트 및 gcov 기반 적용 범위를 수행 할 수 있지만 디버거를 사용하기 위해 VC ++로 쉽게 전환 할 수 있습니다.


디버거는 멀티 스레드 응용 프로그램에서 위험하지는 않지만 쓸모가 없지만 쓸모없는 의견을 좋아합니다.
Pemdas

@Pemdas-멀티 스레딩은 분명히 디버거 친화적이지 않지만 그 라인을 따라 심각한 문제는 없었습니다. 그럼에도 불구하고 올바른 도구는 원칙적으로 디버그 코드보다 더 나은 솔루션이라고 생각합니다. 경쟁 조건, 교착 상태, 두 스레드가 같은 메모리 / 자원에 대해 동시에 싸울 수있는 상황 등을 파악할 수있는 정적 분석 도구가 좋습니다. 나는 그 라인을 따라 무엇을 사용할 수 있는지 전혀 모르지만, 거기에는 영리한 도구가 있다는 것을 알고 있습니다. 예를 들어 klee-나는 그것을 이해하지 못하지만 기본 설명은 매우 인상적입니다.
Steve314

"정확한 도구는 원칙적으로 디버그 코드보다 더 나은 솔루션이라고 생각합니다." 분석의 일부를 수행하는 도구를 사용하는 것이 좋을 수도 있지만, 특히 개발자가 새로운 도구가 도구에 너무 의존하기 시작한다고 걱정합니다.
Pemdas

내가 아직 연구하지 않은 도구에 너무 의존하는 것은 거의 불가능합니다. 계산기 예제에서 예,하지만 여전히 간단한 스프레드 시트를 작성하지 않고 OpenOffice Calc를 사용합니다. 디버그 코드에는 시간이 있지만 (예를 들어 자신의 기괴한 조건 생성 사례와 같은 디버거 사용), 특정 시점을 넘어 서면 기존 도구가 승리합니다. 그리고 115에서 15 %를 빼면 그 계산기도 사용할 것입니다-많은 사람들이 명백한 대답 (100)으로 잘못했을 것입니다. 멀티 스레딩에서, 정답은 때때로 잘못된 것으로 판명 된 것으로 유명합니다.
Steve314

1

내 취향 : 문제의 코드에서 버그를 죽이는 데 사용되는 디버그 코드는 일반적으로 완전히 제거합니다. 외부 힘으로 인한 버그를 죽이는 데 사용되는 디버그 코드는 일반적으로 단순히 주석 처리합니다.


-1

버그가 단위 테스트 또는 내부 버그 인 경우 디버그 코드를 모두 제거 할 수 있습니다. 그러나 버그가 프로덕션 환경에서 발생하는 경우 컴파일 코드 안에 디버그 코드가있는 것이 좋습니다. 컴파일 태그에 넣으면 다른 개발자가이 코드가 디버그 목적만을위한 것임을 이해하는 데 도움이됩니다.


-1

TDD를 사용하면 테스트 코드가 항상 유지되는 위치에있게됩니다.


이것은 질문에 어떻게 대답합니까?
gnat

TDD를 사용하면 제거 할 필요가없는 "디버그"또는 테스트 코드가 나타납니다.
dukeofgaming

미안하지 않습니다. 방법 것입니다?
gnat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.