왜 응용 프로그램을 디버깅 할 때 모든 컴파일러 최적화 기능을 해제해야합니까?디버그 빌드에서 컴파일러 최적화가 켜져 있으면 무엇이 문제입니까?
I는 8 비트 마이크로 컨트롤러 인터럽트 서비스 루틴 + ROM 영역/윈도우 (CONST 전역 변수) + 코드 15K 가능한 코드의 메모리 공간을 갖는다 (OKI 411)에 일하고
배경. 우리는 ~ 13K를 거의 먹는다. 그래서 심지어 디버깅 중에 가능한 최대의 최적화를 켜는 것이 매우 유혹적이다.
왜 응용 프로그램을 디버깅 할 때 모든 컴파일러 최적화 기능을 해제해야합니까?디버그 빌드에서 컴파일러 최적화가 켜져 있으면 무엇이 문제입니까?
I는 8 비트 마이크로 컨트롤러 인터럽트 서비스 루틴 + ROM 영역/윈도우 (CONST 전역 변수) + 코드 15K 가능한 코드의 메모리 공간을 갖는다 (OKI 411)에 일하고
배경. 우리는 ~ 13K를 거의 먹는다. 그래서 심지어 디버깅 중에 가능한 최대의 최적화를 켜는 것이 매우 유혹적이다.
디버그 이진을 컴파일 할 때 컴파일러는 코드 문 (또는 코드 문)과 어셈블리 언어 지침 간의 1 : 1 대응을 유지하려고 시도합니다. 이렇게하면 디버깅 할 때 지시에 따라 명령을 수행 할 수 있으며 디버거가 이진 파일의 현재 위치와 올바른 소스 코드를 쉽게 연관시킬 수 있습니다. 일반적으로 컴파일러는 모든 명명 된 변수가 실제로 메모리 어딘가에 존재하도록 보장하므로 디버거에서 내용을 볼 수 있습니다.
컴파일러 최적화는 사용되지 않거나 불필요한 지역 변수를 생략하고 코드를 재구성하여보다 효율적으로 사용할 수 있습니다. 함수는 인라인 될 수 있고 표현식은 부분적으로 또는 전체적으로 미리 계산되거나 재배치 될 수 있습니다. 대부분의 이러한 최적화 및 유사한 최적화를 통해 원본 소스 코드와 생성 된 어셈블리를 서로 연관시키는 것이 어렵습니다.
제가 생각할 수있는 유일한 점은 디버깅을 더 어렵게 만들 수 있다는 것입니다.
이외에는 아무런 문제가 없어야합니다.
전원을 켜는 것이 좋습니다. 컴파일이 더 빨라지기 때문에 대개 꺼져 있습니다. 큰 프로젝트의 경우 실제 관심사가 될 수 있습니다. 가능하다면 켜는 것이 실제로 좋으므로 마지막 순간의 최적화로 인해 불쾌한 문제가 발생하지 않도록하십시오.
나는 확실히 켜기를 원할 것이다.
이렇게하면 특정 형태의 디버깅에 문제가 발생할 수 있지만 이러한 경우에는 문제를 해결할 수 있어야합니다.
고려 :
for (i = 0; i < 10; i++) {
src[i] = dest[i];
}
최적화 후,이 코드는 같을 수 있습니다 즉
src[0] = dest[0];
src[1] = dest[1];
⋮
src[9] = dest[9];
는 더 이상 아무 i
이 없습니다. 디버거는 i
이 스택 프레임에있을 것으로 예상하지만 옵티마이 저는 스택 프레임을 제거합니다.
또한 스테핑을하면 PC가 모든 곳에서 (무작위로) 점프하고, 디버깅을 매우 어렵게하거나 불가능하게 만드는 다양한 이상한 점이 발생할 것입니다 (옵티마이 저가 수행 한 내용에 따라 다름).
하드웨어 레지스터에서 읽으려고하는 것과 비슷한 상황에서 레지스터가 메모리 매핑되었고 gcc에서 CFLAGS = "- o2"로 잘못된 값을주었습니다 .CLAGS를 사용할 때 = "- O0", 그것은 작업을 시작했습니다. 컴파일러 최적화가 무시되도록 휘발성 변수에 캐스팅하여 동일한 결과를 얻을 수 있음을 언급 할 가치가 있습니다.