LINUX.ORG.RU

Продемонстрирована возможность разработки частей Linux на Rust

 , ,


4

9

Французский программист написал статью, в которой рассмотрел возможность переписывания ядра Linux на Rust.

В статье отмечено, что данный язык хорошо подходит для системного программирования, будучи достаточно низкоуровневым и при этом лишённым многих недостатков C, и уже используется для написания новых ОС. Однако автор не считает создание ОС с нуля перспективным для серьёзного применения, и последовательный перенос отдельных частей Linux на Rust для решения различных проблем безопасности кажется ему более целесообразным.

В качестве «Proof of Concept» была приведена реализация системного вызова, содержащая вставки на Assembler внутри unsafe-блоков. Код компилируется в объектный файл, не связанный с библиотеками и интегрируемый в ядро во время сборки. Работа производилась на основе исходного кода Linux 4.8.17.

>>> Статья



Проверено: Shaman007 ()
Последнее исправление: sudopacman (всего исправлений: 5)

Ответ на: комментарий от eao197

Вот повсеместное использование Result-а в Rust-е так же со стороны выглядит как фича, которую добавили в язык ради блага. Но когда смотришь код на Rust-е, то выясняется, что разработчику приходится очень много внимания уделять этому самому Result-у. Там, где в другом языке можно было бы вернуть Data, в Rust-е нужно возвращать Result<Data, ...>. Там, где в другом языке можно сделать простую цепочку вызовов, в Rust-е нужно обмазываться try! или новым ?. Там, где в других языках просто берется и используется возвращенное значение, в Rust-е нужно делать какой-то вариант match-а. Ну и все эти unwrap_or/unwrap_or_default и пр.

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

Может быть, при написании низкоуровневого кода так и следует делать. Но если брать задачи чуть повыше (например, MQ-брокеры, сервера СУБД, какие-то CAD системы), то в них уже ситуация может быть другой. Откуда и соблазн свести работу с Result-ами к самому минимуму.

Result — это маркер. Он показывает программисту, какой метод может завершится ошибкой. Глядя на:

public void foo() {}

Не ясно, будет ли ошибка, пока мы не заглянем в документацию или тело метода.

public void foo() {
    bar();
    baz();
    foobar();
}

Программист не знает, откуда вылетит исключение, пока не выполнит особые условия по генерированию исключения, или не прочитает документацию по всем методам которые он вызывает. Да это немного разгружает код, но выливается в более длительное чтение документации и/или тестирование. В Rust такое невозможно, так как даже не скомпилируется. Программист обязан предусмотреть обработку всех ошибок, что обязательно и в других языках, но компилятор не поможет без checked exceptions.

unwrap_or/unwrap_or_default, опять заставляете меня повторяться. Выше я привёл пример, из которого очевидно, что такой метод даже разгружает код. Если бы его не было, то вы бы придирались к этому?

let value = match foo() {
    Ok(x) => x,
    Err(_) => 0,
};
numas13
()
Ответ на: комментарий от numas13

В Rust такое невозможно, так как даже не скомпилируется.

Ну так об этом и речь. Осталось только посмотреть, как это будет сказываться на массах: задолбет ли народ писать в стиле

let a = bar()?;
let b = a.baz()?;
let f = foo(a, b)?;
...
или нет. У меня лично пока есть ощущение, что меня бы задолбало.

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

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

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

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

В Rust-е есть паники. В Go есть паники.

В Ceylon-е и Kotlin-е есть исключения. В том же D есть исключения.

Что тут еще из нового, что в какой-нибудь степени претендует на мейнстрим?

eao197 ★★★★★
()

А кстати что там из самого живого/перспективного намечается на замену c/++ для личного байтоёбства c низким оверхедом? В с* поднадоел раздутый синтаксис на тривиальные вещи даже без учёта батареек.

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

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

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

Я про rust, go, swift. Ceylon и D уже старенькие. Kotlin - жаба, ей можно.

И да, паника - не исключение. Из доки:

Unlike an exception in Java or C++, a panic could not be caught at any time. Panics could only be caught by the owner of the task, at which point they had to be handled or that task would itself panic.

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

