당신은 당신이 지역 주민을 볼 수없는 이유에서 힌트를 몇 가지 ...
# 1은 말했다했습니다.
특정 최적화 기능이 켜져 있으면 컴파일러는 지역 주민을보다 쉽게 볼 수있는 몇 가지 작업을 수행 할 수 있습니다.
- 수 있습니다. 기능은 inline입니다. 이 경우 최적화되지 않은 함수의 지역 주민이 호출 스택 프레임과 혼합됩니다.
- Frame-Pointer Omission이라는 트릭을 사용하여 레지스터를 확보하고 함수 호출에 몇 개의 클럭 사이클을 저장할 수 있습니다.
- 스택 공간을 절약하기 위해 나중에 함수에서 다른 변수를 보유하기 위해 함수 본문에서 변수를 먼저 보유한 컴파일러가 reuse the location을 사용할 수 있습니다. 즉, 함수에있는 곳에서 실제로 볼 수있는 지역을 결정합니다.
# 2 - x64 빌드입니다.
MSVC는 x64 Calling Convention이라는 64 비트 코드에 대해 새로운 호출 규칙을 사용합니다. 처음 4 개의 함수 인수는 스택 대신 레지스터에 저장됩니다. 즉, 스택 프레임을보고있을지라도 인수의 일부를 볼 수 없으며 레지스터를 살펴볼 때까지 레지스터가 다른 용도로 재사용 되었다면 복구 할 수 없을 수도 있습니다.
이제 무엇을 할 수 있습니까?
우리는 왜 그런 어려움을 겪어야하는지 알았으므로 위의 문제를 해결하기 위해 무엇을 할 수 있는지 알아 보겠습니다. 그 쟁점들 중 어느 것도 정말로 마개를 보여주지는 못하지만, 그것들은 모두 당신을 위해 그 일을 훨씬 더 어렵게 만듭니다.
몇 가지 최적화를 해제 . 디버깅을 상당히 방해하지 않는 수준에서 최적화 된 릴리스 빌드를 사용해 볼 수 있습니다. 스택 프레임 (/ Oy 및/Ob)을 사용하여 위에서 언급 한 최적화 작업을 시작하는 것이 좋습니다. 그런 다음 최적화가 해제 된 상태에서 문제를 재현 할 수 있기를 바랍니다. 또한 내부 정책 및 고객과의 계약에 따라 고객에게 비공식적 인 빌드를 보내기 전에 변호사를 참여시켜야 할 수도 있습니다. 아마도 세계에서 가장 재미있는 일은 아닐 것입니다.
더 나은 심볼 파일을 작성하십시오. VS2012 이상에는 최적화가 켜져있을 때 더 나은 디버그 정보를 생성하는 새로운 컴파일러 스위치 /d2Zi+ in VS2012 및 /Zo in VS2013이 있습니다. 이렇게하면 디버깅 최적화 코드가 GCC/Clang과 동등하게됩니다. 비록 그것이 VS2012에서 문서화되지는 않았지만, 심볼 파일에서만 생성 된 코드에서 차이점을 발견하지 못했기 때문에 여전히 꽤 안전하다고 생각할 것입니다. 이 플래그를 사용하여 로컬에서 다시 빌드하고 windbg에 .symopt+ 0x40
을 통해 새 심볼 파일을 사용하도록 할 수도 있습니다. 이렇게하면 이미 가지고있는 덤프에서 더 많은 것을 얻을 수 있습니다.
무거운 물건을 들기 위해 windbg 확장을 사용하십시오.other StackOverflow answers에서 CMKD이라는 도구를 언급했는데 내 베이컨을 두 번 저장했습니다. 다른 것들 중에서도 레지스터로 전달 된 x64 호출 규칙에서 인수를 재구성하려고 시도합니다. 그것은 확실한 것이 아니지만, 아마도 그들을 되 찾는 최고의 희망 일 것입니다.
어쨌든 내 말투가 디버깅에 도움이되기를 바랍니다.
[GCC] (http://gcc.gnu.org/) 또는 [Clang/LLVM] (http://clang.llvm.org/)과 같은 다른 컴파일러로 전환하는 것을 고려 했습니까? 디버그 정보와 최적화 (예 :'g ++'또는'-O2 -g'와 함께'clang')로 컴파일 할 수 있습니다. –
지역은 최적화 된 경향이 있습니다. 따라서 "케이크를 가지고 먹을 수 없습니다" 일반적으로 –
릴리즈/최적화 된 빌드가 디버그하기 쉽지 않다고 생각하지 마십시오. x86_64에는 훨씬 더 많은 레지스터가 있으므로 컴파일러는 메모리에 많은 변수를 유출하지 않아도되므로 값을 보지 못한 이유 중 하나 일 수 있습니다. –