В Visual Studio C++, каковы представления распределения памяти?

В Visual Studio у всех нас было "baadf00d", мы видели "CC" и "CD" при проверке переменных в отладчике в C++ во время выполнения.

Из того, что я понимаю, "CC" находится в режиме отладки только для указания, когда память была новой () или alloc() и унитилизована. В то время как "CD" обозначает удаление или освобождение памяти. Я видел только baadf00d в RELEASE build (но я могу ошибаться).

Время от времени мы попадаем в ситуацию с утечками памяти, переполнением буфера и т. Д., И такая информация оказывается полезной.

Будет ли кто-нибудь достаточно любезен, чтобы указать, когда и в каких режимах памяти установлены распознаваемые байтовые шаблоны для целей отладки?

3 ответа

Решение

Эта ссылка имеет больше информации:

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

* 0xABABABAB: Используется Microsoft HeapAlloc() для пометки защитных байтов "без земли" после выделенной памяти кучи. * 0xABADCAFE: Запуск этого значения для инициализации всей свободной памяти для отлова ошибочных указателей. * 0xBAADF00D: Используется Microsoft LocalAlloc(LMEM_FIXED) для Пометить неинициализированную выделенную память кучи * 0xBADCAB1E: Код ошибки, возвращаемый отладчику Microsoft eVC при разрыве соединения с отладчиком * 0xBEEFCACE: Используется Microsoft .NET как магическое число в файлах ресурсов * 0xCCCCCCCC: Используется библиотекой среды выполнения C++ отладки Microsoft для отметки неинициализированная стековая память * 0xCDCDCDCD: используется библиотекой Microsoft C++ для выполнения отладки, чтобы пометить неинициализированную память кучи * 0xDDDDDDDDD: используется кучи отладки Microsoft C++, чтобы пометить свободную память кучи * 0xDEADDEAD: код ошибки Microsoft Windows STOP, используемый, когда пользователь вручную инициирует сбой.
* 0xFDFDFDFD: Используется кучей отладки Microsoft C++ для пометки защитных байтов "без земли" до и после выделенной памяти кучи. * 0xFEEEFEEE: Используется Microsoft HeapFree() для пометки освобожденной памяти кучи.

На самом деле к отладочным выделениям добавлено довольно много полезной информации. Эта таблица является более полной:

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

Смещение адреса после HeapAlloc() После malloc() Во время free() После HeapFree() Комментарии
0x00320FD8  -40    0x01090009    0x01090009     0x01090009    0x0109005A Информация о куче Win32
0x00320FDC  -36    0x01090009    0x00180700     0x01090009    0x00180400 Информация о куче Win32
0x00320FE0  -32    0xBAADF00D    0x00320798     0xDDDDDDDD    0x00320448     Ptr для следующего блока кучи CRT (выделенного ранее во времени)
0x00320FE4  -28    0xBAADF00D    0x00000000     0xDDDDDDDD    0x00320448     Ptr к предыдущему блоку кучи CRT (выделено позже)
0x00320FE8  -24    0xBAADF00D    0x00000000     0xDDDDDDDD    0xFEEEFEEE Имя файла вызова malloc()
0x00320FEC  -20    0xBAADF00D    0x00000000     0xDDDDDDDD    0xFEEEFEEE Номер строки вызова malloc()
0x00320FF0  -16    0xBAADF00D    0x00000008     0xDDDDDDDD    0xFEEEFEEE Количество байтов для malloc()
0x00320FF4  -12    0xBAADF00D    0x00000001     0xDDDDDDDD    0xFEEEFEEE Тип (0=Freed, 1=Normal, 2=CRT-использование и т. Д.)
0x00320FF8  -8     0xBAADF00D    0x00000031     0xDDDDDDDD    0xFEEEFEEE     Request #, увеличивается с 0
0x00320FFC  -4     0xBAADF00D    0xFDFDFDFD     0xDDDDDDDD    0xFEEEFEEE Нет земли
0x00321000  +0     0xBAADF00D    0xCDCDCDCD     0xDDDDDDDD    0xFEEEFEEE 8 требуемых байтов
0x00321004  +4     0xBAADF00D    0xCDCDCDCD     0xDDDDDDDD    0xFEEEFEEE 8 требуемых байтов
0x00321008  +8     0xBAADF00D    0xFDFDFDFD     0xDDDDDDDD    0xFEEEFEEE Нет земли человека
0x0032100C  +12    0xBAADF00D    0xBAADF00D     0xDDDDDDDD    0xFEEEFEEE Выделения кучи Win32 округляются до 16 байтов
0x00321010  +16    0xABABABAB    0xABABABAB     0xABABABAB    0xFEEEFEEE     Win32 куча бухгалтерии
0x00321014  +20    0xABABABAB    0xABABABAB     0xABABABAB    0xFEEEFEEE     Win32 куча бухгалтерии
0x00321018  +24    0x00000010    0x00000010     0x00000010    0xFEEEFEEE     Win32 куча бухгалтерии
0x0032101C  +28    0x00000000    0x00000000     0x00000000    0xFEEEFEEE     Win32 куча бухгалтерии
0x00321020  +32    0x00090051    0x00090051     0x00090051    0xFEEEFEEE     Win32 куча бухгалтерии
0x00321024  +36    0xFEEE0400    0xFEEE0400     0xFEEE0400    0xFEEEFEEE     Win32 куча бухгалтерии
0x00321028  +40    0x00320400    0x00320400     0x00320400    0xFEEEFEEE     Win32 куча бухгалтерии
0x0032102C  +44    0x00320400    0x00320400     0x00320400    0xFEEEFEEE     Win32 куча бухгалтерии

