Tworzenie zrzutów procesu przez WER-a
• tech • 728 słów • 4 minuty czytania
Czasami debugowanie wywalającego się programu jest uciążliwe a nawet bolesne. Ostatnio sam miałem taki paskudny problem z pewną aplikacją UWP (fuuu!). A był to Edge, w którym proces potomny workera (a może renderera lub cokolwiek innego z sufiksem CP w nazwie) notorycznie się wywalał przy stracie, przez co cała aplikacja wylatywała szybko w kosmos. A wszelkie metody podpięcia się debugerem lub próby przechwycenia momentu wyrzucenia wyjątku zawodziły.
W wielu takich okolicznościach problem rozwiązuje ustawienie debuggera jako post-motern[1], bądź skorzystanie z dobrodziejstw Image File Execution Options[2], ewentualnie standardowo odpalać aplikację wraz z debuggerem[3]. Niestety w moim przypadku wszystkie te metody nie przynosiły efektu, bo albo były ignorowane i WER nadal informował mnie “że coś złego się właśnie stało…”, albo aplikacja z podpiętym debuggerem dziwnie się zachowywała lub po prostu wywalała się na dzień dobry… nim dochodziłem do prawdziwego problemu.
W takiej beznadziejnej sytuacji zacząłem się zastanawiać czy może sam szanowny Windows Error Reporting (WER) nie mógłby mi tutaj pomoc i wygenerować dumpa przy crashu, zamiast swojego marudzenia. Okazało się, że jest taka możliwości, trzeba tylko pogrzebać w rejestrze, bo domyślnie taka funkcjonalność jest wyłączona.
Włączenie i skonfigurowanie tej funkcji wymaga dodania klucza LocalDumps
w rejestrze:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps]
wraz z ustawieniem kilku wartości, z czego najważniejsze to DumpType
określające rodzaj tworzonego zrzutu pamięci:
0 - Custom dump
1 - Mini dump
2 - Full dump
Domyślnie pliki będą zapisywane w katalogu %LOCALAPPDATA%\CrashDumps
, ale ścieżkę do miejsca przechowywania można również ustawić na dowolnie inną w DumpFolder
. Więcej informacji do znalezienia w dokumentacji WER-a: Collecting User-Mode Dumps.
Moja szybka konfiguracja na maszynie testowej ograniczyła się tylko do tych opisanych wyżej dwóch wartości:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps]
; DumpFolder = C:\dumps\
"DumpFolder"=hex(7):43,00,3a,00,5c,00,64,00,75,00,6d,00,70,00,73,00,5c,00,00,00,00,00
; DumpType = Full
"DumpType"=dword:00000002
dzięki czemu wreszcie dostałem swój wyczekiwany dump do analizy ;)
To są ustawienia globalne, ale WER umożliwia ograniczenie lub nadpisanie tej konfiguracji dla wybranej aplikacji, trzeba tylko specyficzne wartości zapisać w pod-kluczu z nazwą aplikacji/pliku wykonywalnego, na przykład: ...\LocalDumps\calc.exe
.
Na koniec mała ciekawostka, mianowicie standardowy Menedżer zadań Windows (Task Manager) także potrafi utworzyć obraz zrzutu procesu… w menu kontekstowym na liście procesów widnieje opcja Utwórz plik zrzutu (Create Dump File). No kto by pomyślał ;)
[[1]](#r1)
Zaszyta w systemie opcja Automatic Debugging umożliwia automatyczne uruchomienie i podłączenie debuggera do problematycznego procesu już w chwili wystąpienia sytuacji wyjątkowej (Post Mortem Debugging). W roli Post Mortem Debugger można wykorzystać dowolny debugger, na przykład WinDbg, i od razu przy crashu zacząć szukać przyczyn wystapienia problemu lub inne narzędzie, na przykład ProcDump, i zrzucać sobie pamięć procesu do pliku do późniejszej analizy.
Dane o ustawionym narzędziu i konfiguracji zachowane są w rejestrze w kluczu:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\]
Ścieżka do debuggera zapisana jest w Debugger
i dla przykładowego WinDbg może wyglądać tak:
"<Path>\WinDbg -p %ld -e %ld -g"
Większość debuggerów i podobnych narzędzi mogących pracować w roli Post Mortem Debugger posiada odpowiednie funkcje (w menu lub dostępne z linii poleceń), które umożliwiają szybką i łatwą rejestrację tool-a w systemie, więc nie trzeba samemu ręcznie grzebać.
Z danych tych korzysta WER kiedy coś złego się wydarzy i to on fizycznie odpala proces debuggera, oczywiście o ile został takowy przypisany. Działanie automatycznego debugowania też w jakimś stopniu można konfigurować - Configuring Automatic Debugging.
[[2]](#r2)
Systemowy mechanizm Image File Execution Options (IFEO) wykorzystywany przy debugowaniu zawiera wiele ciekawych funkcji. Jedną z najczęściej wykorzystywanych opcji jest przypisanie do danej aplikacji debuggera, który będzie uruchamiany wraz ze startem procesu programu.
Ustawienie debuggera dokonuje się przez podanie ścieżki w polu Debugger
w konfiguracji IEFO, które znajdują się w rejestrze i są “pogrupowane” w pod-kluczach dla każdej aplikacji w gałęzi:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\]
Przypisanie WinDbg do systemowego kalkulatora mogłoby zatem wyglądać tak:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\calc.exe]
"Debugger"="<Path>\WinDbg.exe"
Image File Execution Options zawiera wiele ciekawych i przydatnych opcji, a dodatkowo nie trzeba konfiguracji dokonywać poprzez ręczną edycję rejestru - istnieje do tego specjalny program gflags
, z którego można skorzystać.
[[3]](#r3)
Uruchomienie aplikacji UWP jest nieco odmienne od innych typowych programów Win32 i plików wykonywalnych PE. O ile w .net był to prawie zwykły PE z odpowiednim EntryPointem, to przy UWP jest znacznie więcej zabawy. A tym samym skutkuje to tym, że próba uruchomienia aplikacji spod debuggera nie należy do prostych i oczywistych rzeczy.
Na szczęście WinDbg wzbogacił się o taką możliwość:
windbg.exe -plmPackage <PLMPackageName> -plmApp <ApplicationId> [<parameters>]
Szczegóły w dokumentacji debuggera: Debugging a UWP app using WinDbg.
Komentarze (0)