Forwarded from Алиса копается
#dev
Все мы знаем, что разыменовывать нулевой указатель плохо, потому что программа крашнется и вообще это UB, отстаньте. На самом деле, за этим утверждением скрывается много всякого интересного и неожиданного.
Начнем с того, что есть нуль, а есть ноль.
Как вытекает из предыдущего, ничего особенного в адресе
Впрочем, одно дело — UB по стандарту, другое — поведение на практике. В прошлом стандарт C воспринимался скорее как гайдлайн, чем правила. Старые компиляторы не делали умных оптимизаций, и вообще Ритчи не подразумевал, что за счет UB будут оптимизировать, поэтому на многих платформах разыменование нулевого указателя только и делало, что читало значение в памяти по адресу
В современном мире писать по адресу, совпадающему с адресом
Хочется верить, что по крайней мере на современных платформах разыменовывание
Потом эту лавочку прикрыли, и даже не потому, что это скрывает баги в программах на C. Ну, точнее, ровно поэтому, только программой на C здесь выступает само ядро. Достаточно большое количество ядерных эксплоитов того времени заключалось в том, чтобы дата рейсом или иным методом заставить ядро разыменовать нулевой указатель. Поскольку внутри ядра (была) видна память текущего процесса, это приводило к тому, что пользовательская память начинала интерпретироваться как ядерные структуры. Чтобы этого избежать, сейчас Linux не позволяет аллоцировать страницы ниже адреса
На этом история с разыменованием нуля могла бы закончиться: в Windows ограничение на память на малых адресах было уже давно, в Linux ввели, других операционных систем не существует. Но хипстеры придумали WebAssembly, и поскольку с ним вопрос об изоляции внутри контейнера не встает, по адресу
Такие дела.
Все мы знаем, что разыменовывать нулевой указатель плохо, потому что программа крашнется и вообще это UB, отстаньте. На самом деле, за этим утверждением скрывается много всякого интересного и неожиданного.
Начнем с того, что есть нуль, а есть ноль.
NULL
не обязан иметь адрес 0
и, например, на некоторых архитектурах и интерпретаторах C это не так. Прагматичным людям из POSIX это не нравится, поэтому там NULL
всегда имеет адрес 0
. Впрочем, не обязательно даже уходить далеко в прошлое: amdgcn определяет NULL
как -1
, так что встретиться с таким сегодня вполне реально. Типичное определение NULL
как (void*)0
на таких машинах все еще работает, потому что (void*)0
стандарт определяет равным NULL
, но вот int x = 0; (void*)x
портабельно NULL
не даст.Как вытекает из предыдущего, ничего особенного в адресе
NULL
а нет, и в железе никто не запрещает существовать странице по адресу 0
. Железу плевать на то, какие правила накладывает стандарт C, и поэтому, например, на процессорах x86 в real mode по адресам 0
— 256
хранятся таблицы прерываний. Разыменовывать адрес 0
в C все еще UB, но вот 1
разыменовать никто не запрещает.Впрочем, одно дело — UB по стандарту, другое — поведение на практике. В прошлом стандарт C воспринимался скорее как гайдлайн, чем правила. Старые компиляторы не делали умных оптимизаций, и вообще Ритчи не подразумевал, что за счет UB будут оптимизировать, поэтому на многих платформах разыменование нулевого указателя только и делало, что читало значение в памяти по адресу
0
. Компилятор C на HP-UX (это были еще те времена, когда свободных компиляторов C не было, и под каждую платформу были свои компиляторы, зачастую платные), например, давал опцию: мапать страницу по адресу 0
, чтобы *(int*)NULL
возвращало 0
(гарантированно! без современного понимания UB!), или не мапать, чтобы падало.В современном мире писать по адресу, совпадающему с адресом
NULL
, опасно прям совсем. В embedded, где такое периодически приходится делать, у этой проблемы есть два решения: молоток и микроскоп. Во-первых, можно написать код для записи по адресу 0
на ассемблере, железо сожрет. Во-вторых, иногда железо игнорирует старшие биты адреса, поэтому можно записывать не по адресу 0
, а, например, по адресу 0x80000000
, который железо воспримет так же, а компилятор проинтерпретирует корректно.Хочется верить, что по крайней мере на современных платформах разыменовывание
NULL
(если его не выкинет компилятор, конечно) приведет к сегфолту или чему-то подобному. Это не так. Во-первых, Linux поддерживает флаг personality MMAP_PAGE_ZERO
, аллоцирующий страницу по адресу 0
на старте программы для совместимости с System V. Во-вторых, даже без этого вы можете с помощью mmap
аллоцировать страницу по адресу 0
руками — этим даже пользовались эмуляторы.Потом эту лавочку прикрыли, и даже не потому, что это скрывает баги в программах на C. Ну, точнее, ровно поэтому, только программой на C здесь выступает само ядро. Достаточно большое количество ядерных эксплоитов того времени заключалось в том, чтобы дата рейсом или иным методом заставить ядро разыменовать нулевой указатель. Поскольку внутри ядра (была) видна память текущего процесса, это приводило к тому, что пользовательская память начинала интерпретироваться как ядерные структуры. Чтобы этого избежать, сейчас Linux не позволяет аллоцировать страницы ниже адреса
sysctl vm.mmap_min_addr
— 64 кибибайта на большинстве устройств. (Нет бы писать без багов...)На этом история с разыменованием нуля могла бы закончиться: в Windows ограничение на память на малых адресах было уже давно, в Linux ввели, других операционных систем не существует. Но хипстеры придумали WebAssembly, и поскольку с ним вопрос об изоляции внутри контейнера не встает, по адресу
0
здесь вполне есть доступная память. Некоторых это бесит, некоторых удивляет, меня — радует, ибо нефиг проталкивать ограничения уровней абстракции вниз (впрочем, с этим в WebAssembly проиграли в других местах).Такие дела.
Алло, это отладочная?
Уже нет. — Хотя, ладно, я никогда не понимал синдрома самозванца. Ну т.е. типа если ты реально самозванец (и переживаешь по этому поводу!), то гораздо больше вопросов к людям вокруг, которые этого не замечают, чем к тебе.
нашел лучшую иллюстрацию этой мысли про синдром самозванца!
Набросайте нам идей проектов на сиспрошный хакатон!
А заодно подписывайтесь на канал сиспро, там и мемы про системщину и математику будут, спасибо @bsielwk)
А заодно подписывайтесь на канал сиспро, там и мемы про системщину и математику будут, спасибо @bsielwk)
Forwarded from Системное программирование ММФ НГУ
Уже через неделю пройдет первое в этом семестре сиспрошное мероприятие Хакатон!
Это событие, когда мы дружно запираемся в офисе, разбиваемся по командам, выбираем тему для проекта и весь день кодим в свое удовольствие!
Для нас это шикарная возможность отвлечься от повседневной рутины, пообщаться, и бахнуть какой-нибудь интересной проектик)
Как это прошло в том году, можете посмотреть здесь: https://youtu.be/V886KappFwA?si=_qp9LRIYygubNmar
А в комментариях к этому посту можете поделиться своими идеями для проекта на хакатон! Может, именно ваша идея принесет какой-то из наших команд победу в этом году!
Это событие, когда мы дружно запираемся в офисе, разбиваемся по командам, выбираем тему для проекта и весь день кодим в свое удовольствие!
Для нас это шикарная возможность отвлечься от повседневной рутины, пообщаться, и бахнуть какой-нибудь интересной проектик)
Как это прошло в том году, можете посмотреть здесь: https://youtu.be/V886KappFwA?si=_qp9LRIYygubNmar
А в комментариях к этому посту можете поделиться своими идеями для проекта на хакатон! Может, именно ваша идея принесет какой-то из наших команд победу в этом году!
Чем хороши воскресенья: в них нет созвонов => можно и код пописать 😏
Аааа, семестр начинается через 10 минут!
И какой семестр: начинается третий сезон алгосов и второй сезон плюсов на английском! Будет жарко.
И какой семестр: начинается третий сезон алгосов и второй сезон плюсов на английском! Будет жарко.
This media is not supported in your browser
VIEW IN TELEGRAM
Так, а как работать после 4 пар в универе с утра?
Хуйня эти ваши speaking clubs, хотите прогрессировать, попробуйте прочитать семестр лекций по плюсам на английском.
Искал одну старую картинку (вот эту, помните эту историю про Мэтта Тейлора и его рубашку, да?), случайно увидел свои посты 2012 года... ну я, конечно, тогда был прям агрессивно тупым. Надо как-то законодательно запретить читать свои старые посты, чтобы не расстраиваться.
Хотя с пары постов и картинок я даже посмеялся, неплохо, уже тогда были все задатки твиттерского.
Хотя с пары постов и картинок я даже посмеялся, неплохо, уже тогда были все задатки твиттерского.