¿Cuáles son los patrones de llenado de la memoria de depuración en Visual Studio C++ y Windows?

Resuelto HidekiAI asked hace 16 años • 3 respuestas

En Visual Studio, todos hemos tenido "baadf00d", hemos visto "CC" y "CD" al inspeccionar variables en el depurador en C++ durante el tiempo de ejecución.

Por lo que tengo entendido, "CC" está en modo DEBUG solo para indicar cuando una memoria ha sido nueva () o alloc () y unilializada. Mientras que "CD" representa memoria eliminada o liberada. Sólo he visto "baadf00d" en la versión RELEASE (pero puede que me equivoque).

De vez en cuando, nos encontramos en una situación en la que tenemos que abordar pérdidas de memoria, desbordamientos de búfer, etc., y este tipo de información resulta útil.

¿Alguien sería tan amable de señalar cuándo y en qué modos la memoria se configura con patrones de bytes reconocibles para fines de depuración?

HidekiAI avatar Sep 24 '08 21:09 HidekiAI
Aceptado

Este enlace tiene más información:

https://en.wikipedia.org/wiki/Magic_number_(programming)#Debug_values

* 0xABABABAB: Utilizado por HeapAlloc() de Microsoft para marcar bytes de protección de "tierra de nadie" después de la memoria de montón asignada.
* 0xABADCAFE: un inicio con este valor para inicializar toda la memoria libre para detectar punteros erróneos
* 0xBAADF00D: Utilizado por LocalAlloc (LMEM_FIXED) de Microsoft para marcar la memoria de montón asignada no inicializada
* 0xBADCAB1E: Código de error devuelto al depurador de Microsoft eVC cuando se corta la conexión con el depurador
* 0xBEEFCACE: Utilizado por Microsoft .NET como número mágico en archivos de recursos
* 0xCCCCCCCC: Utilizado por la biblioteca de tiempo de ejecución de depuración C++ de Microsoft para marcar la memoria de pila no inicializada.
* 0xCDCDCDCD: Utilizado por la biblioteca de tiempo de ejecución de depuración C++ de Microsoft para marcar la memoria del montón no inicializada.
* 0xDDDDDDDD: Utilizado por el montón de depuración de C++ de Microsoft para marcar la memoria del montón liberada.
* 0xDEADDEAD: un código de error de DETENCIÓN de Microsoft Windows que se utiliza cuando el usuario inicia manualmente el bloqueo.
* 0xFDFDFDFD: Utilizado por el montón de depuración de C++ de Microsoft para marcar los bytes de protección de "tierra de nadie" antes y después de la memoria del montón asignada.
* 0xFEEEFEEE: Utilizado por HeapFree() de Microsoft para marcar la memoria del montón liberada.
Mark Ingram avatar Sep 24 '2008 14:09 Mark Ingram

En realidad, se agrega bastante información útil a las asignaciones de depuración. Esta tabla es más completa:

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

