O que exatamente é IRQL_NOT_LESS_OR_EQUAL? O que é o IRQL? Quais coisas usam o IRQL? Por que precisa ser menor ou igual? O que faria com que não fosse menor ou igual? Por que o sistema operacional não pode se recuperar de não ser menor ou igual? O IRQL afeta apenas o Windows?
Este erro parece ser bastante comum . Não estou pedindo ajuda, estou pedindo uma explicação.
Respostas:
É complicado. ;)
Não é mesmo.
IRQL significa "Nível de Solicitação de Interrupção". É um número, variando de 0 a 31 nos sistemas Windows x86 e 0 a 15 nos sistemas x64. Representa a "importância" de uma tarefa no modo kernel em relação a outras tarefas no modo kernel.
IRQL é um estado definido pelo Windows do processador - não de um processo ou thread - que indica ao Windows se o que esse processador está fazendo pode ou não ser interrompido por outras tarefas. Se uma nova tarefa (como uma rotina de serviço de interrupção) tiver um IRQL maior que o IRQL atual do processador, sim, poderá interromper a tarefa atual; caso contrário não. Em um sistema multiprocessador, cada processador possui seu próprio IRQL. Isso inclui os "Processadores lógicos" criados pelo hyperthreading.
(Eu uso a palavra "importância" em vez de "prioridade" porque "prioridade" no Windows refere-se a prioridades de encadeamento, e os IRQLs são algo diferente. Ao contrário das prioridades de encadeamento, as tarefas do kernel no mesmo IRQL não são fatiadas pelo tempo e os IRQLs não são " sujeito a aumento e deterioração automáticos.)
(Devo também mencionar que o termo "tarefa do kernel" aqui não é oficial. O Windows realmente não chama essas coisas de "tarefas do kernel", elas não são objetos gerenciados como são, por exemplo, processos e threads, e não há relação com a tarefa x86 " gates "nem a qualquer coisa mostrada no" Gerenciador de Tarefas ". Como eu (e outros) usamos o termo aqui," tarefa no modo kernel "realmente cobre" qualquer coisa com um começo e um final definidos que precisam ser executados no modo kernel no IRQL 2 ou "Uma rotina de serviço de interrupção é um exemplo de uma" tarefa no modo kernel "; assim como uma rotina DPC. Mas outro exemplo pode ser código em um thread no modo kernel. Esses threads iniciam no IRQL 0, mas se fazem parte do código levantapara o IRQL 2 ou superior, faz alguma coisa e, em seguida, retorna ao seu IRQL anterior, a parte do código com alto nível de IRQL é um exemplo do que estou chamando de "tarefa do kernel" aqui. )
O Monitor de Desempenho mostra o tempo gasto no IRQL 2 como "% de tempo do DPC" e o tempo no IRQL> 2 como "% de tempo de interrupção", independentemente de o tempo realmente ter sido gasto em uma rotina DPC ou ISR ou foi o resultado do aumento do IRQL de um valor mais baixo. Cada um é um subconjunto do que o PerfMon mostra como "% de tempo privilegiado" - que deveria ter sido rotulado como "tempo do modo do kernel".
Depois que uma tarefa do kernel é iniciada no IRQL 2 ou superior, ela é executada até a conclusão antes que qualquer outra coisa no mesmo IRQL seja iniciada no mesmo processador. Ele pode ser interrompido por uma tarefa de IRQL maior (que por sua vez pode ser interrompida por uma tarefa de IRQL ainda mais alta etc.), mas quando as tarefas de IRQL maior são concluídas, o controle retorna à tarefa que interrompeu.
O IRQL é principalmente um mecanismo de serialização . (Muitos dizem "sincronização", mas eu prefiro essa palavra porque ela descreve mais exatamente o resultado.) Seu objetivo é ajudar a garantir que várias tarefas na mesma CPU acessem determinados recursos compartilhados - principalmente estruturas de dados compartilhadas no espaço do kernel do SO - Não é permitido interromper um ao outro de maneiras que possam corromper essas estruturas.
Por exemplo, uma grande quantidade de dados no kernel do Windows, particularmente os dados de gerenciamento de memória e os dados usados pelo planejador de encadeamentos, é "serializada" no IRQL 2. Isso significa que qualquer tarefa que queira modificar esses dados deve estar em execução no IRQL 2 quando faz isso. Se uma tarefa IRQL superior tentar gravar esses dados, isso poderá causar corrupção, porque pode ter interrompido uma tarefa IRQL 2 que pode estar no meio de um ciclo de leitura, modificação, gravação e gravação nesses mesmos dados. Portanto, tarefas com IRQL superior simplesmente não têm permissão para fazer isso.
As tarefas de IRQL superior são principalmente as rotinas de serviço de interrupção dos drivers de dispositivo, porque todas as interrupções de dispositivos ocorrem no IRQL> 2. Isso inclui a interrupção do chip de timer na placa-mãe que gera a atividade de controle de tempo e de tempo no sistema operacional. Seu IRQL está acima do de todos os dispositivos de hardware "comuns".
Os IRQLs 2 e posteriores são usados para tarefas do kernel que não são acionadas por interrupções de hardware, mas durante as quais o agendamento normal do encadeamento - incluindo espera - não pode ocorrer. Assim, quando um processador estiver no IRQL 2 ou superior, nenhuma alternância de contexto de encadeamento poderá ocorrer nesse processador até que o IRQL fique abaixo de 2.
O código do modo de usuário está sempre no IRQL 0. O código do modo do kernel pode ser executado em qualquer IRQL de 0 a qualquer que seja o máximo. IRQL 1 é um caso especial; é apenas modo kernel, mas não tem impacto no agendamento, e é realmente mais um estado de um encadeamento do que do processador - ele é salvo e restaurado durante as alternâncias de contexto do encadeamento, por exemplo.
Para manter várias garantias de serialização, a maioria das exceções (coisas como dividir por zero ou violações de acesso à memória como falhas de página) simplesmente não são tratáveis no IRQL 2 ou superior. (O IRQL 2 btw é comumente chamado de "nível de despacho" ou "nível DPC".)
E agora podemos finalmente explicar esse código de verificação de bug!
O caso mais comum de IRQL_NOT_LESS_OR_EQUAL é devido a uma falha de página (tentativa de acessar um endereço virtual "não residente") ou uma violação de acesso à memória (tentativa de gravar em uma página somente leitura ou para acessar uma página que não está definida ), que ocorre no IRQL 2 ou superior.
Se essas exceções forem geradas no IRQL 0 ou 1, elas poderão ser "tratadas" pelo código fornecido pelo sistema (como o manipulador de falhas de página) ou por um manipulador de exceções fornecido pelo desenvolvedor. No entanto, a maioria das exceções não pode ser tratada se elas ocorrerem no IRQL 2 ou superior.
Então ... o código de verificação de bug significa "uma exceção de um tipo que só pode ser manipulada no IRQL 0 ou 1 ocorreu quando o IRQL estava em 2 ou superior". ou seja, "não inferior ou igual a 1". Formulação estranha, mas aí está.
Existem algumas outras coisas que podem disparar essa verificação de bug, e o valor que o IRQL não é menor ou igual a nem sempre é 1, mas elas ocorrem apenas raramente. A documentação do WinDBG os lista.
fonte