Я про rust, go, swift.

В swift есть исключения, если бы не ваше скудоумие, вы бы об этом могли бы узнать.

Ceylon и D уже старенькие.

Ceylon почти что ровесник Kotlin-а. И он так же для JVM.

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

И да, паника - не исключение.

Я как бы в курсе, что Rust-овская паника — это не нормальное исключение. Однако, сам факт того, что в Rust-е, не смотря на упоротость кодами возврата не смогли обойтись без механизма безусловного прерывания control flow с раскруткой стека и вызовом деструкторов Drop-ов, показателен. Аналогично и в Go, кстати говоря.

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

Однако, сам факт того, что в Rust-е, не смотря на упоротость кодами возврата не смогли обойтись без механизма безусловного прерывания control flow с раскруткой стека и вызовом деструкторов Drop-ов, показателен.

Показательно то, что некоторые люди не различают критические ошибки и ожидаемые.

quantum-troll ★★★★★
()
Ответ на: комментарий от quantum-troll

Показательно то, что некоторые люди не различают критические ошибки и ожидаемые.

Vec.split_off:

fn split_off(&mut self, at: usize) -> Vec<T>

Splits the collection into two at the given index.

Returns a newly allocated Self. self contains elements [0, at), and the returned Self contains elements [at, len).

Note that the capacity of self does not change.

Panics

Panics if at > len.

Паника из-за невозможности аллоцировать новый Vec — это вполне себе критическая ошибка. А вот почему паника из-за at>len? Неужели это не ожидаемая ошибка? Почему нельзя было сделать сигнатуру вида:

fn split_off(&mut self, at: usize) -> Result<Vec<T>,Box<Error>>
?

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

Насколько я знаю, в swift, исключения не более чем сахар над растовским Result. На исключения из C++/Java они почти не похожи.

Ceylon почти что ровесник Kotlin-а.

Ceylon 1.0 - 2013, Kotlin 1.0 - 2016.

не смотря на упоротость кодами возврата не смогли обойтись без механизма безусловного прерывания control flow с раскруткой стека и вызовом деструкторов Drop-ов

Это часть гарантий языка. Обработка ошибок тут сборку.

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

Почему нельзя было сделать сигнатуру вида:

Баланс между надёжностью и удобством.

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

Та же история, что и с доступом к элементу массива по индексу. Если лезем за границу массива, значит ошибка раньше по коду при вычислении индекса. Код возврата в исправлении этой ошибки не поможет.

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

Насколько я знаю,

По ссылке сходите, документацию почитайте.

Ceylon 1.0 - 2013, Kotlin 1.0 - 2016.

Их разработка началась где-то около 2011-го. Практически в одно время. Доступные для использования превью Kotlin-а появились вскоре после Ceylon 1.0.

Это часть гарантий языка. Обработка ошибок тут сборку.

Исключения, по вашей логики, частью гарантий языка не являются. Так и запишем.

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

Их разработка началась где-то около 2011-го.

Rust тоже появился давно. Только 0.1 и 1.0 - два разных языка. Не знаю как у Ceylon и Kotlin, но предположу, что у них тоже были серьезные изменения на пути к 1.0.

Это часть гарантий языка.
Исключения, по вашей логики, частью гарантий языка не являются.

Шта? Я написал ровно обратное.

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

Та же история, что и с доступом к элементу массива по индексу.

Суть в другом: когда в некий метод пользователем передается аргумент, ожидает ли метод некорректного значения этого аргумента или нет. Если ожидает, то где грань между критической ошибкой и ожидаемой?

Если лезем за границу массива, значит ошибка раньше по коду при вычислении индекса.

Определенно.

Код возврата в исправлении этой ошибки не поможет.

Это зависит от прикладного кода. Почему при парсинге числа из строки возвращается Result, а при индексации массива — паника? Хотя и там, и там некорректные входные значения — это нормально?

