2

왜 응용 프로그램을 디버깅 할 때 모든 컴파일러 최적화 기능을 해제해야합니까?디버그 빌드에서 컴파일러 최적화가 켜져 있으면 무엇이 문제입니까?

I는 8 비트 마이크로 컨트롤러 인터럽트 서비스 루틴 + ROM 영역/윈도우 (CONST 전역 변수) + 코드 15K 가능한 코드의 메모리 공간을 갖는다 (OKI 411)에 일하고

배경. 우리는 ~ 13K를 거의 먹는다. 그래서 심지어 디버깅 중에 가능한 최대의 최적화를 켜는 것이 매우 유혹적이다.

답변

6

디버그 이진을 컴파일 할 때 컴파일러는 코드 문 (또는 코드 문)과 어셈블리 언어 지침 간의 1 : 1 대응을 유지하려고 시도합니다. 이렇게하면 디버깅 할 때 지시에 따라 명령을 수행 할 수 있으며 디버거가 이진 파일의 현재 위치와 올바른 소스 코드를 쉽게 연관시킬 수 있습니다. 일반적으로 컴파일러는 모든 명명 된 변수가 실제로 메모리 어딘가에 존재하도록 보장하므로 디버거에서 내용을 볼 수 있습니다.

컴파일러 최적화는 사용되지 않거나 불필요한 지역 변수를 생략하고 코드를 재구성하여보다 효율적으로 사용할 수 있습니다. 함수는 인라인 될 수 있고 표현식은 부분적으로 또는 전체적으로 미리 계산되거나 재배치 될 수 있습니다. 대부분의 이러한 최적화 및 유사한 최적화를 통해 원본 소스 코드와 생성 된 어셈블리를 서로 연관시키는 것이 어렵습니다.

1

제가 생각할 수있는 유일한 점은 디버깅을 더 어렵게 만들 수 있다는 것입니다.

이외에는 아무런 문제가 없어야합니다.

2

전원을 켜는 것이 좋습니다. 컴파일이 더 빨라지기 때문에 대개 꺼져 있습니다. 큰 프로젝트의 경우 실제 관심사가 될 수 있습니다. 가능하다면 켜는 것이 실제로 좋으므로 마지막 순간의 최적화로 인해 불쾌한 문제가 발생하지 않도록하십시오.

나는 확실히 켜기를 원할 것이다.

이렇게하면 특정 형태의 디버깅에 문제가 발생할 수 있지만 이러한 경우에는 문제를 해결할 수 있어야합니다.

5

고려 :

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가 모든 곳에서 (무작위로) 점프하고, 디버깅을 매우 어렵게하거나 불가능하게 만드는 다양한 이상한 점이 발생할 것입니다 (옵티마이 저가 수행 한 내용에 따라 다름).

2

하드웨어 레지스터에서 읽으려고하는 것과 비슷한 상황에서 레지스터가 메모리 매핑되었고 gcc에서 CFLAGS = "- o2"로 잘못된 값을주었습니다 .CLAGS를 사용할 때 = "- O0", 그것은 작업을 시작했습니다. 컴파일러 최적화가 무시되도록 휘발성 변수에 캐스팅하여 동일한 결과를 얻을 수 있음을 언급 할 가치가 있습니다.

관련 문제