일반적인 이유를 위해 버그에서 릴리스 버전에 존재하지 않는 디버그 모드

StackOverflow https://stackoverflow.com/questions/1762088

  •  21-09-2019
  •  | 
  •  

문제

무엇인가에 대한 일반적인 이유를 버그 및 비정상적인 프로그램으로 동작하는 매니페스트는 자신만에 출시 컴파일하지는 발생하지 않는 경우에 디버깅 모드?

도움이 되었습니까?

해결책

C ++의 디버그 모드에서 모든 변수는 null 초기화되는 반면, 명시 적으로 언급되지 않는 한 릴리스 모드에서는 동일하게 발생하지 않습니다.

디버그 매크로 및 초기화되지 않은 변수를 확인하십시오

프로그램에서 스레딩을 사용하면 최적화가 릴리스 모드에서 일부 문제를 일으킬 수 있습니다.

또한 모든 예외를 확인하십시오. 예를 들어 릴리스 모드와 직접 관련이 없지만 언젠가는 VC ++의 MEM 액세스 위반과 같은 몇 가지 중요한 예외를 무시하지만 적어도 Linux, Solaris와 같은 다른 OS에서는 문제가 될 수 있습니다. 이상적으로 귀하의 프로그램은 Null 포인터에 액세스하는 것과 같은 중요한 예외를 포착해서는 안됩니다.

다른 팁

일반적인 함정은 어설 싱 내부에 부작용이있는 표현을 사용하는 것입니다.

다른 차이점은 다음과 같습니다.

  • 쓰레기 수집 언어에서 수집가는 일반적으로 릴리스 모드에서 더 공격적입니다.
  • 메모리 레이아웃은 종종 다를 수 있습니다.
  • 메모리가 다르게 초기화 될 수 있습니다 (예 : 디버그 모드에서 제로화되거나 릴리스에서보다 적극적으로 재사용 할 수 있음);
  • 현지인은 출시 값을 등록하도록 촉진 될 수 있으며, 이는 부동 소수점 값에 문제가 발생할 수 있습니다.

나는 물의 수에 의하여 버그를 과거에는 잘 되었는 디버그 빌드에서 하지만 충돌에서 릴리스 있습니다.많은 기본 원인(를 포함하여 물론 사람들은 이미 요약되어 있습이 스레드)그리고 나는 잡은 밖의 모든 다음과 같다:

  • 회원 또는 변수 회원에서 기능 #ifdef _DEBUG, 는 클래스가 다른 크기 디버그 빌드에서.때때로 #ifndef NDEBUG 사용 릴리스에서 구축
  • 마찬가지로,다른 #ifdef 일만에 존재하는 두 가지 중 하나 구축
  • 디버 버전을 사용하여 디버의 버전 시스템 라이브러리,특히 힙 메모리 할당 기능
  • 인라인된 함수에 구축 릴리스
  • 의 순서를 포함하의 헤더 파일이 있습니다.이지 문제를 일으키지만,당신이 무언가가 있음 #pragma pack 되지 않은 다시 설정한 다음으로 이어질 수 있습 불쾌한 문제입니다.유사한 문제도 발생할 수 있습을 사용하여 컴파일된 헤더와 강제로 포함
  • 캐시:수 있는 코드 등 캐시만 사용됩 릴리스 빌드에서,또는 캐쉬 크기를 제한하는 다른
  • 프로젝트 구성:디버그 및 릴리스 구성할 수 있는 다른 빌드 설정(이것은 일어날 가능성이 높을 사용할 때 IDE)
  • 경쟁 조건,타이밍 문제와 기타 부작용 발생 등의 결과로만 디버깅 코드