Посмотрите на ситуацию с точки зрения прикладного кода: я обрабатываю какую-то информацию, делаю какое-то сложное вычисление индекса и допускаю ошибку в этом вычислении. Ошибка возникает не всегда, а в определенных ситуациях. Получится, что в большинстве случаев мой код будет работать нормально, а иногда будет возникать паника. Которая будет ломать работу целой рабочей нити!

Хотя весь код может быть обмазан синтаксическим сахаром ? и доступ по некорректному индексу в моей ситуации мог бы точно так же привести к возврату отрицательного Result-а куда-то выше. Без прерывания всей работы на этой нити.

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

Шта? Я написал ровно обратное.

Расслабьтесь, вы явно пытаетесь превысить свои умственные способности.

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

а при индексации массива — паника

Всегда есть get() -> Option<T>. То есть у программиста есть выбор гарантий.

RazrFalcon ★★★★★
()
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от eao197

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

Ну уж по серьёзней чем Ваше личное мнение. 19 проектов из лаборатории https://en.wikipedia.org/wiki/Research_Triangle_Park размерность такова:

The product development activity ranges in size from about 1 thousand (KLOC) to about 1 million lines of new or modified code.

А уж заключение, так вообще песня: вроде как никаких преимуществ ООП не дает, но хрен знает почему так.

Статистическими методами преимущество выявить не удалось. Нет ни каких доказательств о преимуществе ООП. А не «вроде» и не «хрен знает почему».

Our results indicate that in a commercial environment there may not be a consistent statistically significant difference in the productivity of object-oriented and procedural software development, at least not for the first couple of generations of an object-oriented product.

А вот если вы на C++ будете делать сложное десктопное приложение, типа CAD-а, то без ООП (хотя бы в виде библиотеки уровня MFC/wxWidgets/Qt) далеко не уедите. Это уже было хорошо показано в 1980-х и 1990-х.

Я могу взять GTK+ и Rust, по скорости разработки вряд ли будет какая-то разница между аналогичной библиотекой и С++. В пример Gnome, Wireshark и gCAD3D.

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

Статистическими методами преимущество выявить не удалось.

На выборке из всего 19 проектов, где хотя бы один был размером 1KLOC? Чему удивляться.

Нет ни каких доказательств о преимуществе ООП. А не «вроде» и не «хрен знает почему».

Ну так почитайте, что там написано:

Our results indicate that in a commercial environment there may not be a consistent statistically significant difference in the productivity of object-oriented and procedural software development, at least not for the first couple of generations of an object-oriented product. The reason may be low reuse level, but it could also be the underlying business model.

Т.е. эти убогие результаты показывают, что может и не быть статистически значимой разницы между ООП и процедурным подходом. По крайней мере на первых итерациях. Может быть из-за небольшого уровня переиспользования, а может быть из-за бизнес-модели.

Одни «может».

Я могу взять GTK+ и Rust, по скорости разработки вряд ли будет какая-то разница между аналогичной библиотекой и С++.

А GObject по-вашему — это не попытка изобразить ООП на чистом Си? Ну так заглянули бы в документацию:

GObject, and its lower-level type system, GType, are used by GTK+ and most GNOME libraries to provide:

  • object-oriented C-based APIs and
  • automatic transparent API bindings to other compiled or interpreted languages.

Таки от ООП настолько никаких выгод, что пришлось для C GObject городить, без которого GTK+ не было бы.

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

На выборке из всего 19 проектов, где хотя бы один был размером 1KLOC? Чему удивляться.

1KLOC - Это про активность развития проекта, а не про исследуемый размер.

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

Мужик, ты что мне пытаешься доказать? Ты понимаешь, что это исследование, целью которого не было найти причину почему ООП сливает, но они делали предположения, и это не основная цель исследования, они не обязаны были выяснить причину. А вот что они таки выяснили на 100%, что на ляме строк кода нет разницы структурное подход был использован или ООП.

А GObject по-вашему — это не попытка изобразить ООП на чистом Си?

Да какая разница, можно хоть WinAPI в пример привести, это не является ООП в том виде которое есть в С++. И в Rust нет классического ООП и без него можно жить.

