Telegram Web
#prog #go #article

How we found a bug in Go's arm64 compiler

TL;DR: для горутин с большим стеком (больше, чем может быть закодировано в литерале в одной инструкции на ARM) в эпилоге функций изменение sp, регистра, указывающего на верхушку стека, происходило через две операции ADD, обе из которых оперировали на sp непосредственно. Если переключение (preemption) между горутинами происходило между этими двумя операциями, любые операции, которые разворачивали стек — в частности, сборщик мусора — следовали вверх по стеку вызовов по частично обновлённому и потому невалидному значению из sp, и в результате предсказуемо крашились.

Может, ввести отдельный хештег для историй дебага? 🤔
🤡7👍51😱1🌚1
#prog #article

Cloudflare just got faster and more secure, powered by Rust

Про то, как в Cloudflare заменяют (пока что не довели до конца, но закончат к началу 2026 года) так называемый FL, центральный компонент своих сервисов. Заголовок несколько вводит в заблуждение: Rust определённо помогает, но большая часть хороших вещей из новой версии связана с архитектурой.

Одна из вещей, которая даёт преимущество новой версии — разделение на модули, каждый из которых сам по себе не занимается IO и явно перечисляет, что он принимает на вход и что возвращает. Это не только даёт возможность на уровне архитектуры явно видеть, как модули зависят друг от друга, но и позволило интегрировать модули в предыдущую версию FL, чтобы избежать параллельной поддержки двух версий одних и тех же функций во время перехода с одной версии на другую.

Отдельно хочу отметить, что часть про отсутствие IO язык с системой эффектов (даже такой примитивной, как в Haskell) мог бы предовтращать надёжно на уровне компилятора, а не соглашений, так что конкретно тут Rust не помогает.
👍6🤡2🤔1
Блог*
конкретно тут Rust не помогает
This media is not supported in your browser
VIEW IN TELEGRAM
😁11❤‍🔥3🤡3💯31👍1
+1
🎉6🤡1
#prog #article

Know your SCM_RIGHTS

TIL что в Linux (на самом деле UNIX) есть способ передавать файловые дескрипторы между процессами. И эти файловые дескрипторы могут быть в том числе TCP- и UDP-сокетами.
👍6😍3🤡2👌1
#prog #cpp #rust #article

Why we didn't rewrite our feed handler in Rust

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

Первое касается ограничений borrow checker-а. Вот какой пример приводят:

fn process_source(sources: Vec<Source>) {
for source in sources {
let mut buffer: Vec<&[u8]> = Vec::new();
let data: Vec<u8> = source.fetch_data();
buffer.extend(data.split(splitter));
process_data(&buffer);
}
}


Простой и понятный код — но, к сожалению, выделяющий память в цикле. Логично было бы вынести аллокацию за цикл и очищать буфер в конце — но тогда компилятор не даёт скомпилировать код:

error[E0597]: `data` does not live long enough
--> src/lib.rs:32:23
|
31 | let data: Vec<u8> = source.fetch_data();
| ---- binding `data` declared here
32 | buffer.extend(data.split(splitter));
| ------ ^^^^ borrowed value does not live long enough
| |
| borrow later used here
33 | process_data(&buffer);
34 | }
| - `data` dropped here while still borrowed


Второй паттерн — самоссылающиеся структуры, известная больная тема в Rust.

Третий паттерн — множество определений разных версий и унифицированный код для работы с ними (из-за необходимости поддержки разных версий схем обмена данных, насколько я понял). Пример из статьи на C++:

struct RecV1 {
uint32_t x;
uint32_t y;
}

struct RecV2 {
uint32_t x;
uint32_t y;
uint32_t z;
}


Унифицированный код для работы с обоими этими типами можно написать при помощи шаблонов:

template <typename T>
T InitRec() {
T res;
res.x = 1;
res.y = 2;
if constexpr(std::is_same_v<T, RecV2>()) {
res.z = 3;
}
return res;
}


Нетрудно видеть, как это обобщается на случай большего количества полей и различных версий. В Rust можно попробовать сделать нечто подобное, но это вырождается в бойлерплейт, облегчать который приходится макросами — иными словами, попытка повторить шаблоны из C++.
👍10🤡6🔥1
Блог*
#prog #cpp #rust #article Why we didn't rewrite our feed handler in Rust Отдельно отмечается, что Rust в технологическом стеке в этой компании уже есть и успешно используется. Проблемы возникли с переписыванием конкретного компонента, который уже есть и…
Надо отметить, что первый пример с оптимизацией действительно не компилируется в лоб, но это не значит, что от аллокации в цикле нельзя избавиться. Именно, вот такой код с использованием bumpalo компилируется:

fn process_source(sources: Vec<Source>) {
let b = bumpalo::Bump::new();
for source in sources {
let data = source.fetch_data();
let mut buffer = bumpalo::collections::Vec::new_in(&b);
buffer.extend(data.split(splitter);
process_data(&buffer);
}
}


В этом коде арена, которая в реализации и выделяет память, конструируется один раз за пределами цикла и позволяет переиспользовать память, но версия вектора из bumpalo создаётся заново на каждой итерации и потому может позволить себе иметь время жизни, сравнимое с временами жизни переменной итерации. Вызывать при этом явно .clear() за счёт RAII не требуется.
🤔6🤡4🤮1
Блог*
+1
+1
🤷73🤡3👍1
#meme про кота

(thanks @memegelion)
😁15🤡9🌚74
😁21🤡1
Почему "национализация" означает "переход в собственность государства", а не "превращение в страну"?
🤔4👍2🤡2😁1
Демидович -> Demidovich -> Полуголубкин

(#лингво)
😁20🤡2🍌2👍1
🤡13💯4😭2👌1
#prog #rust #abnormalprogramming

fibonacci-numbers crate with self-recursive dependencies

I have created a crate called fibonacci-numbers. There are 187 different major versions of the crate, each exporting the Fibonacci number corresponding to that version.
<...>
Version 186 depends on version 184 and 185 and exports the largest Fibonacci number that fits in a u128:


pub const VALUE: u128 = fib184::VALUE + fib185::VALUE;
😁27🔥7🤡4🤯1
#meme про Github
😁151🤡1
#prog #article

That boolean should probably be something else

By storing a boolean as our data, we're coupling that data tightly to our application logic.

Instead, we should remain critical and ask what data the boolean depends on, and should we maybe store that instead?


Да, про сумм-типы там тоже упоминается.
🤡1
#prog #abnormalprogramming

spellscript

esotoric [sic!] programming language that's read like a spellbook


begin the grimoire.
summon the power with essence of 7.
conjure ritual named amplify with value to return value multiplied by value.
enchant power with essence 0 of through ritual amplify with power.
inscribe whispers of "the power is amplified: " bound with power.
close the grimoire.

output: the power is amplified: 49
8🤡4🤯1
2025/10/13 23:16:37
Back to Top
HTML Embed Code: