2014-12-31 12 views
5

Ilekroć otrzymuję zrzut awaryjny dla kompilacji wersji 64 aplikacji, uważam, że rzadko można zobaczyć lokalnych użytkowników, co utrudnia lub uniemożliwia naprawienie niektórych problemów. W x86 zazwyczaj widzę wszystkich mieszkańców bez żadnych problemów.Czy są jakieś opcje kompilatora, aby upuszczenie zrzutu z wersji x64 było bardziej użyteczne?

Czy są dostępne opcje kompilacji w kompilacji wydania, które pozwolą mi wyświetlić lokali w zrzutach awaryjnych wersji kompilacji? Oczywiście nie chcę wyłączać optymalizacji, ale być może jest jakiś sposób zmuszenia go do uratowania mieszkańców z niewielkim wpływem na wydajność?

+0

Czy rozważałeś przejście na inny kompilator, na przykład [GCC] (http://gcc.gnu.org/) lub [Clang/LLVM] (http://clang.llvm.org/)? Możesz skompilować zarówno informacje o debugowaniu, jak i optymalizacje (np. 'G ++' lub 'clang' z' -O2 -g') –

+0

Mieszkańcy mają tendencję do optymalizacji, więc nie, nie możesz "zjeść swojego ciasta i zjeść", ogólnie. –

+1

Nie oczekuj, że wersja/zoptymalizowana kompilacja będzie przyjazna debugowaniu. x86_64 ma o wiele więcej rejestrów, więc kompilator nie będzie musiał przesyłać wielu zmiennych do pamięci, co może być jedną z przyczyn, dla których nie widzisz wartości. –

Odpowiedz

10

pan powiedział kilka rzeczy, które wskazywać na dlaczego nie można zobaczyć mieszkańców ...

# 1 - Jest to build release.

Po włączeniu niektórych optymalizacji kompilator może wykonać kilka czynności, które utrudniają wyszukiwanie mieszkańców.

  1. Może to być inline funkcja. Kiedy tak się dzieje, locals funkcji, która nie jest zoptymalizowana, miesza się z ramką stosu wywołań.
  2. Może zwolnić rejestr i zapisać kilka cykli zegara na wywołanie funkcji za pomocą sztuczki o nazwie Frame-Pointer Omission.
  3. Aby zaoszczędzić miejsce na stosie, kompilator może reuse the location, który trzymał zmienną wcześniej w treści funkcji, aby pomieścić inną zmienną później w funkcji. Oznacza to, że miejsce, w którym znajdujesz się w funkcji, określa, którzy lokalnie jesteś w stanie zobaczyć.

# 2 - Jest to kompilacja x64.

MSVC używa nowej konwencji wywołania dla 64-bitowego kodu trafnie nazwanego x64 Calling Convention. Pierwsze 4 argumenty funkcji są przechowywane w rejestrach zamiast na stosie. Oznacza to, że nawet jeśli patrzysz na ramkę stosu, nie zobaczysz niektórych z argumentów i możesz nawet nie być w stanie ich odzyskać, jeśli rejestry zostały ponownie wykorzystane do czegoś innego, zanim spojrzysz na nie.


Co teraz?

Teraz, gdy wiemy, dlaczego masz tak trudny czas, zobaczmy, co możesz zrobić, aby ominąć powyższe problemy. Żadne z tych problemów nie są tak naprawdę zatyczkami pokazowymi, ale wszystkie one działają razem, aby uczynić to, co jest o wiele trudniejsze dla ciebie.

  1. Wyłącz niektóre optymalizacje. Możesz spróbować tworzyć z kompilacją wydania z optymalizacjami na poziomie, który nie przeszkadza w debugowaniu tak bardzo. Najprawdopodobniej chciałbyś zacząć od wspomnianych powyżej optymalizacji, które działają z ramkami stosu (/ Oy i/Ob). Wtedy musisz mieć nadzieję, że nadal możesz odtworzyć problem z wyłączonymi optymalizacjami. Ponadto, w zależności od twojej wewnętrznej polityki i umowy, którą masz z klientem, może być konieczne zaangażowanie prawnika przed wysłaniem nieoficjalnej kompilacji do klienta - prawdopodobnie nie jest to najbardziej zabawna rzecz na świecie.

  2. Utwórz lepszy plik symboli. VS2012 i nowszy ma nowy przełącznik kompilatora, /d2Zi+ in VS2012 i /Zo in VS2013, który generuje lepsze informacje diagnostyczne po włączeniu optymalizacji. Spowoduje to zoptymalizowanie kodu debugowania na równi z GCC/Clang. Nawet jeśli jest nieudokumentowane w VS2012, nadal uważałbym to za całkiem bezpieczne, ponieważ nie widziałem różnicy w wygenerowanym kodzie - tylko w pliku symboli. Możesz nawet być w stanie odbudować lokalnie z tą flagą i zmusić windbg do użycia twojego nowego pliku symboli przez .symopt+ 0x40. Daje to szansę, aby wydobyć więcej ze składowisk, które już posiadasz.

  3. Użyj przedłużaczy windbg do ciężkiego podnoszenia. W numerze other StackOverflow answers wspomniałem o narzędziu o nazwie CMKD, które kilka razy uratowało mi boczek. Między innymi próbuje rekonstruować argumenty z konwencji wywoływania x64, które zostały przekazane w rejestrach. Nie jest to pewne, ale prawdopodobnie jest to najlepsza nadzieja na odzyskanie ich.

W każdym razie, mam nadzieję, że moje podpalenia okażą się pomocne w debugowaniu.

+0

Wydaje się, że CMKD wykonuje swoją pracę :) Spróbuję tego/Opcja Zo też – paulm

+1

Powinieneś zdecydowanie dodać/Zo, aby uzyskać lepsze śledzenie mieszkańców. Działa to szczególnie dobrze podczas debugowania z windbg (pokazuje onlining), ale działa również z VC++. Jest kilka zastrzeżeń - mój blog obejmuje je: https://randomascii.wordpress.com/2013/09/11/debugging-optimized-codenew-in-visual-studio-2012/ –

Powiązane problemy