LINUX.ORG.RU

Выделение процессу адресов выше 4х Гб


0

0

Господа, здравствуйте!

Меня интересует такой вопрос - можно ли в 64х-битном Linux'е запустить процесс так, чтобы указатели, которые он получает, допустим, при аллокации памяти, гарантировано вылезали за 32 бита? Еще лучше, чтобы адресное пространство ниже 32х бит было защищено, т.е. при попытке обращения туда мы ловили сегфолт.

Зачем это надо : есть очень большой и разлапистый SDK, который разрабатывался под х86 и сейчас адаптируется под x64. Обрезание указателей до 32х бит в нем - common case. Т.к. ядро в основном грузит все это хозяйство и раздает адреса ниже 4х Гб, наверняка многие подобные обрезания остались незамеченными. Если сделать так, как я хочу, можно будет сразу отловить кучу ошибок.

Пока я пытаюсь перед запуском SDK съесть 4-5Гб посредством мелких malloc'ов по 4096 байт, и потом защитить это через mprotect, но не очень получается, ядро меня не спрашивает, где выделять память, да еще и mprotect требует страничного форматирования. С mmap'ом тоже пока не выгорает.

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

Может проще найти компилятор, который сообщает об опасных преобразованиях типов? Intel, Sun, например...

yz
()
Ответ на: комментарий от yz

> Может проще найти компилятор, который сообщает об опасных преобразованиях типов?

Не поможет при явном приведении.

Кстати, а почему бы сразу не попросить 4 Гб?

mannaz
()
Ответ на: комментарий от pained

> Конечно же его сразу отдадут по адресу 0!

Ухтыжка!

mannaz
()

Можно попробовать через LD_PRELOAD прицепить внешний аллокатор в котором реализовать твою логику. В качестве базового можно взять готовый алокатор(google perfomance tools/ intel tbb alloc) и заменить в нем выделение макроблоков памяти анонимным mmap-ом в нужный тебе регион(>4G).

P.S. imho valgrind тебе сильно поможет - он умеет сообщать об ошибках работы с памятью (разименование кривого указателя, использование освобожденного буфера и т.д.) даже когда они еще не привели к краху приложения.

YesSSS ★★★
()
Ответ на: комментарий от mannaz

#include <cstdlib>

int main()
{
size_t p;
int q;

q = (int)p;

return 0;
}


/opt/sunstudio12/bin/CC -xport64 opyt.cpp
"opyt.cpp", line 8: Warning: Converting a 64-bit type value to "int" causes truncation.
"opyt.cpp", line 8: Warning: The variable p has not yet been assigned a value.
2 Warning(s) detected.

yz
()
Ответ на: комментарий от yz

> "opyt.cpp", line 8: Warning: Converting a 64-bit type value to "int" causes truncation.

и где здесь указатели ? :)

Eshkin_kot ★★
()

shmat например получает в качестве аргумента хинт на начало блока, и ядро его у меня весьма часто соблюдало (правда, я эксперементировал только на 32 битах)

malloc -- это функция libc, а *вовсе не* ядра. libc дергает то ли shmat , то ли do_mmap (с аргументами), то ли ... -- что-то в этом духе.

Замапленные сегменты (которые помешают получить блок там, где ты хочешь) можно где-то посмотреть... /proc... /sys... где-то там

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от YesSSS

> В качестве базового можно взять готовый алокатор(google perfomance tools/ intel tbb alloc) и заменить в нем выделение макроблоков памяти анонимным mmap-ом в нужный тебе регион(>4G)

Если физическая память позволяет, то можно еще попробовать поиграться с gpt'шной переменной окружения TCMALLOC_DEVMEM_START - граница в мегабайтах, начиная с которой будут выделяться блоки при использовании /dev/mem-аллокатора. Но для чистоты эксперимента проще и надежнее (если, конечно, подходящих инструментов не найдется) написать собственный malloc, который будет отдавать память из предварительно выделенного mmap блока, располагающегося выше 4 Гб.

mannaz
()
Ответ на: комментарий от mannaz

Отмена. Посмотрел по коду: TCMALLOC_DEVMEM_START тут не поможет.

mannaz
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.