Относительно 0xCC а также 0xCD в частности, это реликвии из инструкций процессора Intel 8088/8086, появившиеся еще в 1980-х годах. 0xCC это особый случай программного кода прерывания INT0xCD, Специальная однобайтовая версия 0xCC позволяет программе генерировать прерывание 3.

Хотя номера программных прерываний в принципе произвольны, INT 3 традиционно использовался для функции прерывания отладчика или функции точки останова, соглашение, которое остается по сей день. Каждый раз, когда запускается отладчик, он устанавливает обработчик прерываний для INT 3 так что при выполнении этого кода операции будет запущен отладчик. Обычно это приостанавливает текущее программирование и отображает интерактивное приглашение.

Обычно х86 INT код операции составляет два байта: 0xCD с последующим желаемым номером прерывания от 0 до 255. Теперь, хотя вы могли бы выпустить 0xCD 0x03 за INT 3 Intel решила добавить специальную версию 0xCC без дополнительного байта - потому что код операции должен быть только один байт, чтобы функционировать как надежный "байт заполнения" для неиспользуемой памяти.

Суть в том, чтобы обеспечить постепенное восстановление, если процессор ошибочно переходит в память, которая не содержит каких-либо предполагаемых инструкций. Многобайтовые инструкции не подходят для этой цели, так как ошибочный переход может привести к любому возможному смещению байта, где он должен был бы продолжить с правильно сформированным потоком команд.

Очевидно, что однобайтовые коды операций работают для этого тривиально, но могут быть и странные исключения: например, учитывая последовательность заполнения 0xCDCDCDCD (также упоминается на этой странице), мы можем видеть, что это довольно надежно, поскольку независимо от того, где находится указатель инструкции (кроме, возможно, последнего заполненного байта), ЦПУ может возобновить выполнение действительной двухбайтовой инструкции x86 CD CD в этом случае для генерации программного прерывания 205 (0xCD).

Еще страннее, тогда как CD CC CD CC интерпретируется на 100%, давая INT 3 или же INT 204 --последовательность CC CD CC CD менее надежен, только 75%, как показано, но обычно 99,99% при повторении в качестве наполнителя памяти типа int.

страница из руководства по эксплуатации 8088/8086, содержащего инструкцию INT
Справочник по макросам, 1987

Другие вопросы по тегам