Windows / C++: czy jest możliwe, aby znaleźć wiersz kodu, w którym został wyrzucony wyjątek o " Offset wyjątku"

Jeden z naszych użytkowników ma wyjątek na starcie naszego produktu. Wysłała nam następujący komunikat o błędzie z systemu Windows:

  Problem Event Name:                        APPCRASH
  Application Name:                          program.exe
  Application Version:                       1.0.0.1
  Application Timestamp:                     4ba62004
  Fault Module Name:                         agcutils.dll
  Fault Module Version:                      1.0.0.1
  Fault Module Timestamp:                    48dbd973
  Exception Code:                            c0000005
  Exception Offset:                          000038d7
  OS Version:                                6.0.6002.2.2.0.768.2
  Locale ID:                                 1033
  Additional Information 1:                  381d
  Additional Information 2:                  fdf78cd6110fd6ff90e9fff3d6ab377d
  Additional Information 3:                  b2df
  Additional Information 4:                  a3da65b92a4f9b2faa205d199b0aa9ef

Czy jest możliwe zlokalizowanie dokładnego miejsca w kodzie źródłowym, w którym wystąpił wyjątek z tą informacją?

Jaka jest powszechna technika dla programistów C++ w systemie Windows, aby zlokalizować miejsce błędu, który wystąpił na komputerze użytkownika?

Nasz projekt jest skompilowany z konfiguracją Wydania, plik PDB jest / align = "left" /

Mam nadzieję, że moje pytanie nie jest zbyt naiwne.
Author: Pavel, 2010-03-27

4 answers

Tak, to możliwe. Rozpocznij debugowanie za pomocą dokładnie tych samych plików binarnych, które są uruchamiane przez użytkownika, upewnij się, że DLL jest załadowany i masz dla niego pasujący plik PDB. Poszukaj w Debug + Windows + Modules adresu podstawowego DLL. Dodaj offset. Debug + Windows + Disassembly i wprowadź obliczony adres w polu Adres(prefiks z 0x). To pokazuje dokładną instrukcję kodu maszynowego, która spowodowała wyjątek. Kliknij prawym przyciskiem myszy + przejdź do kodu źródłowego, aby zobaczyć pasujący kod źródłowy Kolejka

Chociaż pokazuje to stwierdzenie, to zazwyczaj nie jest wystarczająco dobre, aby zdiagnozować przyczynę. Wyjątek 0xc0000005 jest naruszeniem dostępu, ma wiele możliwych przyczyn. Często nawet nie dostajesz żadnego kodu, program mógł przeskoczyć w zapomnienie z powodu uszkodzonego stosu. Albo prawdziwy problem znajduje się daleko, jakaś manipulacja wskaźnikiem, która uszkodziła stertę. Zazwyczaj również naprawdę potrzebujesz śledzenia stosu, który pokazuje, jak program zakończył się na stwierdzeniu, że / align = "left" /

Potrzebujesz minidump. Możesz łatwo dostać jeden od użytkownika, jeśli działa Vista lub Win7. Start TaskMgr.exe, Zakładka procesy, wybierz program, który nadal wyświetla okno dialogowe crash. Kliknij prawym przyciskiem myszy i utwórz plik zrzutu.

Aby było to płynne, naprawdę chcesz zautomatyzować tę procedurę. Podpowiedzi znajdziecie w mojej odpowiedzi w tym wątku .

 66
Author: Hans Passant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:11

Jeśli masz minidump, otwórz go w Visual Studio, Ustaw MODPATH do odpowiednich folderów z oryginalnymi binariami i PDB i powiedz, aby "run". Może być również konieczne polecenie, aby załadować symbole z serwerów symboli Microsoft. Wyświetli stos wywołań w miejscu błędu. Jeśli spróbujesz spojrzeć na kod źródłowy dla konkretnej lokalizacji stosu, może on zapytać, gdzie znajduje się Źródło; jeśli Tak, wybierz odpowiedni folder źródłowy. MODPATH jest ustawiany we właściwościach wiersza poleceń debugowania dla "projekt", który ma nazwę pliku minidump.

 4
Author: Permaquid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-27 19:23:17

Wiem, że ten wątek jest bardzo stary, ale to była najlepsza odpowiedź Google, więc chciałem dodać moje $.02.

Chociaż mini-zrzut jest najbardziej pomocny, o ile skompilowałeś kod z włączonymi symbolami (po prostu Wyślij plik bez .pdb, i zachować .pdb!) możesz sprawdzić, która linia to było za pomocą debuggera MSVC lub debuggera Windows. MSN artykuł na że:

Http://blogs.msdn.com/b/danielvl/archive/2010/03/03/getting-the-line-number-for-a-faulting-application-error.aspx

 2
Author: std''OrgnlDave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-08 21:06:29

Informacje o kodzie źródłowym nie są przechowywane w skompilowanym kodzie C++, w przeciwieństwie do języków obsługujących metadane (takich jak. NET lub Java). Plik PDB jest indeksem symboli, który może pomóc debugerowi mapować skompilowany kod wstecz do źródła, ale musi to być zrobione podczas wykonywania programu, a nie z zrzutu awaryjnego. Nawet w przypadku PDB, skompilowany kod Release podlega wielu optymalizacjom, które mogą uniemożliwić debuggerowi identyfikację kodu źródłowego.

Problemy z debugowaniem, które tylko manifestacja na maszynach użytkowników końcowych jest zwykle kwestią starannego rejestrowania stanu i dużo szczegółowego czasu i wysiłku przeczesywania źródła. W zależności od relacji z użytkownikiem (na przykład, jeśli jesteś wewnętrznym korporacyjnym rozwojem IT), możesz być w stanie stworzyć obraz maszyny wirtualnej komputera użytkownika i użyć go do debugowania, co może znacznie przyspieszyć proces, precyzyjnie replikując zainstalowane oprogramowanie i standardowe uruchomione procesy na komputerze użytkownika stacja robocza.

 1
Author: Dan Story,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-27 10:11:10