После разговора с вами я до сих пор считаю, что то ООП которое есть в С++, не даёт ни каких плюсов. Вот в Rust нет ООП и слава Богу. И до сих пор считаю, что то ООП которое есть в С++ не правильное, почему уже писал.

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

1KLOC - Это про активность развития проекта, а не про исследуемый размер.

Да, это сразу меняет дело.

Мужик, ты что мне пытаешься доказать?

Вам? Ничего.

А вот что они таки выяснили на 100%, что на ляме строк кода нет разницы структурное подход был использован или ООП.

На выборке из 19 проектов достоверность этого исследования находится где-то в районе плинтуса. Т.е., если это были все проекты одной конкретной лаборатории, то для них этот результат значим. Для всего остального мира — нет.

Да какая разница, можно хоть WinAPI в пример привести, это не является ООП в том виде которое есть в С++.

Ну вот и в Java ООП не такое. И в Eiffel. ООП от этого никуда не девается. И то, что C-шные проекты (не только GTK, но и в openssl ООП-шный стиль) вынуждены подходы ООП использовать, как раз является хорошим подтверждением выгод от ООП. По меньшей мере в отдельных областях.

После разговора с вами я до сих пор считаю, что то ООП которое есть в С++, не даёт ни каких плюсов.

Кто ж вам запретит.

Вот в Rust нет ООП и слава Богу.

Аминь. Но тут другое интересно: несколько привлекателен бы был Rust, если бы в нем поддержку ООП сделали более традиционной. И были бы от этого какие-нибудь выгоды.

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

Аминь. Но тут другое интересно: несколько привлекателен бы был Rust, если бы в нем поддержку ООП сделали более традиционной. И были бы от этого какие-нибудь выгоды.

Вооот, видимо в этом корень всех с вами споров. Прикол в том, что там другая идеология. Rust'у не нужно классическое ООП. Там есть базовые типы к которым подмешивается функциональность. Вы читали про типажы в Rust?

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

Насколько я знаю, им надоело делать собственный LFS и сейчас все собирают Debian 8.

Они официально заявляли недавно, что в конце 2017 представят свою ОС с нескучными обоями под свою архитектуру, отконпеленную их канпелятором.

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

О том, что если какой-то Вася Пупкин в своей библиотеке написал какую-то дичь, которая ломает в процессе работы функции значения по адресам a и b, то в Си вы об этой уязвимости узнаете только в рантайме

Неосилятор C детектед.

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

Вооот, видимо в этом корень всех с вами споров.

Да??? У меня было другое ощущение: вы высказываете заблуждение, а когда вам на него указывают, то единственный контраргумент с вашей стороны — это «я так думаю».

Rust'у не нужно классическое ООП.

Это понятно. Понятно и то, что есть люди, которым именно это в Rust-е и нравится. Интересно, повторюсь, другое: насколько привлекательнее для всех остальных был бы Rust при иных раскладах? Ну или другими словами: насколько много людей считают отсутствие классического ООП в Rust-е недостатком Rust-а?

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

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

Дык, разве он чему-то научился? По моему, даже из той ситуации он вышел с уверенностью, что просто джависты уже и до GCC добрались.

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

У некоторых идиотов горит даже от не-гцц, потому что их говноподелки или не компилятся, или падают/виснут.

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

Очевидно, настоящие си-джедаи библиотеками не пользуются и в команде не работают

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

Без расширений (портированных в другие компиляторы, кстати говоря) нельзя сделать ARRAY_SIZE(), отличающий указатель от массива. И еще много других вещей. Просто C страдает от множества реализаций, тормозного коммитета и отсутствия модулей.

kirk_johnson ★☆
()
Последнее исправление: kirk_johnson (всего исправлений: 2)
Ответ на: комментарий от AntonyRF

Ну мужик, в современном мире константы не занимают памяти, если

стиль программирования на Си формировался 15 - 30 лет назад

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

И смотрим что получится:

Tuple!(bool, «ok», string, «what»)(false, "")
Data(«Hello», 0)

Я не вижу тут сообщения об ошибке

