Forwarded from Код, коты и карандаш
Питон: язык, в котором программа запускается сразу, а потом ты её долго и мучительно отлаживаешь.
Хаскель: язык, в котором ты долго и мучительно компилируешь программу, а потом она работает.
Сиплюсплюс: язык: в котором ты долго и мучительно компилируешь программу, а потом долго и мучительно отлаживаешь.
#код
Хаскель: язык, в котором ты долго и мучительно компилируешь программу, а потом она работает.
Сиплюсплюс: язык: в котором ты долго и мучительно компилируешь программу, а потом долго и мучительно отлаживаешь.
#код
😁47💯16🔥1💩1
Код, коты и карандаш
Питон: язык, в котором программа запускается сразу, а потом ты её долго и мучительно отлаживаешь. Хаскель: язык, в котором ты долго и мучительно компилируешь программу, а потом она работает. Сиплюсплюс: язык: в котором ты долго и мучительно компилируешь программу…
Rust: долго и мучительно подбираешь чулки для проекта
🌚18😁10💩2🤔1
Forwarded from Кулешов разгоняет IT
Трансгендеры, Code Property Graph и при чём здесь AI
В мире анализа кода есть такая современная сущность: CPG — графовое представление программы, по сути привычное всем программистам дерево AST, дополненное CFG и PDG. Все крутые современные анализаторы стараются этим пользоваться.
И вот дают мне почитать свежую научную статью про то, как большие языковые модели можно подружить с CPG для поиска ошибок в коде.
Буквально в самом начале, в контексте межпроцедурного анализа, натыкаюсь на список литературы. Взгляд сразу подозрительно цепляется за пункт 28:
И дальше я минут десять искренне пытаюсь понять, не пролистнул ли я куда-то не туда и ту ли вообще статью открыл. Почему в контексте анализа кода внезапно появляется ежеквартальное исследование трансгендеров с названием Reveal?
“Раскрытие” (the reveal) — это момент в жизни трансгендерного человека, когда на него давит гендерная система, требующая «обнародовать правду» о теле или идентичности. Ну, думаю я: намоленный Запад окончательно оплёл всё повесточкой — даже в статьи про графы и анализ кода.
Сначала я проникся и глубоко изучил все грани собственной сексуальности. А затем понял простую вещь: уважаемые учёные из уважаемых университетов просто слепили эту статью с помощью ИИ, который перепутал фреймворк REVEAL для фронтендеров с ежеквартальным исследованием трансгендеров. Смеялся.
⚠️ UPD: Статья в таком виде принята на уважаемую USENIX conference 2025.
В мире анализа кода есть такая современная сущность: CPG — графовое представление программы, по сути привычное всем программистам дерево AST, дополненное CFG и PDG. Все крутые современные анализаторы стараются этим пользоваться.
И вот дают мне почитать свежую научную статью про то, как большие языковые модели можно подружить с CPG для поиска ошибок в коде.
Буквально в самом начале, в контексте межпроцедурного анализа, натыкаюсь на список литературы. Взгляд сразу подозрительно цепляется за пункт 28:
First, they typically focus on function-level analysis, overlooking crucial inter-procedural dependencies and broader program context [5,18,19,21,27,28,43].
[28] Danielle M Seid. Reveal. Transgender Studies Quarterly, 1(1–2):176–177, 2014. Danielle M. Seid is a PhD student at the University of Oregon, where she specializes in film/TV, queer studies, and critical race theory.
И дальше я минут десять искренне пытаюсь понять, не пролистнул ли я куда-то не туда и ту ли вообще статью открыл. Почему в контексте анализа кода внезапно появляется ежеквартальное исследование трансгендеров с названием Reveal?
“Раскрытие” (the reveal) — это момент в жизни трансгендерного человека, когда на него давит гендерная система, требующая «обнародовать правду» о теле или идентичности. Ну, думаю я: намоленный Запад окончательно оплёл всё повесточкой — даже в статьи про графы и анализ кода.
Сначала я проникся и глубоко изучил все грани собственной сексуальности. А затем понял простую вещь: уважаемые учёные из уважаемых университетов просто слепили эту статью с помощью ИИ, который перепутал фреймворк REVEAL для фронтендеров с ежеквартальным исследованием трансгендеров. Смеялся.
⚠️ UPD: Статья в таком виде принята на уважаемую USENIX conference 2025.
😁40❤🔥2👍1💩1
Блог*
#prog #rust #article How to speed up the Rust compiler in December 2025
#prog #rust
Одно из изменений, упомянутых в статье — это переделка fmt::Arguments (aka того, что возвращает format_args!). До этого изменения в структуре были три слайса (точнее, ссылок на них): слайс строковых составляющих форматной строки, слайс с опциями форматирования и слайс собственно аргументов (со стёртыми типами). Шесть машинных слов — это довольно много. После её изменения этот тип состоит из всего двух машинных слов: указатель на шаблон и указатель на аргументы, что позволяет передавать значения этого типа в регистрах.
Как это работает? Представление подробно расписано в исходниках, но если коротко: строка, описывающая шаблон, переписывается в байтовый массив, который содержит куски разных типов. В зависимости от префикса каждый кусок распознаётся как литерал строки, как ссылка на аргумент для форматирования или описание опций форматирования. Среди этих кусков также есть и маркер конца шаблона: ноль. Хранение конца шаблона внутри самого шаблона позволяет не хранить ни длину шаблона, ни длину слайса аргументов.
Как Мара пишет в Mastodon:
Надо отметить, что по сравнению со старым дизайном новый кое в чём проигрывает: отдельные литеральные части шаблона теперь лежат внутри неделимого массива и потому не могут быть дедуплицированы. На практике, впрочем, это не должно быть большой проблемой, поскольку зачастую эти строковые куски занимают меньше места, чем (толстые) указатели на них.
Одно из изменений, упомянутых в статье — это переделка fmt::Arguments (aka того, что возвращает format_args!). До этого изменения в структуре были три слайса (точнее, ссылок на них): слайс строковых составляющих форматной строки, слайс с опциями форматирования и слайс собственно аргументов (со стёртыми типами). Шесть машинных слов — это довольно много. После её изменения этот тип состоит из всего двух машинных слов: указатель на шаблон и указатель на аргументы, что позволяет передавать значения этого типа в регистрах.
Как это работает? Представление подробно расписано в исходниках, но если коротко: строка, описывающая шаблон, переписывается в байтовый массив, который содержит куски разных типов. В зависимости от префикса каждый кусок распознаётся как литерал строки, как ссылка на аргумент для форматирования или описание опций форматирования. Среди этих кусков также есть и маркер конца шаблона: ноль. Хранение конца шаблона внутри самого шаблона позволяет не хранить ни длину шаблона, ни длину слайса аргументов.
Как Мара пишет в Mastodon:
'Hello world' compiles 3% faster and a few bigger projects like Ripgrep and Cargo compile 1.5% to 2% faster. And those binaries are roughly 2% smaller. 🎊
Надо отметить, что по сравнению со старым дизайном новый кое в чём проигрывает: отдельные литеральные части шаблона теперь лежат внутри неделимого массива и потому не могут быть дедуплицированы. На практике, впрочем, это не должно быть большой проблемой, поскольку зачастую эти строковые куски занимают меньше места, чем (толстые) указатели на них.
GitHub
New format_args!() and fmt::Arguments implementation by m-ou-se · Pull Request #148789 · rust-lang/rust
Part of #99012
This is a new implementation of format_args!() and fmt::Arguments. With this implementation, fmt::Arguments is only two pointers in size. (Instead of six, before.) This makes it the ...
This is a new implementation of format_args!() and fmt::Arguments. With this implementation, fmt::Arguments is only two pointers in size. (Instead of six, before.) This makes it the ...
👍7🤔2❤1
Forwarded from Технологический Болт Генона
Cloudflare выложили разбор вчерашнего инцидента
Cloudflare outage on December 5, 2025
https://blog.cloudflare.com/5-december-2025-outage/
Попробую кратко описать чо там у них случилось, если где-то неправильно понял, то поправьте в комментариях
Как и писал CTO (https://news.1rj.ru/str/tech_b0lt_Genona/5926), они катили изменения для того, что бы закрыть свежую и нашумевшую уязвимость React'а (https://news.1rj.ru/str/tech_b0lt_Genona/5918, https://news.1rj.ru/str/tech_b0lt_Genona/5923)
Для этого они провели два действия:
- Они обнаружили что балалайка, котрая тестирует их WAF, не поддерживает нужный размер буфера тела HTTP-запроса, поэтому они её отключили (нужен был 1 MB, а умела только 128 KB)
- Выкатили практически моментально на все сервера изменения. Если я понял правильно, то они так настроили/сделали систему конфигурации после прошлого отвала - https://news.1rj.ru/str/tech_b0lt_Genona/5885
Как и в прошлый раз, сейчас тоже упоминаются две реализации их прокси - FL1 (старая, я не помню на чём, но там есть Lua) и FL2 (новая на Rust)
FL1 стало плохо после отключения балалайки, которая тестировала WAF и его правила, и начала "пятисотить". Происходило это из-за того, что поломался кусок, который отвечал за правила (Lua часть)
И это объясняет почему у части работало всё нормально, а у части нет. Проблем не было у тех чей трафик шёл через FL2
> Customers that have their web assets served by our older FL1 proxy AND had the Cloudflare Managed Ruleset deployed were impacted
> Customers that did not have the configuration above applied were not impacted. Customer traffic served by our China network was also not impacted.
Когда CF увидели, что всё посыпалось, то вообще должна была отработать система "отката". Но что-то пошло не так 🌝
Правила, когда отрабатывают, то выполняются определённые действия (в том числе и к трафику)
> Typical actions are “block”, “log”, or “skip”. Another type of action is “execute”, which is used to trigger evaluation of another ruleset.
Но как выяснилось они никогда не откатывали аварийно правила с типом execute и при откате сломавшего всё нового правила возникла ошибка в логике
> This code expects that, if the ruleset has action=”execute”, the “rule_result.execute” object will exist. However, because the rule had been skipped, the rule_result.execute object did not exist, and Lua returned an error due to attempting to look up a value in a nil value.
В FL2 проблемы не существовало такой, потому что, цитирую
> This is a straightforward error in the code, which had existed undetected for many years. This type of code error is prevented by languages with strong type systems.
Как утверждается в посте, что они извлекли уроки от прошлого масштабного падения и начали вносить изменения, но не успели за две недели доделать.
Короче, растпобеда случилась 🗿
Cloudflare outage on December 5, 2025
https://blog.cloudflare.com/5-december-2025-outage/
Попробую кратко описать чо там у них случилось, если где-то неправильно понял, то поправьте в комментариях
Как и писал CTO (https://news.1rj.ru/str/tech_b0lt_Genona/5926), они катили изменения для того, что бы закрыть свежую и нашумевшую уязвимость React'а (https://news.1rj.ru/str/tech_b0lt_Genona/5918, https://news.1rj.ru/str/tech_b0lt_Genona/5923)
Для этого они провели два действия:
- Они обнаружили что балалайка, котрая тестирует их WAF, не поддерживает нужный размер буфера тела HTTP-запроса, поэтому они её отключили (нужен был 1 MB, а умела только 128 KB)
- Выкатили практически моментально на все сервера изменения. Если я понял правильно, то они так настроили/сделали систему конфигурации после прошлого отвала - https://news.1rj.ru/str/tech_b0lt_Genona/5885
Как и в прошлый раз, сейчас тоже упоминаются две реализации их прокси - FL1 (старая, я не помню на чём, но там есть Lua) и FL2 (новая на Rust)
FL1 стало плохо после отключения балалайки, которая тестировала WAF и его правила, и начала "пятисотить". Происходило это из-за того, что поломался кусок, который отвечал за правила (Lua часть)
[lua] Failed to run module rulesets callback late_routing: /usr/local/nginx-fl/lua/modules/init.lua:314: attempt to index field 'execute' (a nil value)
И это объясняет почему у части работало всё нормально, а у части нет. Проблем не было у тех чей трафик шёл через FL2
> Customers that have their web assets served by our older FL1 proxy AND had the Cloudflare Managed Ruleset deployed were impacted
> Customers that did not have the configuration above applied were not impacted. Customer traffic served by our China network was also not impacted.
Когда CF увидели, что всё посыпалось, то вообще должна была отработать система "отката". Но что-то пошло не так 🌝
Правила, когда отрабатывают, то выполняются определённые действия (в том числе и к трафику)
> Typical actions are “block”, “log”, or “skip”. Another type of action is “execute”, which is used to trigger evaluation of another ruleset.
Но как выяснилось они никогда не откатывали аварийно правила с типом execute и при откате сломавшего всё нового правила возникла ошибка в логике
if rule_result.action == "execute" then
rule_result.execute.results = ruleset_results[tonumber(rule_result.execute.results_index)]
end
> This code expects that, if the ruleset has action=”execute”, the “rule_result.execute” object will exist. However, because the rule had been skipped, the rule_result.execute object did not exist, and Lua returned an error due to attempting to look up a value in a nil value.
В FL2 проблемы не существовало такой, потому что, цитирую
> This is a straightforward error in the code, which had existed undetected for many years. This type of code error is prevented by languages with strong type systems.
Как утверждается в посте, что они извлекли уроки от прошлого масштабного падения и начали вносить изменения, но не успели за две недели доделать.
Короче, растпобеда случилась 🗿
🔥4🤔2
#prog #c #article #abnormalprogramming
Серия из трёх (на текущий момент) статей о странностях C
Weekend projects: getting silly with C
Getting silly with C, part (void*)2
Getting silly with C, part ~(~1<<1)
Наверное, мои самый любимые примеры кода из статей — это многострочный комментарий:
и абьюз type punning-а на сигнатуре
Серия из трёх (на текущий момент) статей о странностях C
Weekend projects: getting silly with C
Getting silly with C, part (void*)2
Getting silly with C, part ~(~1<<1)
Наверное, мои самый любимые примеры кода из статей — это многострочный комментарий:
#include <stdio.h>
int main() {
puts("Hello world");
asm("/*");
/* Nested comment */
for (int i = 0; i < 10; i++) puts("I LIKE PANCAKES!");
asm("*/");
puts("Goodbye world");
}
и абьюз type punning-а на сигнатуре
main для доставания "Главного ответа о вселенной, смысле жизни и всего такого" из воздуха:#include <stdio.h>
int main(int i) {
do do do do "baby shark!";
while (++i % 2);
while (i == 2);
while (i % 3);
while (i % 7);
printf("The answer is %d.\n", i);
}
😁8👍2🤯2🍌1
Блог*
#prog #c #article #abnormalprogramming Серия из трёх (на текущий момент) статей о странностях C Weekend projects: getting silly with C Getting silly with C, part (void*)2 Getting silly with C, part ~(~1<<1) Наверное, мои самый любимые примеры кода из статей…
Для интересующихся, как это работает:
Форматирование кода скрывает тот факт, что в программе содержатся четыре вложенных друг в друга do-while цикла (это можно проявить, если отформатировать код). Для того, чтобы циклы завершились, нужно, чтобы после выхода из циклов
* кратно 2
* не равно 2
* кратно 3
* кратно 7
Так как 2 не кратно ни 3, ни 7, условие "не равно 2" избыточно. И действительно, если убрать один из
Тот факт, что в
main, вообще говоря, в C либо не принимает аргументов, либо принимает два: argc и argv. GCC даже указывает на это при компиляции с -Wall. В данной программе main имеет некорректную сигнатуру, но в силу того, как распределяются регистры для целевого ABI, первый аргумент для int main(int, char**) и int main(int) попадают в один и тот же регистр. Иными словами, при запуске этой программы в i попадает значение argc, и так как на godbolt по умолчанию программе никаких аргументов не прокидывается, i имеет значение 1 (первым аргументом OS передаёт название программы — так, например, работает busybox, который в одном бинарнике скрывает несколько программ и по этому аргументу выбирает, какую звать).Форматирование кода скрывает тот факт, что в программе содержатся четыре вложенных друг в друга do-while цикла (это можно проявить, если отформатировать код). Для того, чтобы циклы завершились, нужно, чтобы после выхода из циклов
i было:* кратно 2
* не равно 2
* кратно 3
* кратно 7
i начинает с 1 (точнее, 2 из-за преинкремента на первой итерации), наименьшим общим кратным 2, 3 и 7 является число 42, поэтому именно это значение принимает i и оно в итоге выходит на печать.Так как 2 не кратно ни 3, ни 7, условие "не равно 2" избыточно. И действительно, если убрать один из
do и второй while, то результат будет тот же.Тот факт, что в
i попадает именно значение argc, можно подтвердить, если добавить на gobolt окно с исполнением и докинуть аргументов командной строки для программы. Если туда вписать 41 значение, то argc будет равно 42, на первой итерации i станет равным 43 и потому программа выдаст следующее число, кратное 2, 3 и 7: The answer is 84.🤩4❤1🙏1