Zine.net online

Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc
w Szukaj

mgrzeg.net - Admin on Rails :)

Rozwiązywanie problemów z mscordacwks

Tym razem kilka słów o dosyć często pojawiającym się problemie, który miałem opisać wieki temu, ale inne wpisy jakoś zawsze okazywały się ciekawsze, ważniejsze i mniej udokumentowane. Przy okazji będę mógł zachęcić do zainteresowania się biblioteką procdumpext.dll, która wiele rzeczy bardzo usprawnia.

Analizując zrzuty pamięci przygotowane na innym komputerze nietrudno trafić na sytuację, gdy środowisko uruchomieniowe różni się od naszego i wówczas może się okazać, że nie będziemy w stanie korzystać z możliwości udostępnianych przez sos.dll, psscor2.dll, sosex.dll, czyli bibliotek wspierających analizę aplikacji .NET. Aby temu zaradzić, musimy dostarczyć debuggerowi odpowiednią wersję biblioteki mscordacwks.dll.
Weźmy prosty przykład.

1. Ładujemy zrzut pamięci do windbg
W tym miejscu polecam przygotowanie sobie skojarzenia w eksploratorze dla plików .dmp (.hdmp, .mdmp) z windbg, który z automatu załaduje nam rewelacyjną bibliotekę rozszerzeń Andrew Richardsa -  procdumpext.dll. Poza usprawnieniami typu ustawienie .prefer_dml na 1, co pozwala na wykorzystanie dml (linki) podczas analizy, biblioteka ta próbuje z automatu ustalić debuggowaną wersję clr oraz ładuje sosex, psscor(x) i sos odpowiednie dla analizowanego zrzutu. Odpowiedni plik .reg oraz procdumpext.dll są do pobrania z dysku skydrive Andrew Richardsa: http://sdrv.ms/11C7S9c
Jeśli nam to nie będzie odpowiadać, to wystarczy, że ustawimy odpowiednią zmienną środowiskową, aby zmienić to zachowanie:

0:000> !procdumpext.help
[CIAP]
  !loadsos        - Runs .cordll and .loadby sos
  !loadpsscor     - Runs .cordll and .load psscor2/4
  !loadsosex      - Runs .cordll and .load sosex
                  - Note, sosex is loaded with sos or psscor2/4

  Define PROCDUMPEXT_LOADCORDLL to choose the extension at load
                  0 = Disabled
                  1 = SOS + SOSEX
                  2 = PSSCORx + SOSEX (default)

2. Mając załadowany zrzut oraz zestaw bibliotek (sosex, psscorx, sos) próbujemy np. dowiedzieć się czegoś o stosie wywołań:

0:000> !mk
Thread 0:
Unable to initialize .NET data interface. Version 2.0.50727.5472 of mscordacwks.dll is required.
Locate and load the correct version of mscordacwks.dll. See documentation for the .cordll command.

lub wyjątkach:

0:000> !pe
Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
            2) the file mscordacwks.dll that matches your version of mscorwks.dll is
                in the version directory
            3) or, if you are debugging a dump file, verify that the file
                mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
            4) you are debugging on the same architecture as the dump file.
                For example, an IA64 dump file must be debugged on an IA64
                machine.

You can also run the debugger command .cordll to control the debugger's
load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.
If that succeeds, the PSSCOR command should work on retry.

If you are debugging a minidump, you need to make sure that your executable
path is pointing to mscorwks.dll as well.

Postępując zgodnie z sugestią, uruchamiamy .cordll:

