Вопрос

Для разработки на C++ для 32-битных систем (будь то Linux, Mac ОС или окна, PowerPC или x86) я инициализировал указатели, которые в противном случае были бы неопределенными (например,Они не могут сразу получить правильное значение), как так:

int *pInt = reinterpret_cast<int *>(0xDEADBEEF);

(Чтобы не печатать и не СУХОЙ Правая сторона обычно будет постоянной, например,БАД_ПТР.)

Если пинта оказывается в восторге от того, что она получит надлежащее значение, то она сразу же сбой в большинстве систем (вместо того, чтобы сбой намного позже, когда некоторая память перезаписана или переходит в очень длинный цикл).

Конечно, это поведение зависит от базового аппаратного обеспечения (получение целого числа 4 байтов от нечетного адреса 0xdeadbeef от пользовательского процесса может быть совершенно допустимым), но сбой был на 100% надежным для всех систем, которые я разработал до сих пор (для Mac OS 68ххх, Mac OS PowerPC, Linux Redhat Pentium, Windows Gui Pentium, Windows Console Pentium).Например, на PowerPC он незаконен (ошибка автобуса) принести 4 -байт целого числа с нечетного адреса.

Каково хорошее значение для этого в 64-битных системах?

Это было полезно?

Решение

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

Посмотрите в ядре Linux по адресу включить/linux/poison.h.Этот файл содержит разные значения ошибок для множества разных подсистем ядра.Не существует одного подходящего значения отравления.

Кроме того, вы можете проверить включаемые файлы для каждой архитектуры в дереве исходного кода ядра Linux, чтобы получить информацию о том, что используется в конкретных архитектурах.

Другие советы

0xBADC0FFEE0DDF00D

По данным Википедии, BADC0FFEE0DDF00D используется в 64-битных системах IBM RS/6000 для обозначения неинициализированных регистров ЦП.

Большинство современных 64-битных систем позволяют использовать только 2 младших48–252 биты адресного пространства;старшие биты адреса должны быть нулевыми.Некоторые фишки (например.amd64) также позволяет вам использовать наибольший 248–252.Адреса за пределами этих диапазонов никогда не могут быть сопоставлены с доступной памятью;оборудование просто не позволит этого.

Поэтому я рекомендую вам использовать значение, близкое к 2.63, что далеко от любого из потенциально пригодных для использования пространств.Если первые четыре шестнадцатеричные цифры равны 7ff8, значение будет представлять собой NaN двойной точности с плавающей запятой, что удобно.Итак, я предлагаю симпатичную шестнадцатеричную фразу: 0x7FF8BADFBADFBADF.

Кстати, не стоит использовать значение, близкое к 0, потому что при этом будет сложно определить компенсировать разыменование NULL — например, доступ к члену структуры — из разыменования подозрительного шаблона.

Я предполагаю, что вы уже сделали скидку на NULL (т.е.0 без приведения типов).Это определенно самый безопасный выбор, поскольку теоретически это действительный указатель. мог укажите адрес памяти 0xDEADBEEF (или любой другой адрес памяти, отличный от NULL).

0xDEADBEEFBAADF00D может работать.

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

Я думаю, двух 0xDEADBEEF должно быть достаточно.

Я вижу несколько ответов, утверждающих, что NULL — хороший выбор, но я не согласен.

NULL часто используется как допустимое возвращаемое значение функций.Это указывает на возврат ошибки или неизвестное значение.Это другое значение, чем «неинициализированный указатель».

Использование отладчика в коде и обнаружение NULL оставит две возможности:указатель никогда не был инициализирован или ему не удалось выделить память.

Установка неинициализированного указателя на 0xDEADBEEF или его 64-битный эквивалент означает, что NULL-указатель указывает на намеренное значение.

Конечно, это зависит от ОС и среды.Я также не думаю, что 0xDEADBEEF обязательно является плохим указателем в произвольной 32-битной системе.

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

0x42 может работать как на 32-битной, так и на 64-битной версии?(Это все равно должно вызвать сбой, поскольку оно достаточно близко к указателю NULL, и, учитывая его довольно большой размер, есть вероятность, что вы не получите его при обычном разыменовании поля структуры с указателем структуры, равным NULL).

Поскольку система, над которой я работал, в основном работает на платформе x86_64, я использую следующее значение:

0xDEADBEEFDEADBEEF

Причины:

  • На платформе x86_64 в текущей реализации для адреса виртуальной памяти используются только младшие 48 бит, то есть любое значение > 2^48 должно работать: https://en.wikipedia.org/wiki/X86-64
  • Как 0xDEADBEEF уже очень хорошо известен для этой цели в 32-битной версии, 0xDEADBEEFDEADBEEF в 64-битной версии просто более «обратно совместима»
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top