Tratando exceções
O sistema operacional usa o tratamento de exceção estruturado para sinalizar determinados tipos de erros. Uma rotina chamada por um driver pode gerar uma exceção que o driver deve manipular.
O sistema intercepta os seguintes tipos gerais de exceções:
Falhas ou armadilhas definidas por hardware, como,
- Violações de acesso (veja abaixo)
- Desalinhamentos do tipo de dados (como uma entidade de 16 bits alinhada em um limite de bytes ímpares)
- Instruções ilegais e privilegiadas
- Sequências de bloqueio inválidas (tentando executar uma sequência inválida de instruções em uma seção intertravada de código)
- O inteiro é dividido por zero e transborda
- Divisões de ponto flutuante por zero, estouros, fluxos inferiores e operandos reservados
- Pontos de interrupção e execução de etapa única (para dar suporte a depuradores)
Exceções definidas pelo software do sistema, como,
- Violações de página de proteção (tentando carregar ou armazenar dados de ou para um local dentro de uma página de proteção)
- Erros de leitura de página (tentando ler uma página na memória e encontrando um erro de E/S simultâneo)
Uma violação de acesso é uma tentativa de executar uma operação em uma página que não é permitida nas configurações atuais de proteção de página. As violações de acesso ocorrem nas seguintes situações:
Uma operação de leitura ou gravação inválida, como gravar em uma página somente leitura.
Para acessar a memória além do limite do espaço de endereço do programa atual (conhecido como violação de comprimento).
Para acessar uma página que atualmente é residente, mas dedicada ao uso de um componente do sistema. Por exemplo, o código do modo de usuário não tem permissão para acessar uma página que o kernel está usando.
Se uma operação pode causar uma exceção, o driver deverá colocar a operação em um bloco try/except . Os acessos de locais no modo de usuário são causas típicas de exceções. Por exemplo, a rotina ProbeForWrite verifica se o driver pode realmente gravar em um buffer de modo de usuário. Se não puder, a rotina gerará uma exceção STATUS_ACCESS_VIOLATION. No exemplo de código a seguir, o driver chama ProbeForWrite em uma tentativa/exceto para que ele possa lidar com a exceção resultante, se uma ocorrer.
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 */
...
}
Os drivers devem lidar com quaisquer exceções geradas. Uma exceção que não é tratada faz com que o sistema bug marcar. O driver que faz com que a exceção seja gerada deve lidar com isso: um driver de nível inferior não pode contar com um driver de nível superior para lidar com a exceção.
Os drivers podem gerar diretamente uma exceção usando as rotinas ExRaiseAccessViolation, ExRaiseDatatypeMisalignment ou ExRaiseStatus . O driver deve lidar com quaisquer exceções geradas por essas rotinas.
Veja a seguir uma lista parcial de rotinas que, pelo menos em determinadas situações, podem gerar uma exceção:
Os acessos de memória a buffers de modo de usuário também podem causar violações de acesso. Para obter mais informações, consulte Erros em Referência a endereços User-Space.
Observe que a manipulação de exceção estruturada é distinta das exceções do C++. O kernel não dá suporte a exceções C++.
Para obter mais informações sobre o tratamento de exceções estruturadas, consulte o SDK do Microsoft Windows e a documentação do Visual Studio.