0:000> .cordll -ve -u -l
CLRDLL: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscordacwks.dll:2.0.50727.5456 f:0
doesn't match desired version 2.0.50727.5472 f:0
CLRDLL: Unable to find mscordacwks_AMD64_AMD64_2.0.50727.5472.dll by mscorwks search
CLRDLL: Unable to find 'mscordacwks_AMD64_AMD64_2.0.50727.5472.dll' on the path
CLRDLL: Unable to get version info for 'c:\websymbols\mscorwks.dll\5174DDB399d000\mscordacwks_AMD64_AMD64_2.0.50727.5472.dll', Win32 error 0n87
Cannot Automatically load SOS
CLRDLL: ERROR: Unable to load DLL mscordacwks_AMD64_AMD64_2.0.50727.5472.dll, Win32 error 0n87
CLR DLL status: ERROR: Unable to load DLL mscordacwks_AMD64_AMD64_2.0.50727.5472.dll, Win32 error 0n87
0:000> !error 0n87
Error code: (Win32) 0x57 (87) - Parametr jest niepoprawny.

Wygląda zatem na to, że debugger nie może znaleźć pliku mscordacwks.dll odpowiadającego obecnemu w zrzucie mscorwks.dll. Plik mscordacwks.dll stanowi pomost pomiędzy natywnym debuggerem, jakim jest windbg, a konkretną wersją mscorwks.dll i bez niego sos, sosex, psscor nie są w stanie nic zrobić.