Desplazamiento de dirección después de HeapAlloc() Después de malloc() Durante free() Después de HeapFree() Comentarios
0x00320FD8 -40 0x01090009 0x01090009 0x01090009 0x0109005A Información del montón Win32
0x00320FDC -36 0x01090009 0x00180700 0x01090009 0x00180400 Información del montón Win32
0x00320FE0 -32 0xBAADF00D 0x00320798 0xDDDDDDDD 0x00320448 Ptr al siguiente bloque de montón CRT (asignado anteriormente en el tiempo)
0x00320FE4 -28 0xBAADF00D 0x00000000 0xDDDDDDDD 0x00320448 Ptr al bloque de montón CRT anterior (asignado más adelante en el tiempo)
0x00320FE8 -24 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Nombre de archivo de la llamada malloc()
0x00320FEC -20 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Número de línea de llamada malloc()
0x00320FF0 -16 0xBAADF00D 0x00000008 0xDDDDDDDD 0xFEEEFEEE Número de bytes para malloc()
0x00320FF4 -12 0xBAADF00D 0x00000001 0xDDDDDDDD 0xFEEEFEEE Tipo (0=Liberado, 1=Normal, 2=uso CRT, etc.)
0x00320FF8 -8 0xBAADF00D 0x00000031 0xDDDDDDDD 0xFEEEFEEE Solicitud #, aumenta desde 0
0x00320FFC -4 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEFEEE Tierra de nadie
0x00321000 +0 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE Los 8 bytes que querías
0x00321004 +4 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE Los 8 bytes que querías
0x00321008 +8 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEFEEE Tierra de nadie
0x0032100C +12 0xBAADF00D 0xBAADF00D 0xDDDDDDDD 0xFEEEFEEE Las asignaciones de montón de Win32 se redondean a 16 bytes
0x00321010 +16 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Contabilidad del montón Win32
0x00321014 +20 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Contabilidad del montón Win32
0x00321018 +24 0x00000010 0x00000010 0x00000010 0xFEEEFEEE Contabilidad del montón Win32
0x0032101C +28 0x00000000 0x00000000 0x00000000 0xFEEEFEEE Contabilidad del montón Win32
0x00321020 +32 0x00090051 0x00090051 0x00090051 0xFEEEFEEE Contabilidad del montón Win32
0x00321024 +36 0xFEEE0400 0xFEEE0400 0xFEEE0400 0xFEEEFEEE Contabilidad del montón Win32
0x00321028 +40 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Contabilidad del montón Win32
0x0032102C +44 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Contabilidad del montón Win32
John Dibling avatar Dec 09 '2008 17:12 John Dibling

En cuanto a y en particular, se trata de reliquias de la instrucción del procesador Intel 8088/80860xCC de 0xCDla década de 1980 . 0xCCEs un caso especial del código de operación de interrupción de software . La versión especial de un solo byte permite que un programa genere la interrupción 3 .INT 0xCD0xCC

Aunque los números de interrupción del software son, en principio, arbitrarios, INT 3tradicionalmente se utilizaban para la función de interrupción o punto de interrupción del depurador , una convención que se mantiene hasta el día de hoy. Cada vez que se inicia un depurador, instala un controlador de interrupciones de modo INT 3que cuando se ejecute ese código de operación, se active el depurador. Por lo general, pausará la programación que se está ejecutando actualmente y mostrará un mensaje interactivo.

Normalmente, el código de operación x86 INTocupa dos bytes: 0xCDseguido del número de interrupción deseado del 0 al 255. Entonces, aunque podría emitir 0xCD 0x03para INT 3, Intel decidió agregar una versión especial, 0xCCsin bytes adicionales, porque un código de operación debe tener solo un byte para funcionar como un 'byte de relleno' confiable para la memoria no utilizada.

El punto aquí es permitir una recuperación elegante si el procesador salta por error a una memoria que no contiene ninguna instrucción prevista . Las instrucciones de varios bytes no son adecuadas para este propósito, ya que un salto erróneo podría aterrizar en cualquier posible desplazamiento de bytes donde tendría que continuar con un flujo de instrucciones formado correctamente.

Obviamente, los códigos de operación de un byte funcionan de manera trivial para esto, pero también puede haber excepciones extravagantes: por ejemplo, considerando la secuencia de llenado 0xCDCDCDCD(también mencionada en esta página), podemos ver que es bastante confiable ya que no importa dónde aterrice el puntero de instrucción ( excepto quizás el último byte llenado), la CPU puede reanudar la ejecución de una instrucción x86 válida de dos bytesCD CD , en este caso para generar la interrupción de software 205 (0xCD).

Lo que es aún más extraño, mientras que CD CC CD CCes 100% interpretable (dando o INT 3o INT 204), la secuencia CC CD CC CDes menos confiable, solo el 75% como se muestra, pero generalmente el 99,99% cuando se repite como un relleno de memoria de tamaño int.

Página del manual del conjunto de instrucciones 8088/8086 contemporáneo que muestra la instrucción INT
Referencia del macroensamblador , 1987

Glenn Slayden avatar Jan 15 '2018 00:01 Glenn Slayden