Как сделать выделение памяти в MSVC C++ детерминированным?

При отладке некоторого кода C++ с множеством указателей было бы полезно, если бы адреса памяти между запусками были одинаковыми. Есть ли способ сделать серию адресов, возвращаемых между последовательными запусками программы, выполняющей одно и то же распределение памяти, детерминированной?

Может быть, переменная среды или что-то, что можно установить для отладочной кучи?

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


person Joe    schedule 26.01.2016    source источник
comment
Есть ли способ сделать последовательности адресов, которые возвращаются между последовательными запусками программы, выполняющей одно и то же распределение памяти, детерминированными? Боюсь, нет способа получить одинаковые адреса из повторные запуски вашей программы.   -  person πάντα ῥεῖ    schedule 27.01.2016
comment
Я согласен с @πάνταῥεῖ. При запросе памяти, будь то из статического хранилища или динамического, вы зависите от операционной системы. И если он загружает вашу программу с разных адресов и выдает вам разные адреса, когда вы запрашиваете память, ваша программа ничего не может с этим поделать.   -  person SergeyA    schedule 27.01.2016
comment
Рандомизация адресного пространства, скорее всего, является основной причиной этого. en.wikipedia.org/wiki/   -  person drescherjm    schedule 27.01.2016
comment
Чтобы отключить ASLR в Windows: stackoverflow.com/questions/9560993/   -  person drescherjm    schedule 27.01.2016
comment
Вы можете заменить operator new. В своем варианте создайте одно большое отображение памяти (очевидно, для этого требуется x64) и выделяйте последовательно из этого блока.   -  person MSalters    schedule 27.01.2016
comment
@drescherjm Я попытался отключить ASLR для всей системы с помощью EMET, как описано в одном из ответов по вашей ссылке. Однако я все еще получил разные адреса из распределения памяти. Изменяется ли ASLR только там, где загружаются исполняемые файлы, но не там, где виртуальная память выделяется для других целей? Во всяком случае, это не похоже на волшебную таблетку, на которую я надеялся. Также было бы неплохо, если бы было что-то, что можно было бы установить для каждого процесса, чтобы общая безопасность не ставилась под угрозу. :-/   -  person Joe    schedule 27.01.2016
comment
@MSalters Мне все равно нужно было бы убедиться, что большой блок памяти распределен детерминировано, чтобы указатели внутри него оставались неизменными между запусками. Теоретически я мог бы сделать то, что вы предлагаете, и создать класс умного указателя, который добавляет базу + смещение для каждого разыменования, но это звучит сложным и глупым обходным путем для того, что кажется простым параметром для установки в системе памяти.   -  person Joe    schedule 27.01.2016
comment
@Joe: Нет, вам не нужен класс интеллектуальных указателей. Выберите фиксированный базовый адрес. Вероятность того, что 99% из них свободны в 64-битном адресном пространстве, составляет 99%. Очень легко недооценить ошеломляюще большое 64-битное адресное пространство; 16 ГБ - это всего лишь миллиардная.   -  person MSalters    schedule 27.01.2016
comment
@MSalters Я вижу, что вы правы в том, что вы можете дополнительно указать базовый адрес при вызове VirtualAlloc, и я согласен с вами в том, что крайне маловероятно, что вы выберете диапазон адресов, который перекрывает ранее существовавшие распределения. Необходимость писать распределитель не так проста, как хотелось бы, но выполнима.   -  person Joe    schedule 01.02.2016
comment
@MSalters Я забыл сказать: я сомневаюсь, что есть лучшее решение, чем ваше, поэтому, если вы напишете ответ, я его приму.   -  person Joe    schedule 01.02.2016


Ответы (2)


(Переведено из комментария)

Вы можете заменить оператора новым. В вашей собственной версии создайте одно большое сопоставление памяти с фиксированным базовым адресом. Вероятность того, что он свободен в 64-битном адресном пространстве, составляет >99%. Затем просто выделяйте последовательно из этого блока.

person MSalters    schedule 02.02.2016

используется специальная куча отладки, которая выполняет дополнительные проверки и записывает специальные значения.

Нет, нет такой вещи, как куча отладки, но менеджер кучи отладки, который подготавливает макет и канарейки. дополнительные проверки и специальные значения — это просто результат кода, скомпилированного в режиме отладки. Адреса по-прежнему произвольные, полученные из операционной системы.

Есть ли способ сделать серию адресов, возвращаемых между последовательными запусками программы, выполняющей одно и то же распределение памяти, детерминированной?

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

person πάντα ῥεῖ    schedule 26.01.2016
comment
Там определенно есть отладочная куча. msdn.microsoft.com/en-us/library/974tc9t1.aspx - person Joe; 27.01.2016
comment
@Joe Это не означает, что выделенная память отображается по детерминированным адресам, а означает, что макет подготовлен из диспетчера кучи отладки. - person πάντα ῥεῖ; 27.01.2016