3. Dostarczenie odpowiedniej wersji mscordacwks.
Tu mamy kilka możliwości. Po pierwsze - prosimy osobę, która dostarczyła nam zrzut, aby podesłała odpowiedni plik ze swojego systemu. Idealnie, gdy mamy dostęp do zdalnego systemu, ale dosyć marzeń - nierzadko trzeba podać szczegółową instrukcję, co może stanowić pewien problem.
Druga opcja, to pobranie odpowiedniej wersji biblioteki z Microsoftu. Wykorzystując ulubioną wyszukiwarkę dosyć szybko trafiamy na odpowiedni link (w omawianym przypadku: http://support.microsoft.com/kb/2833946/pl). Ściągamy odpowiedni plik (w naszym przypadku będzie to Windows6.1-KB2833946-x64.msu) i wypakowujemy zawartość (tu do utworzonego katalogu msu):

>expand -F:* Windows6.1-KB2833946-x64.msu msu
Narzędzie rozwijania plików Microsoft (R) wersja 6.1.7600.16385
Copyright (c) Microsoft Corporation. Wszelkie prawa zastrzeżone.

Dodawanie pliku .\WSUSSCAN.cab do kolejki rozpakowywania
Dodawanie pliku .\Windows6.1-KB2833946-x64.cab do kolejki rozpakowywania
Dodawanie pliku .\Windows6.1-KB2833946-x64-pkgProperties.txt do kolejki rozpakowywania
Dodawanie pliku .\Windows6.1-KB2833946-x64.xml do kolejki rozpakowywania

Trwa rozpakowywanie plików...

Rozpakowywanie plików ukończone...
Ogółem plików: 4.

I dalej (przechodzimy do msu i wypakowujemy do utworzonego podkatalogu cab)

>expand -F:* Windows6.1-KB2833946-x64.cab cab
[CIAP]

Znajdujemy interesujący nas plik (tu mamy dwa o tej samej nazwie, jednak w interesującej nas wersji 2.0.50727.5472 znajduje się w katalogu amd64_netfx-mscordacwks_b03f5f7f11d50a3a_6.1.7601.18140_none_b7d3fac0af07f3ae)

4. Ładujemy mscordacwks i używamy poleceń z bibliotek rozszerzeń
- zgodnie z oczekiwaniem .cordll zmieniamy nazwę pliku na mscordacwks_AMD64_AMD64_2.0.50727.5472.dll, kopiujemy do c:\debuggers;
- powtarzamy próbę załadowania mscordacwks przy użyciu .cordll

0:000> .cordll -ve -u -l
CLRDLL: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscordacwks.dll:2.0.50727.5456 f:0
doesn't match desired version 2.0.50727.5472 f:0
CLRDLL: Unable to find mscordacwks_AMD64_AMD64_2.0.50727.5472.dll by mscorwks search
CLRDLL: Unable to find 'SOS_AMD64_AMD64_2.0.50727.5472.dll' on the path
Cannot Automatically load SOS
CLRDLL: Loaded DLL mscordacwks_AMD64_AMD64_2.0.50727.5472.dll
CLR DLL status: Loaded DLL mscordacwks_AMD64_AMD64_2.0.50727.5472.dll

Od teraz możemy bez problemu używać wszystkich możliwości dostępnych w bibliotekach rozszerzeń:

0:000> !pe
Exception object: 00000000027451d8
Exception type: System.NotSupportedException
Message: Kultura 'pl'  to kultura neutralna. Nie można użyć jej do formatowania ani do analizowania i dlatego nie można jej ustawić jako kultury bieżącej wątku.
InnerException: <none>
StackTrace (generated):
    SP               IP               Function
    000000000029DF10 000007FEF2BF705A System.Globalization.CultureInfo.CheckNeutral(System.Globalization.CultureInfo)
    000000000029DF50 000007FEF225CB84 System.Globalization.CultureInfo.get_NumberFormat()
    000000000029DFA0 000007FEDAB722E8 System.Windows.Forms.NativeWindow+WindowClass.GetFullClassName(System.String)
    000000000029DFF0 000007FEDAB71E76 System.Windows.Forms.NativeWindow+WindowClass.RegisterClass()
    000000000029E0F0 000007FEDAB71C83 System.Windows.Forms.NativeWindow+WindowClass.Create(System.String, Int32)
    000000000029E160 000007FEDAB714E1 System.Windows.Forms.NativeWindow.CreateHandle(System.Windows.Forms.CreateParams)
    000000000029E330 000007FEDAB7115B System.Windows.Forms.Control.CreateHandle()
    000000000029E440 000007FEDAB6F4E9 System.Windows.Forms.Application+ThreadContext.get_MarshalingControl()
    000000000029E4A0 000007FEDAB6EF25 System.Windows.Forms.WindowsFormsSynchronizationContext..ctor()
    000000000029E4E0 000007FEDAB6EE6C System.Windows.Forms.WindowsFormsSynchronizationContext.InstallIfNeeded()
    000000000029E530 000007FEDAB6D91D System.Windows.Forms.Control..ctor(Boolean)
    000000000029E680 000007FEDAB7ABB5 System.Windows.Forms.ScrollableControl..ctor()
    000000000029E6F0 000007FEDAB7AA89 System.Windows.Forms.ContainerControl..ctor()
    000000000029E730 000007FEDAB6D3E8 System.Windows.Forms.Form..ctor()
    000000000029E7C0 000007FF001614C0 MotinoinJoy.FormMain..ctor()
    000000000029E800 000007FF00160E9C MotinoinJoy.Program.Main(System.String[])

StackTraceString: <none>
HResult: 80131515

Oczywiście moglibyśmy dostarczyć jeszcze odpowiednią wersję sos.dll, ale biorąc pod uwagę fakt, iż psscor2.dll pokrywa funkcjonalność sos.dll, to możemy się tym nie przejmować i po prostu rozładować bibliotekę sos i używać poleceń z psscor2.dll.

Opublikowane 15 stycznia 2014 18:18 przez mgrzeg

Powiadamianie o komentarzach

Jeżeli chciałbyś otrzymywać email gdy ta wypowiedź zostanie zaktualizowana, to zarejestruj się tutaj

Subskrybuj komentarze za pomocą RSS

Komentarze:

 

dotnetomaniak.pl said:

Dziękujemy za dodanie artykułu - Trackback z dotnetomaniak.pl

stycznia 17, 2014 09:08
 

ssolnica said:

Kiedyś John Robbins pisał, że "analyze -v" ładuje SOSa automatycznie przy dumpach manage'owanych więc jest to jakaś opcja dla tych co nie mają procdumpext-a :)

lutego 5, 2014 11:32

Co o tym myślisz?

(wymagane) 
(opcjonalne)
(wymagane) 

  
Wprowadź kod: (wymagane)
Wyślij

Subskrypcje

W oparciu o Community Server (Personal Edition), Telligent Systems