Qu'est-ce que IRQL_NOT_LESS_OR_EQUAL exactement? Qu'est-ce que l'IRQL? Quelles choses utilisent IRQL? Pourquoi doit-il être inférieur ou égal? Qu'est-ce qui ferait en sorte qu'il ne soit pas inférieur ou égal? Pourquoi le système d'exploitation ne peut-il pas s'en remettre s'il n'est pas inférieur ou égal? IRQL affecte-t-il uniquement Windows?
Cette erreur semble être assez courante . Je ne demande pas d'aide, je demande une explication.
Réponses:
C'est compliqué. ;)
Non, vraiment, ça l'est.
IRQL signifie "Interrupt Request Level". Il s'agit d'un nombre allant de 0 à 31 sur les systèmes Windows x86 et de 0 à 15 sur les systèmes x64. Il représente "l'importance" d'une tâche en mode noyau par rapport aux autres tâches en mode noyau.
IRQL est un état du processeur défini par Windows - pas d'un processus ou d'un thread - qui indique à Windows si quoi que ce soit que ce processeur fait peut être interrompu par d'autres tâches. Si une nouvelle tâche (telle qu'une routine de service d'interruption) a un IRQL supérieur à l'IRQL actuel du processeur, alors oui, elle peut interrompre la tâche en cours; sinon non. Sur un système multiprocesseur, chaque processeur possède son propre IRQL. Cela inclut les «processeurs logiques» créés par hyperthreading.
(J'utilise le mot "importance" plutôt que "priorité" parce que "priorité" dans Windows fait référence aux priorités des threads et les IRQL sont quelque chose de différent. Contrairement aux priorités des threads, les tâches du noyau sur le même IRQL ne sont pas découpées en temps et les IRQL ne sont pas '' t soumis à un boost et à une décroissance automatiques.)
(Je dois également mentionner que le terme "tâche du noyau" n'est pas officiel ici. Windows n'appelle pas vraiment ces choses "tâches du noyau", ce ne sont pas des objets gérés comme le sont par exemple les processus et les threads, et il n'y a pas de relation avec la tâche x86 " gates "ni à tout ce qui est affiché dans" Task Manager ". Comme moi (et d'autres) j'utilise le terme ici," tâche en mode noyau "couvre vraiment" tout ce qui a un début et une fin définis qui doit être fait en mode noyau à IRQL 2 ou ci-dessus. "Une routine de service d'interruption est un exemple d'une" tâche en mode noyau "; il en va de même pour une routine DPC. Mais un autre exemple peut être du code dans un thread en mode noyau. Ces threads commencent à IRQL 0, mais s'ils font partie du code soulèvevers IRQL 2 ou supérieur, fait quelque chose, puis revient à son IRQL précédent, la partie haute IRQL du code est un exemple de ce que j'appelle une "tâche du noyau" ici. )
Le Moniteur de performances affiche le temps passé à IRQL 2 en tant que «% temps DPC» et le temps à IRQL> 2 en tant que «% temps d'interruption», indépendamment du fait que le temps a été réellement passé dans une routine DPC ou ISR ou était le résultat de l'augmentation d'IRQL à partir de une valeur inférieure. Chacun est un sous-ensemble de ce que PerfMon affiche comme "% de temps privilégié" - qui aurait dû être étiqueté "temps en mode noyau".
Une fois qu'une tâche du noyau est démarrée sur IRQL 2 ou supérieur, elle s'exécute jusqu'à ce que toute autre opération sur le même IRQL soit lancée sur le même processeur. Il peut être interrompu par une tâche IRQL supérieure (qui pourrait à son tour être interrompue par une tâche IRQL encore plus élevée, etc.), mais lorsque les tâches IRQL supérieures sont terminées, le contrôle revient à la tâche qu'il a interrompue.
IRQL est principalement un mécanisme de sérialisation . (Beaucoup disent "synchronisation", mais je préfère ce mot car il décrit plus exactement le résultat.) Son but est d'aider à garantir que plusieurs tâches sur le même CPU qui accèdent à certaines ressources partagées - principalement des structures de données partagées dans l'espace du noyau du système d'exploitation - ne sont pas autorisés à s'interrompre les uns les autres de manière à corrompre ces structures.
Par exemple, une grande partie des données du noyau Windows, en particulier les données de gestion de la mémoire et les données utilisées par le planificateur de threads, sont "sérialisées" à IRQL 2. Cela signifie que toute tâche qui souhaite modifier ces données doit s'exécuter à IRQL 2 quand il le fait. Si une tâche IRQL supérieure tente d'écrire de telles données, cela pourrait entraîner une corruption, car elle pourrait avoir interrompu une tâche IRQL 2 qui pourrait être au milieu d'un cycle de lecture-modification-écriture sur ces mêmes données. Les tâches avec un IRQL supérieur ne sont donc tout simplement pas autorisées à le faire.
Les tâches à IRQL supérieur sont principalement les routines de service d'interruption des pilotes de périphérique, car toutes les interruptions des périphériques se produisent à IRQL> 2. Cela comprend l'interruption de la puce de minuterie sur la carte mère qui pilote le chronométrage et l'activité temporelle dans le système d'exploitation. Son IRQL est supérieur à celui de tous les périphériques matériels "ordinaires".
Les IRQL 2 et supérieurs sont utilisés pour les tâches du noyau qui ne sont pas déclenchées par des interruptions matérielles mais pendant lesquelles la planification normale des threads - y compris l'attente - ne peut pas se produire. Ainsi, une fois qu'un processeur est à IRQL 2 ou supérieur, aucun changement de contexte de thread ne peut se produire sur ce processeur jusqu'à ce que IRQL tombe en dessous de 2.
Le code en mode utilisateur est toujours à IRQL 0. Le code en mode noyau peut s'exécuter sur n'importe quel IRQL de 0 à la valeur maximale. IRQL 1 est un cas particulier; il est uniquement en mode noyau mais n'a aucun impact sur la planification, et est vraiment plus un état d'un thread que du processeur - il est enregistré et restauré lors des changements de contexte de thread, par exemple.
Afin de maintenir diverses garanties de sérialisation, la plupart des exceptions (des choses comme la division par zéro ou des violations d'accès à la mémoire comme des défauts de page) ne sont tout simplement pas gérables à IRQL 2 ou supérieur. (IRQL 2 btw est communément appelé "niveau de répartition" ou "niveau DPC".)
Et maintenant, nous pouvons enfin expliquer ce code bugcheck!
Le cas le plus courant d'IRQL_NOT_LESS_OR_EQUAL est dû à une erreur de page (tentative d'accès à une adresse virtuelle "non résidente"), ou à une violation d'accès à la mémoire (tentative d'écriture sur une page en lecture seule ou d'accès à une page non définie) du tout), qui se produit à IRQL 2 ou supérieur.
Si de telles exceptions sont déclenchées à IRQL 0 ou 1, elles peuvent être "gérées" soit par du code fourni par le système (comme le gestionnaire de défauts de page), soit par un gestionnaire d'exceptions fourni par le développeur. Cependant, la plupart des exceptions ne peuvent pas être gérées du tout si elles se sont produites à IRQL 2 ou supérieur.
Donc ... le code de vérification d'erreur signifie "une exception d'un type qui ne peut être géré qu'à IRQL 0 ou 1 s'est produite lorsque IRQL était à 2 ou plus." c'est-à-dire "pas inférieur ou égal à 1". Étrange formulation, mais elle est là.
Il y a quelques autres choses qui peuvent déclencher cette vérification de bogue, et la valeur à laquelle l'IRQL n'est pas inférieur ou égal n'est pas toujours 1, mais elles ne se produisent que rarement. La documentation WinDBG les répertorie.
la source