ну нужно же и в исходник заглядывать...

1) сообщение об ошибке в Ok.what, его надо самому распечатать: в fun writeln не стал вставлять,

2) fun и не пытается прочитать 2-ую строку, если её нет. Не совсем так, как в твоём оригинале, да, согласен, машинально сделал неправильно. Но fun(«Hello\n »); ошибку вернёт.

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

И кстати, чего это вдруг противопоставление композиции и ООП?

Всё из-за проблем связанных с наследованием, не трудно найти критику ООП и сравнение композиции vs наследования в сети.

композиция и наследование --- два, в общем, равноправных подхода в ООП. Равно как смешение этих подходов. И была масса статей на эту тему ещё в доинтернетовскую эпоху.

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

Вот видишь, твой «безопасный» D никак не спас тебя от совершения ошибки.

D сделал ровно то, что его попросили. Не пытаться прочитать строку, если её просто нет. Это ошибка (точнее, недопонимание) человека, написавшего алгоритм, который решил, что если строки нет, то так и должно быть.

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

Как должна выглядеть отсылка сообщения, отвечать или не отвечать на которое выбирает получатель

ну, тут есть варианты. Как выбирает? У получателя нет реализации необходимого метода, или он просто (в динамике) отказывается от выполнения(ответа)?

Тот-же D способен реализовать это при помощи opDispatch.

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

если чётко представляет, как и что работает «под капотом». Такие языки.

Вот я об этом и говорю, что в Rust о таких проблемах

думать не надо.

Так не бывает.

Утверждение явно неверно в сравнении Rust с С/С++

Посмотрим. При самом мягком подходе, даже в случае хобби — разработки, довлеет время. Практика показала, что языки, постоянно требовавшие излишне строгой спецификации, «не пошли».

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

Писать платформо-зависимый код, это призывают адепты С языков?

Нет. Си создавался более 30 лет назад, когда кросс — платформенный код не то что был редок, большинство товарищей считали, что он просто невозможен.

Но и сейчас, когда программист пишет код и совершенно не представляет, как работает процессор... боже мой, я регулярно вижу недоумение, когда у человека «на ровном месте» валится программа и он не может ничего понять... и подумать о стеке, ляму не хватает. Это неправильно и в консерватории что-то явно надо подправить.

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

Короче нужен компилируемый быстрый петон где можно писать прямо на сисвызовах, но и рядом же втыкать «батарейки»

D

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

И да, паника - не исключение. Из доки:
a panic could not be caught at any time. Panics could only be caught by the owner of the task, at which point they had to be handled or that task would itself panic.

В том-же D исключения бывают лёгкие и тяжёлые, в последнем случае дальнейшее выполнение программы невозможно. Чем это принципиально отличается (исключением оно быть вовсе не перестаёт)?

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

Rust'у не нужно классическое ООП.

Там есть базовые типы к которым подмешивается функциональность.

Ой, да ладно. ООП придумали, по большому счёту, чтобы моделировать сущности реального мира. По-видимому, реальные большие проекты в другой парадигме слишком сложно разрабатывать и поддерживать.

Раст решил сам себя ограничить, ну ладно, практика покажет.

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

Практика показала, что языки, постоянно требовавшие излишне строгой спецификации, «не пошли».

Практика показывает, что rust за два года взлетел выше D, которому уже больше 10 лет.

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

Я не знаю какие исключения бывают в D. Я приводил в пример исключения C++.

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

Тот-же D способен реализовать это при помощи opDispatch.

D может это реализовать только в compile-time. И, как я понимаю, D не может создавать dll/so-шки с экспортируемыми из них классами?

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

D сделал ровно то, что его попросили

C и C++ тоже делают только то что их попросили, однако это не особо помогает находить и исправлять ошибки.

чем это принципиально отличается от подходов, в других системах?

Покажи эти другие системы в которых гаранитируется отсутствие data races. Даже в таком ориентированном на многопоточность языке как Go, нет таких гарантий. Вместо этого они пользуются ThreadSanitizer чтобы ловить гонки в рантайме.

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