몇 가지 팁은 수년에 걸쳐 축적을 위한 수단의 디버/릴리스 버그:

  • 을 재현하려고 변칙적인 행동을 디버그 빌드에서 당신이 할 수있는 경우,그리고 더 나은,단위 테스트를 캡처
  • 는 것에 대해 생각과 다릅 두:컴파일러 설정,캐시,디버그-만 코드입니다.을 최소화하기 위해 시도하는 사람들의 차이 일시적으로
  • 만들어 놓으로 구축 최적화 switch off(그래서 당신은 더 많이 받게 유용한 데이터를 디버거에서),또는 최적화된 디버그 빌드.을 최소화함으로써 간의 변경사항을 디버그 및 출시,당신은 더 많은 가능성이 될 수 있을 격리하려는 차이의 원인입니다.

예!, 조건부 편집이있는 경우 타이밍 버그 (최적화 된 릴리스 코드 구절, 최적화되지 않은 디버그 코드), 메모리 재사용 대 디버그 힙이있을 수 있습니다.

특히 C 영역에 있다면 가능합니다.

하나의 원인은 디버그 버전이 코드를 추가하여 길 잃은 포인터를 확인하고 어떻게 든 코드가 충돌하지 않도록 (또는 잘못 행동)를 보호 할 수 있기 때문일 수 있습니다. 이 경우 컴파일러에서 얻은 경고 및 기타 메시지를 신중하게 확인해야합니다.

또 다른 원인은 최적화 (일반적으로 릴리스 버전 및 디버그의 경우 꺼짐)입니다. 코드 및 데이터 레이아웃이 최적화되었을 수 있으며 디버깅 프로그램이 예를 들어 사용되지 않은 메모리에 액세스하는 것만으로도 릴리스 버전은 예약 메모리에 액세스하거나 코드를 가리키려고합니다!

편집 : 다른 언급 된 것을 볼 수 있습니다. 물론 디버그 모드에서 컴파일하지 않으면 조건부로 제외 된 전체 코드 섹션이있을 수 있습니다. 그렇다면, 그것이 실제로 코드를 디버깅하고 프로그램 자체의 정확성에 중요한 것이 아니기를 바랍니다!

CRT 라이브러리 기능은 디버그 대 릴리스 ( /MD VS /MDD)에서 다르게 행동합니다.

예를 들어, 디버그 버전은 종종 청구를 확인하기 위해 표시된 길이로 전달하는 버퍼를 시사합니다. 예는 포함됩니다 strcpy_s, StringCchCopy, 끈이 더 일찍 끝나더라도 szdest 더 낫다 N 바이트 길이!

예를 들어, 당신이 같은 구조물을 사용하는 경우

#if DEBUG

//some code

#endif

.NET에서 조건부 편집을 사용하지 않더라도 #if DEBUG, 컴파일러는 디버그 모드보다 릴리스 모드의 최적화로 여전히 더 자유롭고 버그 만 해제 할 수 있습니다.

더 많은 정보를 제공해야하지만 그렇습니다. 가능합니다. 디버그 버전이하는 일에 따라 다릅니다. 릴리스 버전으로 컴파일되지 않는 로그 또는 추가 확인이있을 수 있습니다. 이 디버그 코드 경로는 의도하지 않은 부작용이있을 수 있으며, 이는 상태를 변경하거나 이상한 방식으로 변수에 영향을 미칩니다. 디버그 빌드는 일반적으로 느리게 실행되므로 스레딩에 영향을 미치고 레이스 조건을 숨길 수 있습니다. 릴리스 컴파일의 간단한 최적화와 동일하지만 릴리스 컴파일이 최적화로 무언가를 단락시킬 수 있습니다.

더 자세한 내용이 없으면 "OK NOT OK"는 런타임에 어떤 종류의 오류를 컴파일하지 않거나 던지지 않는다고 가정합니다. 컴파일 버전에 의존하는 코드가 있는지 확인하십시오. #if DEBUG 진술 또는 그로 표시된 방법을 통해 Conditional 기인하다.

디버그 코드와 릴리스 코드가 다르고 릴리스 모드에서만 사용되는 코드에 버그가있는 경우 조건부 컴파일이있는 경우 가능합니다.

그 외에는 불가능합니다. 디버그 코드 및 릴리스 코드가 컴파일되는 방법에는 차이가 있으며 디버거에서 실행 되든지 실행되면 코드가 실행되는 방식에 차이가 있지만 이러한 차이가 성능 차이 이외의 다른 것을 유발하는 경우 문제가있었습니다.

