Jasica.Net

C#, .Net, SQL i nie tylko

Corupted State Exception

.Net w wersji 4.0 wprowadził pojęcie Corupted State Exception. W odróżnieniu od pozostałych wyjątków, nie są one wyłapywane przez bloki catch/finally. Takie zachowanie ma jak najbardziej sens, gdyż w większości sytuacji stanowią one sygnał, że w programie stało się coś złego i dalsze wykonywanie może nie mieć sensu. Występują one głównie przy współpracy z natywnymi bibliotekami. Poniższe wyjątki mogą być traktowane jako CSE:

  • STATUS_ACCESS_VIOLATION
  • STATUS_STACK_OVERFLOW
  • EXCEPTION_ILLEGAL_INSTRUCTION
  • EXCEPTION_IN_PAGE_ERROR
  • EXCEPTION_INVALID_DISPOSITION
  • EXCEPTION_NONCONTINUABLE_EXCEPTION
  • EXCEPTION_PRIV_INSTRUCTION
  • STATUS_UNWIND_CONSOLIDATE

Przeglądając tą listę możemy zauważyć, że w większości wypadków sugerują one błędy w kodzie natywnym. Poniższy kod C++ generuje błędne odwołanie do fragmentu pamięci, które posłuży jako przykład:

extern "C" __declspec(dllexport) 
int Add(int a, int b)
{
    int * t = 0;
    *t = 1;
    return a + b;
}

Kod tej funkcji w C# można wywołać stosując atrybut DllImport:

[DllImport("test.dll")]
public static extern int Add(int a, int b);

static void Main(string[] args)
{
     try
     {
         int result = Add(1, 2);
         Console.WriteLine(result);
     }
     catch (Exception ex)
     {
         Console.WriteLine("Cath: " + ex.Message + ex.StackTrace);
     }
     finally
     {
         Console.WriteLine("Finally");
     }
     Console.WriteLine("End");
}

Wynik działania powyższego kodu będzie różny w zależności od wybranej wersji CLR. W 4.0 nie wykona się zarówno blok catch jak i finally, natomiast w wcześniejszych wersjach wyjątek zostanie złapany, a program wykona się do końca. Wyjątki tego typu można wyłapywać CLR 4.0 o ile programista świadomie oznaczy metodę atrybutem HandleProcessCorruptedStateExceptions. Może to mieć znaczenie, gdy biblioteka zawiera dobrze znany błąd i nie da się go wyeliminować w danej chwili inaczej. Zachowanie to można wyłączyć także dla całego kodu, bez dokonywania jakikolwiek zmian w nim. Zachowanie kompatybilności wstecz można wymusić dodając wpis w pliku konfiguracyjnym:

<configuration>
    <runtime>
        <legacyCorruptedStateExceptionsPolicy enabled="true"/>
    </runtime>
</configuration>

Corupted State Exception chronią mniej świadomych programistów przed kontynuowaniem wykonywania kodu, gdy aplikacja znalazła się w złym stanie i dalsze operacje mogą prowadzić do utraty bądź uszkodzenia ważnych danych. Niestety, często w aplikacjach znajdują się zbyt ogólne bloki catch, łapiące wyjątki każdego typu, co zamiast zapewniać stabilność aplikacji, mogą prowadzić do nieoczekiwanych rezultatów. CAS chronią przed tego typu błędami i jednocześnie pozwalają wymusić wyłapywanie ich o ile zachodzi taka konieczność przy pomocy wspomnianego wcześniej atrybutu- HandleProcessCorruptedStateExceptions.

Pingbacks and trackbacks (1)+

Dodaj komentarz

Loading