Wiem, jak generować pliki Crash Dump za pomocą ADPlus lub DebugDiag, ale zastanawiam się, czy istnieje sposób, aby to zrobić na komputerze klienta bez instalowania tych narzędzi ... konkretnie, chciałbym lubię móc skonfigurować moją aplikację (na przykład przy użyciu wartości rejestru), aby wygenerować zrzut awaryjny w przypadku krytycznej awarii. Dokładniej, muszę móc to zrobić z aplikacji C#, ale nie mam nic przeciwko P/Invoke'ing w razie potrzeby. Dzięki!Generowanie automatycznych zrzutów systemu .NET
Odpowiedz
Należy pamiętać, że tworzenie minizrzutu z wnętrza procesu "awaryjnego" (lub nawet wątku) nie jest proste lub może być niedokładne (dotyczy również uwag funkcji).
Poza tym, jeśli twój proces jest w takim gniewie, że możesz potrzebować napisać zrzut awaryjny, cała sytuacja jest zazwyczaj tak mocno podświetlona, że nawet próba utworzenia zrzutu awaryjnego może spowodować kolejną awarię (sytuacje takie jak odłożenie na bok - ale te mogą być jeszcze trudniejsze do "złapania" z obecnego procesu).
"Najlepszą rzeczą, którą możesz zrobić, jeśli nie możesz zainstalować oddzielnych aplikacji w systemach klienta, jest uruchomienie zewnętrznego procesu (który może również zawieść w krytycznych sytuacjach!) I niech to spowoduje awarię awarii z twojego obecnego procesu (patrz Superassert.NET from John Robbins). Możesz nawet posunąć się tak daleko, aby umieścić zewnętrzny plik binarny w zasobach aplikacji, rozpakuj go na starcie (aby zminimalizować awarię krytycznych wersji) na dysku (jeśli się odważysz).
W zależności od rodzaju potrzebnych informacji można dodać procedurę obsługi zdarzenia AppDomain.UnhandledException
? (Wiem, że nie jest to dokładnie to, czego szukasz, ale jest to zdecydowanie dostępne na komputerach klienckich.)
Czy korzystasz z systemu logowania, takiego jak log4net? Zwykle wyłączasz komunikaty poziomu debugowania dla wydania. Możesz jednak pomyśleć o napisaniu specjalnego appendera, który loguje się do pliku tylko w niektórych przypadkach (np. Awarii). Ten program zapisuje najpierw w pamięci podręcznej tylko pierścień, który może być zapisany do pliku, później - uruchamiany na przykład przez wyjątek, jak sugeruje 280Z28.
Mini zrzut jest ** sposób ** bardziej pomocny niż logi. Przechwytuje kompletny stan aplikacji, w tym samym momencie, gdy zostanie rzucony nieprzechwycony wyjątek. Możesz go załadować do debuggera i uzyskać pełną symboliczną informację, wygodnie powiązaną z kodem źródłowym, pełną ścieżkę śledzenia wszystkich wątków, dokładną lokalizację usterki, informacje o załadowanych modułach, pamięć i dowolną liczbę niestandardowych informacji, które chcesz dodać . – IInspectable
Można wywołać funkcję dbghelp.dll
w wydarzeniu AppDomain.UnhandledException
.
W tym zdarzeniu można zrzucić dziennik danych wyjątków .NET i zapisać minidump do pliku.
Istnieje również thread on the MSDN forums, który opisuje podpis P/Invoke i właściwe użycie.
Nie, [nie można tego bezpiecznie zrobić] (http://stackoverflow.com/questions/1134048/generating-net-crash-dumps-automatically/1135666#comment57477239_1237097). 'MiniDumpWriteDump' ** musi ** zostać wywołany z oddzielnego procesu. – IInspectable
Myślę, że jeśli twoja aplikacja zostanie podtworzona, to równie dobrze możesz zrobić ujęcie w pliku mini zrzutu, a co najgorszego, co się stanie, aplikacja się zawiesi? I tak to się dzieje, więc równie dobrze możesz spróbować.
Kod w urządzeniu MSDN forum mentioned by VoiDed wydaje się dość solidny. Potrzebowałem wersję VB.Net tak oto wersję VB dla każdego, kto może jej potrzebować:
Friend Class MiniDump
'Code converted from C# code found here: http://social.msdn.microsoft.com/Forums/en-US/clr/thread/6c8d3529-a493-49b9-93d7-07a3a2d715dc
Private Enum MINIDUMP_TYPE
MiniDumpNormal = 0
MiniDumpWithDataSegs = 1
MiniDumpWithFullMemory = 2
MiniDumpWithHandleData = 4
MiniDumpFilterMemory = 8
MiniDumpScanMemory = 10
MiniDumpWithUnloadedModules = 20
MiniDumpWithIndirectlyReferencedMemory = 40
MiniDumpFilterModulePaths = 80
MiniDumpWithProcessThreadData = 100
MiniDumpWithPrivateReadWriteMemory = 200
MiniDumpWithoutOptionalData = 400
MiniDumpWithFullMemoryInfo = 800
MiniDumpWithThreadInfo = 1000
MiniDumpWithCodeSegs = 2000
End Enum
<Runtime.InteropServices.DllImport("dbghelp.dll")> _
Private Shared Function MiniDumpWriteDump(_
ByVal hProcess As IntPtr, _
ByVal ProcessId As Int32, _
ByVal hFile As IntPtr, _
ByVal DumpType As MINIDUMP_TYPE, _
ByVal ExceptionParam As IntPtr, _
ByVal UserStreamParam As IntPtr, _
ByVal CallackParam As IntPtr) As Boolean
End Function
Friend Shared Sub MiniDumpToFile(ByVal fileToDump As String)
Dim fsToDump As IO.FileStream = Nothing
If (IO.File.Exists(fileToDump)) Then
fsToDump = IO.File.Open(fileToDump, IO.FileMode.Append)
Else
fsToDump = IO.File.Create(fileToDump)
End If
Dim thisProcess As Process = Process.GetCurrentProcess()
MiniDumpWriteDump(thisProcess.Handle, _
thisProcess.Id, _
fsToDump.SafeFileHandle.DangerousGetHandle(), _
MINIDUMP_TYPE.MiniDumpNormal, _
IntPtr.Zero, _
IntPtr.Zero, _
IntPtr.Zero)
fsToDump.Close()
End Sub
End Class
tylko upewnij się solidnie eception obsługiwać połączenia do niego i powinno być stosunkowo bezpieczne.
* "Co najgorszego, co się stanie, twoja aplikacja ulegnie awarii?" * - To nie jest najgorsze, co może się zdarzyć. Znacznie gorszy scenariusz polegałby na tym, że wywołanie 'MiniDumpWriteDump' zakleszczyło twój proces i uniemożliwiło jego zakończenie. Jedną z pierwszych rzeczy, które robi MiniDumpWriteDump, jest zawieszenie wszystkich wątków w procesie. Jeśli nie masz szczęścia, jeden z tych wątków znajdował się w połowie przydzielania pamięci sterty. A gdy 'MiniDumpWriteDump' spróbuje przydzielić pamięć sterty, będzie bez końca czekać na zwolnienie blokady, ale jest trzymane przez zawieszony wątek. Nie możesz bezpiecznie wykonać tego procesu. – IInspectable
Czy możesz zabić proces w tym stanie? Jeśli działa to w 99% wypadków i zakleszczeń w 1%, gdzie wszystko, co musi zrobić użytkownik, to wymuszenie zabójstwa Myślę, że jest to uczciwy handel, zależne od okoliczności. Czy uruchomiłbym nowy proces z powodu awarii procesu? – jcmcbeth
Można skonfigurować system Windows Error Reporting (WER), aby utworzyć zrzut awaryjny w określonym katalogu używając następującego skryptu rejestru:
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps] "DumpFolder"="C:\\Dumps" "DumpCount"=dword:00000064 "DumpType"=dword:00000002 "CustomDumpFlags"=dword:00000000
Zrzut trafi do katalogu C: \ Zrzuca z nazwą, która odzwierciedla nazwa procesu, który się zawiesił. DumpType = 2 daje pełny zrzut pamięci. DumpType = 1 daje mini zrzut. Na komputerach 64-bitowych nie ma potrzeby umieszczania ich w węzłach Wow32.WER używa tylko klucza rejestru innego niż WOW określonego powyżej.
W zależności od rodzaju awarii ta metoda może nie działać. Muszę jeszcze dowiedzieć się, dlaczego i jakich typów awarii się nie złapie. Ktoś?
Jak wspomniano tutaj (http://msdn.microsoft.com/en-us/library/bb787181(VS.85).aspx) Nie wiem, czy to działa dla kodu zarządzanego. – uli78
"Aplikacje obsługujące własne niestandardowe raporty o awariach, w tym aplikacje .NET, nie są obsługiwane przez tę funkcję" –
Próbowałem tego i ** działa dla kodu zarządzanego ** - w moim przypadku testowym było to framework 4.5 . Ale musiałem użyć następującej instrukcji w mojej aplikacji .net: Application.SetUnhandledExceptionMode (UnhandledExceptionMode.ThrowException); –
- 1. Generowanie zrzutów sterty Java JRE7
- 2. Debugowanie zrzutów .NET za pomocą windbg
- 3. Automatyczne generowanie testów jednostki .NET
- 4. Generowanie pliku PDF w .NET
- 5. Generowanie kodu przy użyciu .net
- 6. Przechwytywanie zrzutów zawartości okna przewijania
- 7. Używaj automatycznych narzędzi z README.md
- 8. Wyświetlanie zrzutów rdzenia
- 9. Sprawdzanie pola we wszystkich wystąpieniach zrzutów pamięci
- 10. Tworzenie zrzutów rdzenia na Cygwin
- 11. iOS Zrób kilka zrzutów ekranu
- 12. Schemat sterty zrzutów V8 JavaScript
- 13. Jak używać zrzutów w TWIG?
- 14. Wykonywanie zrzutów wątków w produkcji
- 15. Wykonywanie zrzutów ekranu w Xcode
- 16. Rozproszone porównanie zrzutów z Selenium
- 17. Analizowanie zrzutów wątku procesu java
- 18. Natychmiastowe uruchomienie ognia systemu .net System.Timers.Timer
- 19. Wdrażanie wirtualnego systemu plików w .NET
- 20. "Za dużo prób przekierowań automatycznych" komunikat o błędzie podczas korzystania z httpWebRequest w .NET
- 21. Generowanie podprogramu Fortran z kodekiem SymPy dla systemu równań
- 22. Uruchamianie pliku node.js bez dzienników automatycznych
- 23. Strategia uzyskiwania SQL dla automatycznych migracji
- 24. Czy mogę używać symulatora systemu iOS do tworzenia zrzutów ekranu dla App Store?
- 25. Generowanie kodu C# z Roslyn i .NET Core
- 26. Jak można sprawić, aby klient HTTP NIE wykonał automatycznych przekierowań?
- 27. Automatyczne wykonywanie zrzutów ekranu okna programu
- 28. Przechwytywanie zrzutów pulpitu za pomocą javascript
- 29. Wykonywanie zrzutów ekranu bieżącego ekranu urządzenia
- 30. Symulator iOS nie chce zapisywać zrzutów ekranu
Podczas gdy mądrość jest ostrożna w działaniu podczas awarii aplikacji, dobrze jest także pomyśleć o tym, co robi aplikacja. Jeśli jesteś w produkcji, bądź BARDZO ostrożny - jednak, jeśli piszesz aplikację przetwarzania wsadowego, prawie na pewno lepiej jest utworzyć minizrzutu do celów debugowania później zamiast konieczności czasochłonnego repro. Porady ogólne: zawsze rozważ swoją sytuację przed podjęciem decyzji projektowej i bądź ostrożny wobec zbyt szerokiej porady. – jhclark
@jhclark Całkowicie _nie mam nic przeciwko pisaniu mini/crash-dump; w rzeczywistości, _proper_ dump jest najlepszym narzędziem analizy post mortem, o które można prosić. Ale nie chodzi o to, aby zapisać go z procesu ofiary. Ponieważ jest to ogólnie niewiarygodne. Posiadanie jakiegoś zewnętrznego procesu stróżującego jest drogą do zrobienia (nawet coś takiego jak Sysinternals procdump może zrobić w sytuacjach wewnętrznych). IMHO jest prawdziwe bez względu na rodzaj aplikacji lub próbę osiągnięcia. –