디버그 버전에서는 오류가 발생하지 않을 수 있지만 (타이밍 또는 메모리 할당이 다르기 때문에) 오류가 없음을 의미하지는 않습니다. 코드의 타이밍을 변경하여 오류가 발생하든 아니든 디버그 모드와 관련이없는 다른 요소도있을 수 있지만 코드가 올바른 경우 오류가 발생하지 않는다는 사실로 모두 요약됩니다. 어떤 상황에서도.

따라서 오류를받지 않고 실행할 수 있기 때문에 디버그 버전은 괜찮지 않습니다. 릴리스 모드에서 실행할 때 오류가 발생하면 릴리스 모드 때문이 아니기 때문에 처음부터 오류가 있었기 때문입니다.

컴파일러 최적화가 있습니다 유효한 코드를 중단 할 수 있습니다 그들은 너무 공격적이기 때문에.

최적화가 덜 켜진 상태에서 코드를 컴파일하십시오.

비 공동 함수에서 모든 실행 경로는 반환 문으로 끝나야합니다.

디버그 모드에서 리턴 명령문으로 그러한 경로를 종료하는 것을 잊어 버린 경우 기능은 일반적으로 기본적으로 0을 반환합니다.

그러나 릴리스 모드에서는 기능이 쓰레기 값을 반환 할 수 있으며, 이는 프로그램 실행 방식에 영향을 줄 수 있습니다.

있을 수있다. 그것이 발생하고 조건부 편집이 관련되어 있지 않은 경우, 프로그램이 잘못되었음을 확신 할 수 있고, 메모리의 우연한 메모리 초기화 또는 메모리의 레이아웃으로 인해 디버그 모드에서만 작동하고 있습니다!

방금 레지스터의 이전 값을 복원하지 않은 어셈블리 기능을 호출 할 때 경험했습니다.

"릴리스"구성에서 VS는 /O2로 컴파일하여 속도를위한 코드를 최적화했습니다. 따라서, 앞서 언급 한 함수와 공유 된 CPU 레지스터 (최적화)에 매핑되는 일부 로컬 변수는 심각한 메모리 손상으로 이어집니다.

어쨌든 코드의 어느 곳에서나 CPU 레지스터를 간접적으로 엉망으로 만들지 않는지 확인하십시오.

C/C ++에서 DLL과 PDB를 구축 할 때 전에 기억합니다.

나 이거 기억해:

  • 로그 데이터를 추가하면 언젠가 버그가 움직이거나 사라지거나 완전히 다른 오류가 나타나게됩니다 (실제로 옵션이 아니 었습니다).
  • strcpy 및 strcat에서의 숯 할당과 char [] 등의 배열로 인해 이러한 오류가 많이 있습니다.
  • Bounds Checker를 실행하고 단순히 Memory Alloc/Dealloc 문제를 해결하여 일부를 제거했습니다.
  • 여러 번, 우리는 체계적으로 코드를 통과하고 모든 파일을 통해 char 할당을 수정했습니다.
  • 확실히 메모리 할당 및 관리 및 제약 조건 및 디버그 모드와 릴리스 모드의 차이와 관련이 있습니다.

그리고 최선을 다했습니다.

때로는 이러한 버그를 작업하면서 생산을 유지하지 않기 위해 DLLS의 디버그 버전을 클라이언트에게 임시로 제공합니다.

또 다른 이유는 DB 통화 일 수 있습니다. 같은 스레드에서 동일한 레코드를 여러 번 저장하고 업데이트하고 때로는 업데이트를 위해 업데이트하고 있습니까? 이전 Create 명령이 여전히 처리되었고 업데이트를 위해 DB 호출이 레코드를 찾지 못했기 때문에 업데이트가 예상대로 작동하지 않았거나 작동하지 않았습니다. 디버거가 착륙하기 전에 보류중인 모든 작업을 완료 할 수 있으므로 디버그에서는 발생하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top