Суть в том, что crater — это внутренний гоняльщик тестов на всей экосистеме крейтов. Он использовался не только в этой ситуации, а вообще для любых экспериментов в финальной стадии.
Нет, это практика того, как это реально происходило в мире Rust за время существования стабильности.
Могу припомнить одну серьезную проблему — что-то там сделали то ли с ptr::copy, то ли с крейтом libc.
Сейчас вот намечается ещё одна волна потенциально серьёзных правок — когда старый unsound код принимался старым borrow checker'ом. Это не на пару минут.
А, вот оно что.
Так всё-таки, в чём именно проблема? Берите новый компилятор и новые библиотеки. Упомянутые депрекейшены на практике правятся за пару минут.
Это реально не страшная цена за прогресс языка и эта ситуация точно лучше, чем в мире C++.
Вы то ли специально передёргиваете, то ли в каком-то своём мире живёте.
Ну хотите использовать старый компилятор — используйте старый.
Хотите обновлять свой энтерпрайз когда надо — обновляйте когда надо.
В 2014 году библиотек на стабильном Rust не было — он вышел в 2015.
Бегать и фиксить депрекейшены за 4 года мне не приходилось ни разу — и зачем сразу бегать, если это warning? Если вы такие все консервативные, можете сидеть хоть на 1.0 до сих пор.
И у вас прекрасно продолжат компилироваться старые версии, даже если новым зачем-то понадобился более новый компилятор. В приложениях версии прибиты файлом с версиями.
Проприетарные библиотеки в смысле "нам кто-то дал бинари, но не исходники" в экосистеме Rust пока не использует никто. Там и с распространением будут проблемы. С другой стороны, а чем это хуже проприетарной библиотеки на C или C++?
А на тему аудита экосистемы есть интересные инициативы: 12.
В общедоступном выпущенном компиляторе никогда не было NLL в запрещающем режиме. Т.е. это делалось в рамках разработки очередной версии с целью проверки того, собственно, можно ли его сразу в запрещающем режиме включать.
Эти предупреждения ничем от deprecation warnings не отличаются.
Дыры в soundness надо же как-то чинить.
И ни один из этих языков не пересекается по нише с Rust.
Сравнивать rustls с openssl — нормально. Когда первая достигнет объёмов использования хотя бы в 10% от openssl, можно будет увидеть, что уязвимостей там правда меньше.
При этом не стоит забывать, что поиск уязвимостей тоже не стоит на месте. Благодаря ASLR, защите стека, DEP и другим прелестям, классическое переполнение буфера уже когда сложнее превратить в эксплуатируемую уязвимость — а значит внимание смещается на "менее технические" моменты, не связанные с конкретным языком программирования. Социальная инженерия, например, сильна как никогда.
Ох уж эти оптимизаторы на ассемблере.
Вы пробовали когда-нибудь написать максимально быстрый на ваш взгляд код для функции на ассемблере, а потом сравнить с кодом, сгенерированным компилятором при хотя бы -O2? Попробуйте.
И заработает, да. Потому что тут у вас один поток исполнения.
Это хорошо, что вас заставляют специально извернуться, чтобы указать, что вы собираетесь работать с куском памяти однопоточно. Когда по умолчанию считается, что можно, получается небезопасно.
И да, тут у вас всё равно остаётся механизм защиты, который можно описать как "run-time borrowing". К Cell это не применимо, т.к. там только Copy-типы, но RefCell паникует, если вы таки взяли одновременно 2 ссылки на запись.
А у вас какие-то особые требования, по которым вам надо сидеть на одной заранее выбранной версии компилятора?
Такое бывает, например, при сертификации, но в обычном продакшене вы просто обновляетесь раз в 6 недель на новый компилятор. Максимум что он привнесёт — warning'и о deprecation чего-либо. Чините их, и на следующую версию опять обновляетесь без проблем.
Обратную совместимость уже 4 года как не ломают.
Вообще это интересно, что вы коснулись mem::uninitialized. Как раз с ним был связан недавний RFC — эта функция теперь deprecated.
А почему? А как раз потому, что, как оказалось, факт создания значения определённого типа вне области определения этого типа — уже UB.
Это всё важно в первую очередь в контексте оптимизации. Если вы компилятор, и вам говорят, что вот тут bool — допустимые значения 0 и 1, то встретив код типа
let flag = false;
let x = 100500;
...
if flag {
x += 1;
}
вы можете соптимизировать этот код, основываясь на численном представлении bool. Если bool не 0 или 1, этот код будет работать неправильно. Но не только этот код. Возможно этот bool используется уже скомпилированным кодом стандартной библиотеки, например.
Поэтому да, странные эффекты могут начаться по всей программе. Но UB всё равно именно там, где нарушили инвариант — в unsafe.
Ошибки аллокации достаточно бесполезно ловить в пользовательской программе.
Во-первых, почти вся стандартная библиотека опирается на аллокатор, но если добавить тип ошибки в возвращаемые значения всех функций, которые выделяют память, пользоваться этим будет совершенно невозможно.
Во-вторых, как минимум на десктопных Linux по умолчанию включён overcommit, который делает невозможной локальную обработку ошибки выделения памяти.
В-третьих, если вы пишете прикладную программу, близкую к системной в плане управления ресурсами (веб-сервер, сервер БД), то у вас и так весьма особенные нужды в выделении памяти. Часто используются пулы, маппинг файлов/анонимной памяти прямо от системы. Куча в первую очередь интересна "совсем прикладным" программам, которым нехватка ресурсов неинтересна.
Суть в том, что crater — это внутренний гоняльщик тестов на всей экосистеме крейтов. Он использовался не только в этой ситуации, а вообще для любых экспериментов в финальной стадии.
Нет, это практика того, как это реально происходило в мире Rust за время существования стабильности.
Могу припомнить одну серьезную проблему — что-то там сделали то ли с ptr::copy, то ли с крейтом libc.
Сейчас вот намечается ещё одна волна потенциально серьёзных правок — когда старый unsound код принимался старым borrow checker'ом. Это не на пару минут.
Если она давно не обновляется никем не надо на неё залезать изначально.
Иначе вы берёте её на свою поддержку.
К winapi естественно используются биндинги, так что всё интересное там происходит на стороне C++-тулчейна, а не раста.
А, вот оно что.
Так всё-таки, в чём именно проблема? Берите новый компилятор и новые библиотеки. Упомянутые депрекейшены на практике правятся за пару минут.
Это реально не страшная цена за прогресс языка и эта ситуация точно лучше, чем в мире C++.
Вы то ли специально передёргиваете, то ли в каком-то своём мире живёте.
Ну хотите использовать старый компилятор — используйте старый.
Хотите обновлять свой энтерпрайз когда надо — обновляйте когда надо.
В 2014 году библиотек на стабильном Rust не было — он вышел в 2015.
Бегать и фиксить депрекейшены за 4 года мне не приходилось ни разу — и зачем сразу бегать, если это warning? Если вы такие все консервативные, можете сидеть хоть на 1.0 до сих пор.
И у вас прекрасно продолжат компилироваться старые версии, даже если новым зачем-то понадобился более новый компилятор. В приложениях версии прибиты файлом с версиями.
Проприетарные библиотеки в смысле "нам кто-то дал бинари, но не исходники" в экосистеме Rust пока не использует никто. Там и с распространением будут проблемы. С другой стороны, а чем это хуже проприетарной библиотеки на C или C++?
А на тему аудита экосистемы есть интересные инициативы: 1 2.
Нет, все вокруг сговорились и обманывают Siemargl!
Слышу звон, не знаю где он.
В общедоступном выпущенном компиляторе никогда не было NLL в запрещающем режиме. Т.е. это делалось в рамках разработки очередной версии с целью проверки того, собственно, можно ли его сразу в запрещающем режиме включать.
Эти предупреждения ничем от deprecation warnings не отличаются.
Дыры в soundness надо же как-то чинить.
Упоминать в этом разговоре суровую академию это даже неприлично.
И ни один из этих языков не пересекается по нише с Rust.
Сравнивать rustls с openssl — нормально. Когда первая достигнет объёмов использования хотя бы в 10% от openssl, можно будет увидеть, что уязвимостей там правда меньше.
При этом не стоит забывать, что поиск уязвимостей тоже не стоит на месте. Благодаря ASLR, защите стека, DEP и другим прелестям, классическое переполнение буфера уже когда сложнее превратить в эксплуатируемую уязвимость — а значит внимание смещается на "менее технические" моменты, не связанные с конкретным языком программирования. Социальная инженерия, например, сильна как никогда.
Ох уж эти оптимизаторы на ассемблере.
Вы пробовали когда-нибудь написать максимально быстрый на ваш взгляд код для функции на ассемблере, а потом сравнить с кодом, сгенерированным компилятором при хотя бы
-O2
? Попробуйте.И заработает, да. Потому что тут у вас один поток исполнения.
Это хорошо, что вас заставляют специально извернуться, чтобы указать, что вы собираетесь работать с куском памяти однопоточно. Когда по умолчанию считается, что можно, получается небезопасно.
И да, тут у вас всё равно остаётся механизм защиты, который можно описать как "run-time borrowing". К
Cell
это не применимо, т.к. там толькоCopy
-типы, ноRefCell
паникует, если вы таки взяли одновременно 2 ссылки на запись.А у вас какие-то особые требования, по которым вам надо сидеть на одной заранее выбранной версии компилятора?
Такое бывает, например, при сертификации, но в обычном продакшене вы просто обновляетесь раз в 6 недель на новый компилятор. Максимум что он привнесёт — warning'и о deprecation чего-либо. Чините их, и на следующую версию опять обновляетесь без проблем.
Обратную совместимость уже 4 года как не ломают.
Вообще это интересно, что вы коснулись
mem::uninitialized
. Как раз с ним был связан недавний RFC — эта функция теперь deprecated.А почему? А как раз потому, что, как оказалось, факт создания значения определённого типа вне области определения этого типа — уже UB.
Это всё важно в первую очередь в контексте оптимизации. Если вы компилятор, и вам говорят, что вот тут
bool
— допустимые значения0
и1
, то встретив код типавы можете соптимизировать этот код, основываясь на численном представлении
bool
. Еслиbool
не0
или1
, этот код будет работать неправильно. Но не только этот код. Возможно этотbool
используется уже скомпилированным кодом стандартной библиотеки, например.Поэтому да, странные эффекты могут начаться по всей программе. Но UB всё равно именно там, где нарушили инвариант — в unsafe.
Ошибки аллокации достаточно бесполезно ловить в пользовательской программе.
Во-первых, почти вся стандартная библиотека опирается на аллокатор, но если добавить тип ошибки в возвращаемые значения всех функций, которые выделяют память, пользоваться этим будет совершенно невозможно.
Во-вторых, как минимум на десктопных Linux по умолчанию включён overcommit, который делает невозможной локальную обработку ошибки выделения памяти.
В-третьих, если вы пишете прикладную программу, близкую к системной в плане управления ресурсами (веб-сервер, сервер БД), то у вас и так весьма особенные нужды в выделении памяти. Часто используются пулы, маппинг файлов/анонимной памяти прямо от системы. Куча в первую очередь интересна "совсем прикладным" программам, которым нехватка ресурсов неинтересна.
Вы сейчас описали практически как vagga работает — только без демонов и командной строки из 5 опций на пустом месте ;)
Понял, спасибо.
https://docs.docker.com/compose/compose-file/#restart