Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет yigal_s ([info]yigal_s)
@ 2011-09-04 13:47:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
немного хардкора
забавную штучку я раскопал, а потом и нашел по ссылке аналогичные наблюдения

http://groups.google.com/group/lock-free/browse_thread/thread/d7ac22f807d1d439


Возможно и похоже (я не проверял, у меня сейчас на виндах нет ни дебаггера ни даже С++, а дискуссия по ссылке чуток неадеквата), что сейчас под виндоуз невозможно написать 100% надёжный lock-free код, возвращающий память системе с помощью вызова free и подобного, а не возвращающий выделенную память в пул, либо использующий сборщик мусора.

Причина несколько тонка - в результате освобождения памяти может произойти исключение при доступе по "старому" указателю. Само по себе это не беда - можно надеяться словить исключение и обработать его как факт того, что указатель устарел.

Проблема, однако, в том, что адресуясь по устаревшим указателям наугад можно нечаянно задеть guard-page другого треда, а это, как это не смешно, приводит через непродолжительное время к терминации процесса.

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

Вообще, чего б этому самому ядру не заботиться о том, чтобы не сносить аттрибут guard-pages если они не относятся к стеку текущего треда? Ведь уже так или иначе исключение по доступу к guard page стека делается в kernel-mode, так отчего бы и нет? Впрочем, тогда либо придется вводить дополнительный аттрибут памяти "stack guard page", либо тупо проверять, а не относится ли данный guard-page на который нечаянно наступили, к какому-нибудь еще стеку, что действительно довольно тупо. Опять же, если продвинутый пользователь желает использовать guard-pages сам для своих собственных структур данных (а не для стека треда), то чужой тред снова имеет чудесную возможность долбануть по этому guard-page, получить исключение и поднять лапки кверху, поскольку что делать с этим исключением он не знает.

В общем, весь концепт guard-page задизайнен, похож, немного криво.
----------------------------------
С другой стороны, как отмечают тут (ссылка аж с 2003-го года!) память может быть замаплена и на порты ввода-вывода устройств, и тут уже остается не жаловаться на кривой дизайн или имлементацию guard-page, а просто, видимо, обозначить, что lock-free синхронизацию принципиально нельзя делать без поддержки сборщика мусора (которому самому желательно быть lock-free :-))) или рецайлинга объектов (даже не памяти, а именно объектов, чтобы будущие адресации нечаянно не попали на переалллоцированный объект другого формата).

Вроде, подобные мысли время от времени попадались, но не так чтобы где-то я видел их четко и однозначно сформулированными. Надо будет что-нидь перечитать по теме.
--------------------
UPD: перечитал. был неправ. можно память и освобождать. без сборщика мусора. и без рецайклинга. но аккуратно. )))


(Добавить комментарий)


[info]mediant@lj
2011-09-05 07:16 (ссылка)
InterlockedPopEntrySList это старая тема, и бага там нет. Но это лишь для избранных, don't try this at home :)

По ссылке довольно верно и доходчиво объясняют: обработчик ядра проверяет адрес исключения на равенство ExpInterlockedPopEntrySListFault - той самой инструкции, очевидно все это еще до проверки на guard page.

Вот и имеем Quod licet Iovi, non licet bovi в отдельно взятой OC...

(Ответить) (Ветвь дискуссии)


[info]yigal_s@lj
2011-09-05 13:52 (ссылка)
по ссылке приводится обработчик исключения из ntdll.dll, никакого отношения к "ядру" он не имеет, обычный код юзеровского уровня. :-)))

меж тем, проблема обязана хендлиться именно в ядре. есть ли подходящий обработчик в ядре - вопрос отдельный.

* Но это лишь для избранных, don't try this at home :)

Вот вот. Но людям хочеца, как ты прекрасно знаешь. :-)

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]mediant@lj
2011-09-05 14:20 (ссылка)
kd? nt!KiCheckForSListAddress? Это уж никак не usermode.
Кроме того, можешь погулить ExpInterlockedPopEntrySListFault+reactos+doxygen для полноты картины. Reactos, понятное дело, не эталон, но концептуально все именно так и работает.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]yigal_s@lj
2011-09-05 14:25 (ссылка)
а, вот оно как? Ну тогда всё нормально, поциент будеть жить.

(Ответить) (Уровень выше)