Dans Visual Studio C ++, quelles sont les représentations d'allocation de mémoire?


216

Dans Visual Studio, nous avons tous eu "baadf00d", avons vu "CC" et "CD" lors de l'inspection des variables dans le débogueur en C ++ pendant l'exécution.

D'après ce que je comprends, "CC" est en mode DEBUG uniquement pour indiquer quand une mémoire a été new () ou alloc () et unitilialized. Tandis que "CD" représente la mémoire supprimée ou libérée. Je n'ai vu que "baadf00d" dans la version RELEASE (mais je peux me tromper).

De temps en temps, nous nous retrouvons dans une situation de résolution des fuites de mémoire, des dépassements de mémoire tampon, etc. et ce type d'informations est très pratique.

Quelqu'un serait-il assez aimable pour indiquer quand et dans quels modes la mémoire est définie sur des modèles d'octets reconnaissables à des fins de débogage?



@ Lưu Vĩnh Phúc: Ce n'est pas l'OS, c'est le débogueur. Le "D" (comme sur 0xCD et 0xDD) est pour le débogage (c'est-à-dire que malloc_dbg est ce qui est appelé via malloc comme expliqué dans msdn.microsoft.com/en-us/library/aa270812(v=vs.60).aspx ). Je crois qu'il ajoute également des clôtures / poteaux autour des tas pour suivre les dépassements de tampon. Il est très utile d'attraper des problèmes lorsque vous avez un bogue de double suppression ou de libération multiple (ou même un appel possible de suppression au lieu de supprimer []) et des pointeurs pendants qui ont été supprimés et lorsque vous inspectez les données, c'est "0xDD" (ou lorsque le tas non initialisé affiche 0xCD)
HidekiAI

Je n'ai pas dit que c'était l'OS. C'est l'autre demandeur qui a mal écrit le titre
phuclv

Réponses:


317

Ce lien contient plus d'informations:

http://en.wikipedia.org/wiki/Magic_number_(programming)

* 0xABABABAB: utilisé par HeapAlloc () de Microsoft pour marquer les octets de garde "no man's land" après la mémoire de tas allouée
* 0xABADCAFE: démarrage de cette valeur pour initialiser toute la mémoire libre pour intercepter les pointeurs errants
* 0xBAADF00D: utilisé par LocalAlloc de Microsoft (LMEM_FIXED) pour marquer la mémoire de tas allouée non initialisée
* 0xBADCAB1E: Code d'erreur renvoyé au débogueur Microsoft eVC lorsque la connexion est rompue avec le débogueur
* 0xBEEFCACE: utilisé par Microsoft .NET comme nombre magique dans les fichiers de ressources
* 0xCCCCCCCC: utilisé par la bibliothèque d'exécution de débogage C ++ de Microsoft pour marquer la mémoire de pile non initialisée
* 0xCDCDCDCD: utilisé par la bibliothèque d'exécution de débogage C ++ de Microsoft pour marquer la mémoire de tas non initialisée
* 0xDDDDDDDD: utilisé par le tas de débogage C ++ de Microsoft pour marquer la mémoire de tas libérée
* 0xDEADDEAD: code d'erreur d'arrêt de Microsoft Windows utilisé lorsque l'utilisateur initie manuellement le plantage.
* 0xFDFDFDFD: utilisé par le tas de débogage C ++ de Microsoft pour marquer les octets de garde "no man's land" avant et après la mémoire de tas allouée
* 0xFEEEFEEE: utilisé par HeapFree () de Microsoft pour marquer la mémoire de tas libérée

19
Ici, je vois BAADF00D(mauvaise nourriture), BEEFCACE(gâteau de boeuf), BAADCAB1E(mauvais câble), BADCAFE(mauvais café) et DEADDEAD(mort mort). Est-ce intentionnel?
Anderson Green

38
@AndersonGreen Bien sûr, c'est intentionnel. Cela s'appelle hexspeak .

28
Nous avions l'habitude d'utiliser C0CAC01A lorsque nous faisions de la programmation de bas niveau (noyau du système d'exploitation) à l'époque ...;)
Per Lundberg

2
0xDEADBEEF, 0xC0EDBABEaussi des classiques même s'ils ne sont pas tombés dans la langue vernaculaire de MS
J. Paulding

3
En tant que fan de Paul McCartney, j'aimeBEA71E5
BlueRaja - Danny Pflughoeft

111

Il y a en fait pas mal d'informations utiles ajoutées aux allocations de débogage. Ce tableau est plus complet:

http://www.nobugs.org/developer/win32/debug_crt_heap.html#table

