Udostępnij przez


Obsługa wyjątków

System operacyjny używa obsługi wyjątków strukturalnych w celu sygnalizowania niektórych rodzajów błędów. Rutyna wywoływana przez kierowcę może zgłosić wyjątek, który kierowca musi obsłużyć.

System wychwytuje następujące ogólne rodzaje wyjątków:

  1. Błędy lub pułapki zdefiniowane przez sprzęt, takie jak

    • Naruszenia dostępu (patrz poniżej)
    • Niezgodność typu danych (na przykład jednostka 16-bitowa wyrównana do nieparzystej granicy bajtów)
    • Niedozwolone i uprzywilejowane instrukcje
    • Nieprawidłowe sekwencje blokady (próba wykonania nieprawidłowej sekwencji instrukcji w sekcji kodu o synchronizowanej blokadzie)
    • Liczba całkowita dzieli się przez zero i przepełnienie
    • Operacje zmiennoprzecinkowe dzielenie przez zero, przepełnienia, niedopełnienia i zarezerwowane operandy
    • Punkty przerwania i wykonywanie jednego kroku (w celu obsługi debugerów)
  2. Wyjątki zdefiniowane programowo systemu, takie jak,

    • Naruszenia strony chronionej (próba wczytania lub przechowywania danych z lub do lokalizacji na stronie chronionej)
    • Błędy odczytu strony (próba odczytania strony w pamięci i napotkanie współbieżnego błędu we/wy)

Naruszenie dostępu to próba wykonania operacji na stronie, która nie jest dozwolona w ramach bieżących ustawień ochrony strony. Naruszenia dostępu występują w następujących sytuacjach:

  • Nieprawidłowa operacja odczytu lub zapisu, taka jak zapisywanie na stronie tylko do odczytu.

  • Aby uzyskać dostęp do pamięci poza limitem przestrzeni adresowej bieżącego programu (nazywane naruszeniem długości).

  • Aby uzyskać dostęp do strony, która jest obecnie rezydentem i przeznaczona do użytku komponentu systemowego. Na przykład kod trybu użytkownika nie może uzyskać dostępu do strony używanej przez jądro.

Jeśli operacja może spowodować wyjątek, sterownik powinien ująć operację w bloku try/except. Dostęp do lokalizacji w trybie użytkownika są typowymi przyczynami wyjątków. Na przykład procedura ProbeForWrite sprawdza, czy sterownik może faktycznie zapisywać w buforze trybu użytkownika. Jeśli nie może, procedura zgłasza wyjątek STATUS_ACCESS_VIOLATION. W poniższym przykładzie kodu sterownik wywołuje ProbeForWrite w try/except, aby móc obsłużyć wynikowy wyjątek, jeśli taki wystąpi.

try {
    ...
    ProbeForWrite(Buffer, BufferSize, BufferAlignment);
 
    /* Note that any access (not just the probe, which must come first,
     * by the way) to Buffer must also be within a try-except.
     */
    ...
} except (EXCEPTION_EXECUTE_HANDLER) {
    /* Error handling code */
    ...
}

Sterowniki muszą obsługiwać wszelkie zgłoszone wyjątki. Wyjątek, który nie jest obsługiwany, powoduje, że system może sprawdzić usterkę. Sterownik, który powoduje zgłaszanie wyjątku, musi go obsłużyć: sterownik niższego poziomu nie może polegać na sterowniku wyższego poziomu do obsługi wyjątku.

Sterowniki mogą bezpośrednio zgłaszać wyjątek, używając procedur ExRaiseAccessViolation, ExRaiseDatatypeMisalignment lub ExRaiseStatus . Sterownik musi obsługiwać wszelkie wyjątki, które zgłaszają te procedury.

Poniżej przedstawiono częściową listę procedur, które przynajmniej w niektórych sytuacjach mogą zgłosić wyjątek:

Dostęp do buforów w trybie użytkownika może również powodować naruszenia dostępu. Aby uzyskać więcej informacji, należy odnieść się do Errors in Referencing User-Space Addresses.

Należy pamiętać, że obsługa wyjątków strukturalnych różni się od wyjątków języka C++. Jądro nie obsługuje wyjątków języka C++.

Aby uzyskać więcej informacji na temat obsługi wyjątków strukturalnych, zobacz zestaw Microsoft Windows SDK i dokumentację programu Visual Studio.