Parfois, les bugs peuvent causer une exception de violation d'accès à la mémoire.
Comment exactement cette exception est déclenchée? Quel mécanisme fonctionne derrière les scènes? P>
a-t-il besoin de supporter de la CPU (à partir de ce que la CPU?) / Du système d'exploitation (à partir de quelle version?) / Du compilateur (à partir de quelle version?) p>
Un scénario spécifique Je souhaite mieux comprendre: p> Le code suivant peut entraîner une exception d'une violation d'accès. < / p> Je suppose que czxxx pointe sur un bloc de mémoire en lecture seule, mais ce qui se passe exactement? P> P>
6 Réponses :
void Kaboom() { int* certain_death = NULL; *certain_death = 0; }
En fait, votre exemple a un comportement indéfini en fonction de la norme;)
Dans l'architecture X86 (et la plupart des autres aussi), ceci est démarré à partir de la MMU - l'unité de gestion de la mémoire. Le MMU est utilisé pour traduire des adresses de mémoire virtuelles aux adresses de mémoire physique. Si une demande est faite pour accéder à une adresse non valide (0x00000000 ou quelque chose de trop élevé), le MMU piégera (interruption) au système d'exploitation (ceci est fait pour chaque accès non dans la TLB (Traduire le tampon de lookaside - le cache de traduction MMU. "))). Ici, le système d'exploitation sera en mesure de dire qu'il s'agit d'un accès illégal de la mémoire et de se propager à l'application utilisateur via le mécanisme dépendant du système d'exploitation (signaux de Linux (SIGSEGV), je ne connais pas assez de Windows pour dire comment cela se fait en elle). P>
Cette fonctionnalité est disponible pour tout CPU, système d'exploitation et compilateur moderne. L'exigence la plus élémentaire est une MMU, qui est présente dans tous les processeurs intégrés les plus fondamentaux. Je doute que tout PC fonctionne actuellement qui ne supporte pas cela. P>
Après la méthode OP, lorsqu'une chaîne littérale est utilisée, la mémoire est placée dans le segment .Text de l'exécutable. C'est là que le code binaire et les valeurs constants sont assis. Naturellement, dans la plupart des OSS, ceci est en lecture seule (en particulier sous Linux avec diverses améliorations de sécurité). Lorsque vous essayez de changer une valeur d'une chaîne littérale, vous essayez essentiellement d'écrire à une mémoire en lecture seule, ce qui entraîne une violation d'accès. Encore une fois, cela est capturé par le MMU qui voit une commande d'écriture à une adresse mémoire en lecture seule. P>
Le mécanisme dépendant du système d'exploitation est appelé "exceptions structurées" sous Windows: msdn.microsoft.com/en-us/library/ms680657%28v=vs.85%29.aspx
Lorsque vous essayez d'accéder à une adresse mémoire, l'ordinateur passe à travers plusieurs étapes: P>
Si l'adresse n'est pas en mémoire, la CPU générera une exception de vérification de la mémoire. À ce stade, le système d'exploitation prend la relève. P>
Si, à ce stade, la mémoire n'est pas disponible, il existe une des deux possibilités. L'adresse n'est pas disponible, soit vous n'avez pas les autorisations dont vous avez besoin (par exemple, essayer d'écrire en mémoire en lecture seule). Dans ce cas, le système d'exploitation passera la violation d'accès au processus. P>
Quant aux versions CPU et OS, il s'agit d'un système qui permet une mémoire virtuelle. Je ne connais pas les détails de cela. P>
Les violations d'accès à la mémoire sont un gros sujet :) p>
Protection des informations dans les systèmes informatiques (à partir de 1973 :) établie d'un mécanisme de segments em>, où les processus sont attribués à une base em> et a lié em>; Toute tentative d'accès à la mémoire en dehors de la plage La ligne de processeurs 80x86 implémente le support de segment de base et le Gemsos Security Le noyau est un noyau de système d'exploitation certifié A1 basé sur ce mécanisme. P>
Mais les segments ne sont pas très dynamiques, et presque tous les systèmes d'exploitation modernes sont Systèmes de pagination , que page dans la mémoire em> quand il n'est pas disponible. Ceci repose sur la CPU ayant un MMU , unité de gestion de la mémoire, qui vérifie tous les accès à la mémoire pour les privilèges corrects et présence / absence du mappage de mémoire correct. Lorsqu'un processus tente d'accéder à la mémoire qui n'est pas actuellement mappé dans la RAM, le MMU signale la CPU selon laquelle une erreur est survenue et que la CPU suspend le processus de chargement de la page de mémoire demandée à partir du disque. (Ou si la mémoire ne doit pas être mappée pour le processus, disons qu'il tente d'accéder à 80386 Intel a été la première puce Intel à supporter la pagination, laquelle est la raison pour laquelle Windows 3.1's "386 enchante enchanté" était donc em> beaucoup mieux que le mode 286. P>
Les compilateurs ne sont pas vraiment impliqués, mais la CPU, le MMU et le système d'exploitation du noyau doivent em> tous travaillent ensemble. P> base: base + liaison code> signifiait que le programme avait fait quelque chose de stupide et doit être tué. P>
0x0 code> ou à un emplacement de mémoire aléatoire qui n'a pas été mappé avec
MMAP code> ou mémoire similaire alloué des primitives, il tue le processus.) p>
Et si la RAM et le disque sont-ils tous les deux?
@Scott 混合 理论 Il est normal que la RAM soit pleine ou très presque entièrement inutilisée, la RAM est gaspillée. Étant donné que la performance se dégrade, plus l'ordinateur doit utiliser l'espace d'échange, normalement, les gens essaieront de ne exécuter que autant de logiciels que vous intégrerez en mémoire. Une fois que l'espace de swap est plein, le noyau commencera à renvoyer des erreurs pour des allocations de mémoire ou tuera des processus entiers pour libérer de l'espace. Recherchez "Oom Killer" pour plus de détails à ce sujet.
La violation de l'accès à la mémoire peut se produire ici également:
delete pSample; //again deleting the same memory! delete pSample;
Toutes ces réponses expliquent très bien ce qui se passe très bien au niveau du processeur. Comme mentionné, une fois que le processeur a souligné une interruption au système d'exploitation, les éléments changent avec différents systèmes d'exploitation.
Windows utilise un mécanisme appelé " exceptions structurées ". Très important de ne pas confondre cela avec des exceptions C ++, elles sont différentes. Exceptions structurées conceptuellement forts> fonctionne de la même manière que c ++ exceptions, en ce sens qu'ils détournent la pile à la recherche d'un gestionnaire. Les exceptions structurées étant agnostiques linguistiques, elles font Des exceptions structurées peuvent être capturées avec P> __try
{
//Usual code
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
//Handling code
}
__finally
{
//Cleanup
}