Adresse Offset Après HeapAlloc () Après malloc () Pendant free () Après HeapFree () Commentaires
0x00320FD8 -40 0x01090009 0x01090009 0x01090009 0x0109005A Informations de tas Win32
0x00320FDC -36 0x01090009 0x00180700 0x01090009 0x00180400 Informations de tas Win32
0x00320FE0 -32 0xBAADF00D 0x00320798 0xDDDDDDDD 0x00320448 Ptr au bloc de tas CRT suivant (alloué plus tôt dans le temps)
0x00320FE4 -28 0xBAADF00D 0x00000000 0xDDDDDDDD 0x00320448 Ptr au bloc de tas CRT précédent (alloué ultérieurement)
0x00320FE8 -24 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Nom de fichier de l'appel malloc ()
0x00320FEC -20 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Numéro de ligne de l'appel malloc ()
0x00320FF0 -16 0xBAADF00D 0x00000008 0xDDDDDDDD 0xFEEEFEEE Nombre d'octets à malloc ()
0x00320FF4 -12 0xBAADF00D 0x00000001 0xDDDDDDDD 0xFEEEFEEE Type (0 = libéré, 1 = normal, 2 = utilisation CRT, etc.)
0x00320FF8 -8 0xBAADF00D 0x00000031 0xDDDDDDDD 0xFEEEFEEE # de demande, augmente de 0
0x00320FFC -4 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEFEEE No mans land
0x00321000 +0 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE Les 8 octets que vous vouliez
0x00321004 +4 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE Les 8 octets que vous vouliez
0x00321008 +8 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEFEEE No mans land
0x0032100C +12 0xBAADF00D 0xBAADF00D 0xDDDDDDDD 0xFEEEFEEE Les allocations de tas Win32 sont arrondies à 16 octets
0x00321010 +16 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Win32 comptabilité de tas
0x00321014 +20 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Win32 comptabilité de tas
0x00321018 +24 0x00000010 0x00000010 0x00000010 0xFEEEFEEE Win32 comptabilité de tas
0x0032101C +28 0x00000000 0x00000000 0x00000000 0xFEEEFEEE Win32 comptabilité de tas
0x00321020 +32 0x00090051 0x00090051 0x00090051 0xFEEEFEEE Win32 comptabilité de tas
0x00321024 +36 0xFEEE0400 0xFEEE0400 0xFEEE0400 0xFEEEFEEE Win32 comptabilité de tas
0x00321028 +40 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Win32 comptabilité de tas
0x0032102C +44 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Win32 comptabilité de tas

5

En ce qui concerne 0xCCet 0xCDen particulier, ce sont des vestiges de l' Intel 8088 / 8086 instruction de processeur ensemble dans les années 1980. 0xCCest un cas particulier de l' opcode interruption logicielle . La version spéciale à un octet permet à un programme de générer une interruption 3 .INT 0xCD0xCC

Bien que les nombres d'interruptions logicielles soient, en principe, arbitraires, INT 3était traditionnellement utilisé pour la fonction d' interruption ou de point d'arrêt du débogueur , une convention qui reste à ce jour. Chaque fois qu'un débogueur est lancé, il installe un gestionnaire d'interruption pour INT 3que lorsque cet opcode est exécuté, le débogueur soit déclenché. En général, il suspend la programmation en cours d'exécution et affiche une invite interactive.

Normalement, l' INTopcode x86 est de deux octets: 0xCDsuivi du numéro d'interruption souhaité de 0 à 255. Maintenant, bien que vous puissiez émettre 0xCD 0x03pour INT 3, Intel a décidé d'ajouter une version spéciale - 0xCCsans octet supplémentaire - car un opcode ne doit être qu'un octet pour fonctionner comme un `` octet de remplissage '' fiable pour la mémoire inutilisée.

Le point ici est de permettre une récupération gracieuse si le processeur saute par erreur dans la mémoire qui ne contient aucune instruction prévue . Les instructions multi-octets ne conviennent pas à cet objectif car un saut erroné pourrait atterrir à n'importe quel décalage d'octet possible où il devrait continuer avec un flux d'instructions correctement formé.

Évidemment, les opcodes à un octet fonctionnent trivialement pour cela, mais il peut aussi y avoir des exceptions bizarres: par exemple, compte tenu de la séquence de remplissage 0xCDCDCDCD(également mentionnée sur cette page), nous pouvons voir qu'elle est assez fiable car peu importe où le pointeur d'instruction atterrit ( sauf peut - être le dernier octet rempli), la CPU peut reprendre l'exécution d'une instruction x86 valide à deux octetsCD CD , dans ce cas pour générer l'interruption logicielle 205 (0xCD).

Plus étrange encore, alors qu'elle CD CC CD CCest 100% interprétable - donnant soit INT 3ou INT 204- la séquence CC CD CC CDest moins fiable, seulement 75% comme indiqué, mais généralement 99,99% lorsqu'elle est répétée comme un remplissage de mémoire de taille int.

page du manuel d'instructions 8088/8086 contemporain montrant les instructions INT
Macro Assembler Reference , 1987


Wow, je n'ai pas réalisé (connecter les deux) 0xCC était INT3. Cela a du sens (c'est-à-dire pas par coïncidence). J'avais l'habitude d'injecter "NOP + INT3" dans des endroits où il y a des JMP pour inspecter les registres avant qu'il ne saute à quelques reprises (retour quand). Merci pour cet aperçu, mystère résolu!
HidekiAI

C'était NOPpour quoi ? La saisie d'un seul 0xCCoctet avec la commande eb(entrer les octets) ne suffirait-elle pas?
Glenn Slayden

Juste une habitude, à l'époque, certains codes lisaient deux octets et essayaient de les utiliser comme table de raccourcis, ou dans certains cas, lorsque je listais le code assembleur, en ajoutant NOP, il ne s'afficherait pas comme '???' ou quelque chose (plus lisible) lors du démontage; dans l'ensemble, pour de multiples raisons, il est juste devenu une habitude de simplement injecter un NOP avant ou après le BRK; oh , dans certains cas, certaines applications tenteraient de faire la somme de contrôle du bloc d'adresses, donc j'équilibrer le JMP $ XYZW avec INT3 + [certains hex] sourire
HidekiAI
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.