Je débogue un vidage sur incident 64 bits C ++ (géré) (violation d'accès).
Le vidage a une taille totale de 32,374,535 Ko.
L'application est multithread , et la pile d'appels correspondante ne mentionne que mscvrt.dll! memcpy
(je ne sais pas quel autre thread crée celui-ci). Il n'y a évidemment pas de code source correspondant.
La fenêtre Visual Studio Locals
est vide.
L'exception non gérée mentionne Emplacement d'écriture de violation d'accès 0x000000F02A6BB000 , mais à cet emplacement, il semble n'y avoir rien:
0x000000F02A6BAF84 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .............................................................. 0x000000F02A6BAFC2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .............................................................. 0x000000F02A6BB000 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? .............................................................. <= here it is. 0x000000F02A6BB03E ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ..............................................................
Je ne vois aucune raison pour laquelle l'écriture sur cet emplacement mémoire poserait un problème, donc Je crois (en fonction de la taille du vidage) que je suis confronté à une erreur de mémoire (ce qui signifie qu'il serait impossible de copier quelque chose en mémoire, car tellement de mémoire est déjà utilisée qu'il n'y a plus de place). Cependant, si cela était vrai, ne devrait-il pas y avoir des informations dans cet emplacement de mémoire?
Quelqu'un a-t-il une idée à ce sujet?
3 Réponses :
Sans voir le code source, il n'y a aucun moyen de savoir ce qu'il pourrait faire s'il rencontre une erreur de mémoire insuffisante. Il y a certainement beaucoup de programmes qui ne vérifient pas chaque allocation de mémoire pour l'échec et leur code pourrait complètement dérailler en conséquence.
Le résultat le plus courant d'une erreur de mémoire insuffisante qui n'est pas vérifiée est une violation d'accès, mais c'est généralement à une adresse qui est soit très petite, soit qui contient un motif évident non logique. En effet, de nombreuses fonctions d'allocation de mémoire renvoient zéro lorsqu'elles sont à court de mémoire et un échec de vérification peut entraîner l'accès à une adresse proche de la valeur renvoyée. En outre, certaines fonctions laissent le résultat non initialisé et renvoient une erreur distincte. Ne pas vérifier cette erreur peut entraîner l'utilisation de la valeur non initialisée pour accéder à la mémoire et cela semble généralement très étrange.
Ici, l'adresse semble raisonnable. Mais qui sait. Peut-être que le code alloue un nouveau tampon, libère l'ancien et change l'ancienne adresse pour la nouvelle mais, en cas d'erreur, ne change pas d'adresse mais libère l'ancienne adresse, provoquant un accès après libre. Sans le code source, il n'y a aucun moyen de le savoir.
Il est en effet possible qu'une violation d'accès soit en fait une erreur de mémoire insuffisante (ou autre type d'erreur liée à la mémoire), comme mentionné dans les commentaires de Scheff et Peter.
Dans ce cas particulier, la grande taille du vidage (± 33 Go) indique que l'application (avec d'autres applications) pourrait consommer trop de mémoire.
Intuitivement, cela ne me semble pas être une erreur de mémoire insuffisante. Les services du système d'allocation de mémoire sur certains systèmes d'exploitation mal conçus renverront des valeurs avec succès lorsqu'ils n'ont pas alloué la mémoire. Autant de défauts que Windoze a, je ne pense pas que ce soit un tel système. Si vous fonctionniez sur un système qui effectue une sorte d'allocation différée, alors je soupçonnerais ce que vous soupçonnez.
Il me semble que vous obtenez un dépassement de mémoire qui provoque une écriture sur une page qui n'a pas été mappée dans l'espace d'adressage.
Ecrire dans (ou même lire à partir) de la mémoire que vous ne «possédez» pas conduit à un comportement indéfini . Sans source, il sera vraiment extrêmement difficile de trouver le problème et sa cause. Il sera également quasiment impossible de le réparer de toute façon. Quant à deviner les raisons possibles, peut-être qu'une variable de pointeur local non initialisée a été utilisée?
Tous les
??
me font penser que la mémoire à cette adresse n'appartient pas au processus débogué. (Même le débogueur ne veut pas ou ne peut pas le lire.) Donc, cela ressemble vraiment à une "violation d'accès".@Scheff: Qu'entendez-vous par "n'appartenant pas au processus débogué"? Je pensais que, sous Windows, chaque processus a la permission d'utiliser chaque morceau de mémoire libre pour faire son travail, sans limitation (sauf lorsque l'ordinateur manque de mémoire, bien sûr). Pouvez-vous le confirmer et où puis-je trouver des informations à ce sujet?
La mémoire peut être protégée en écriture. De plus, si la seule chose sur la pile d'appels est
memcpy
, vous avez probablement très mal écrasé la pile.Définitivement pas. Chaque processus doit demander des blocs de mémoire au système d'exploitation (le noyau Windows). Ensuite, il peut accéder en lecture / écriture exclusivement à cette mémoire. Les autres parties de la mémoire globale doivent être inaccessibles. C'est pour la protection des processus les uns contre les autres. Wikipédia: protection de la mémoire
@Scheff: nous pourrions donc avoir la situation suivante ici: certaines applications utilisent beaucoup de mémoire. Une application veut en utiliser davantage (alors qu'elle utilise déjà pas mal de mémoire). Pour ce faire, il souhaite réserver un bloc de mémoire à partir du noyau du système d'exploitation. Cependant, il n'y a plus de blocs disponibles et l'application se bloque. Dans ce cas, ne devrais-je pas obtenir une erreur
Mémoire insuffisante
au lieu d'une violation d'accès?Yepp - mémoire insuffisante. Cependant, il existe plusieurs façons de gérer le manque de mémoire - lever une exception, se souvenir simplement d'un pointeur nul ou essayer d'utiliser l'adresse sans vérifier. Ce dernier est bon pour la violation d'accès mais la valeur d'adresse pas si mauvaise ne ressemble pas à ceci. Peut-être qu'il s'agit d'un accès hors limite qui s'est produit juste à la fin de l'espace d'adressage accordé. Cependant, tout est supposé sans plus de détails ...
@Dominique - cela dépend de beaucoup de choses. Si un programme ne vérifie pas si une allocation réussit et tente quand même d'utiliser la mémoire, l'utilisation de la mémoire peut entraîner une violation d'accès. La cause d'une violation d'accès, ainsi que d'autres symptômes liés à l'arrêt anormal du programme, est souvent le système d'exploitation qui détecte un programme accédant à quelque chose qu'il ne devrait pas (par exemple, la mémoire que le système d'exploitation n'a pas fournie à ce programme), puis arrête de force le programme.
Quand j'ai manqué de mémoire sur Windows la dernière fois, cela avait l'air très différent: au début, tout est devenu très lent lorsque le système a commencé à échanger des pages de mémoire. Enfin, la surcharge était si lourde que même le pointeur de la souris s'est arrêté pour bouger. Après avoir attendu un peu, tout le système ne répondait absolument pas (même s'il faisait toujours des choses sans interruption avec le disque dur) et j'ai éteint l'ordinateur. :-)
Scheff et Peter: merci beaucoup pour vos réponses très rapides. Il est maintenant clair pour moi que le vrai problème ici n'est pas la violation d'accès, mais le simple fait que mon programme est allé si haut dans l'utilisation de la mémoire. Je conseillerai aux ingénieurs d'exploitation de surveiller de près ce programme et une fois que la consommation de mémoire est trop élevée, un vidage de mémoire temporaire doit être effectué afin de voir si cette consommation de mémoire peut être réduite. Scheff, si vous résumez vos commentaires en une réponse, je l'accepterai.
Merci pour l'offre, mais je pense que cela ne vaut pas une bonne réponse car il manque un problème clair à résoudre. C'est beaucoup de devinettes. Cependant, si je pouvais aider à clarifier les choses, j'en suis satisfait. ;-)
Dans l'état actuel des choses, la question sera probablement close en raison d'un manque d ' exemple minimal reproductible , je vous suggère de fournir une.