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)

Dodaj komentarz

/dozwolony markdown/

/nie zostanie opublikowany/