commit -m "better"
2.96K subscribers
873 photos
106 videos
3 files
2.08K links
just random thoughts
Download Telegram
#musl

https://lobste.rs/s/osfunr/musl_preprocessor_debate
https://catfox.life/2022/04/16/the-musl-preprocessor-debate/
https://www.openwall.com/lists/musl/2013/03/29/13

Я уже как-то писал про сумасшедших авторов Musl, которые никак не хотят запилить
#define __MUSL__

Как ни странно, я немного поменял свое мнение, хотя и мои новые аргументы не подкрепляют точку зрения Ричарда Фелкера.

Мои аргументы:

* мало кто использует musl с аллокатором из musl, потому что аллокатор из musl сосет.

* стандарты на аллокатор - очень размытое понятие, потому что они менялись со временем, и некоторые функции тупо не стандартизированы(reallocarray, о которой я писал в прошлом посте).

* mimalloc(который я использую вместе с musl) недавно поменял свое поведение(оба поведения имеют право на существование) - конкретно, malloc(0) возвращал уникальный указатель, а теперь может возвращать nullptr.

* исходя из всего этого, потребители не могут пользоваться
__MUSL__
, для того, чтобы проверить свойство аллокатора - нужен configure-time тест.

Дело, конечно, усложняется кросс-компиляцией, и невозможностью получить нужную информацию через configure-time test, но что тут поделать.

Отдельно отмечу, от смены версии mimalloc сломалось прямо очень много configure-time тестов, и я предлагаю из этого сделать такие выводы:

- #semver не работает. Только тесты, только хардкор.

- LD_PRELOAD на аллокатор - так себе затея, потому что довольно много кода полагается на определенное поведение аллокатора, и в момент configure включает врапперы для неподходящих аллокаторов. LD_PRELOAD эту логику ломает.

Кажется, совсем иделаьное решение - подставлять все нужные флажки в configure/cmake/meson/etc в системе построения пакетов, но, кажется, это утопично.

Конечным потребителям musl вполне можно продолжать иметь свой
#define __MUSL__
, потому что для них он продолжает нести вполне понятную семантику.
🔥2👍1
И последняя новость из мира LLVM на сегодня.

https://llvmweekly.org/issue/458

"LLVM’s libc gained implementations of fork, rand, srand, waitpid, wait4, execv, execve, kill, strerror_r, and strsignal functions. e3638e8, 38b6f58, 995105d, 3f96581, 9015810, a9f95b7, 07793f9"

Коллеги прямо очень быстро пишут libc от LLVM.

Я осторожно скажу, что не ожидаю ее готовность к концу 2022, но вот в первой половине 23 надеюсь уже "пощупать" (ЕБЖ, конечно).

Лично для меня это самый ожидаемый проект от экосистемы LLVM(после, собственно, самой llvm/clang/lld), потому что, писал и буду писать, авторы что #glibc, что #musl - негодяи с завышенным ЧСВ, и появление еще одного конкурента на этой делянке - это very appropriate.
👍8
Мне тут посоветовали вместо #mosh использовать https://eternalterminal.dev

Я не знаю, как оно работает, и, весьма вероятно, не узнаю, потому что это какая-то пионерская поделка. Как-то рассказывал про #kitty, вот, примерно из той же оперы - говнокод, работающий исключительно благодаря огромным вложенным усилиям.

Он, знаете ли, падает у меня, причем очень настойчиво, я фикшу одну ошибку, он падает где-то еще:

pg-> et [email protected]
Could not reach the ET server:
pg.vla.yp-c.yandex.net:2022

pg-> et -u pg pg.vla.yp-c.yandex.net
Segmentation fault

Штоа?

* Падал при любой попытке вывести исключение. Почему?

376   numFrames = backtrace(stack, 
MAX_STACK_FRAMES);
377 memmove(stack, stack + 1,
sizeof(void *) * (numFrames - 1));

Ну, например, потому что у меня backtrace() возвращает 0, потому что без frame pointer вывести стектрейс - дорогое удовольствие, #musl не умеет. 0 - нормальный результат, https://man7.org/linux/man-pages/man3/backtrace.3.html

* Кидал исключение даже до того, как печатал —help. Почему? Потому что, перед тем, как сделать что-то разумное, пытался перенаправить stderr в файл, и, при этом, содержал некорректную реализацию GetTempDirectory() - https://github.com/MisterTea/EternalTerminal/blob/master/src/base/Headers.hpp#L384 (кто так делает, в 21 веке???), при попытке открыть файл в которой летело исключение. Далее смотри пункт 1. Вообще, неправильное получение tmp dir - этим много кто грешит, поэтому я даже запилил микробиблиотечку, которой патчу клиентов по месту - https://github.com/pg83/ix/blob/main/pkgs/bin/et/ix/ix.sh#L26 https://github.com/pg83/ix/tree/main/pkgs/lib/shim/ix

Настраивать логгирование до парсинга command line - это так-то клиника.

Оно у меня снова падает, и я не уверен, что хочу продолжать этот квест.
😁7🔥5👍3🤯1🍌1
https://lwn.net/SubscriberLink/920158/313ec4305df220bb/

https://www.opennet.ru/opennews/art.shtml?num=58532

Ядрописатели решили запилить свою libc, для "small, low-level" приложений.

По первой ссылке жалкая попытка обосновать этот проект. Жалкая, потому что автор решил сравниться с какими-то калеками, типа diet libc, uclibc, которые не развиваются много лет.

С #musl сравнения, очевидно, нет, потому что если бы оно было, то было бы очевидно, что #nolibc не нужна.

Оч. странный продукт, ни одного .c файла, все заинлайнено в .h файлах - https://elixir.bootlin.com/linux/v6.2-rc4/source/tools/include/nolibc

Зачем так делать, если есть ориентация на минимальный размер получающегося кода?

https://elixir.bootlin.com/linux/v6.2-rc4/source/tools/include/nolibc/stdio.h#L32 - а вот так вот сделаны stdin, stdout, stderr. Rust, как тебе такое?

Nevertheless, это поделие может быть мне полезно, на самой первой стадии, когда надо собрать musl "из ничего", даже без стандартных unix tools, типа cp, mv, и так далее.

Думаю, вполне можно собрать простые версии unix tools с этой libc, и дальше, пользуясь ими, по человечески собрать #musl.
🤡10👍6😁1
https://www.phoronix.com/news/Wine-8.6-Released

#wine решили забандлить libm из #musl.

Это, конечно, хорошая тема. Потому что позволяет wine runtime еще меньше зависеть от системы.

Если не можешь статически собрать весь код - то собери статически (ну или, хотя бы, по жестким версиям исходников динамически) свой runtime.
🔥7👍4🤔3👎1
commit -m "better"
Как говорится, доверяй, но проверяй! Я тут, случайно, в выводе pstree увидел красивое: flock---unbound Глаз за это зацепился, потому что я сразу подумал, что тут что-то не то, дерево процессов должно было выглядеть так: flock---timeout---unbound Ну,…
#unbound #musl #dns #dnsmasq

Перешел с unbound на dnsmasq, по советам коллег.

(да, я понимаю, что это продукты несколько разных масштабов, потому что unbound - настоящий рекурсивный dns resolver, а dnsmasq - "просто" кеширующая прокся (+dhcp +говна самовар), я их использовал для одного и того же)

pg# ls -la /ix/.../bin/unbound 
... 5683992 unbound
pg# ls -al /ix/.../bin/dnsmasq
... 2948464 dnsmasq

dnsmasq (вроде) не виснет, и весит меньше.

Заодно сделал использование локального кешера обязательным, потому что musl без этого так себе работает - https://wiki.musl-libc.org/functional-differences-from-glibc.html#Name-Resolver/DNS, а люди потом жалуются на alpine - https://martinheinz.dev/blog/92

Коллеги посоветовали посмотреть в сторону #systemd-resolvd, но, КМК, они так шутят, потому что, будучи статически слинкованным, он будет под сотню мегабайт весить, наверное.
👍6🤔2🔥1
Вышел новый #musl, https://musl.libc.org/releases.html

Постоянство - признак мастерства, новые версии выходят раз в год, примерно в одно и то же время.

Запилили в dns resolver поход по TCP, вот только я приспособил #dnsmasq, ага.

Убрали макросы stat64, lstat64, и прочее барахло для совместимости с API glibc. Сломали сборку примерно всего кода, ожидающего glibc-style API по поддержке 64-битных оффсетов, печаль-беда.
👍7🔥2👎1🌭1
Ночной (уже) #rant

У меня продолжает бомбить от обновления #musl, да.

Есть такое, довольно популярное мнение, что мы "должны" open source'у, и что надо тащить все изменения в #upstream, неважно, насколько там упоротые мейнтейнеры.

Я с этим категорически не согласен, ничего мы никому не должны, кроме того, что написано в файле LICENSE.txt.

Вот, возьмем данную ситуацию.

Что я якобы "должен" сделать?

* Сходить к Ричарду Фелкеру, и попытаться его убедить, что надо дать людям возможность узнать версию musl, с которой ты собираешься, чтобы по этой информации сделать какой-либо вывод? Да щаз, он в readme своего проекта написал, что этого не будет никогда (https://wiki.musl-libc.org/faq.html "Why is there no MUSL macro?"), а он же не может ошибиться?

* Сходить к авторам configure/autoconf скриптов, и рассказать, как "правильно" детектить наличие тех или иных фичей? Так никто не знает, как "правильно", даже Фелкер, потому что есть тесты на собираемость, и есть тесты на linkability, и они в C/C++ могут давать разный результат, из-за "define pread64 pread" https://git.musl-libc.org/cgit/musl/tree/include/unistd.h#n203 - какой-то класс тестов может не скомпилироваться, какой-то - не слинковаться.

* Сходить к авторам rust (компания пидорасов, не забываем про это!), и сказать им, что не надо руками писать интерфейсы к libc - https://github.com/rust-lang/rust/blob/master/library/std/src/sys/unix/mod.rs#L98 ?

К кому из этих трех обобщенных высокомерных мудаков мне сходить? В чем убедить?

Правильно, я пойду к самому близкому ко мне высокомерному мудаку с сильным мнением - к себе!

Мое "сильное мнение" в данном вопросе - не надо чинить то, что не сломано, и пошел бы Фелкер со своим мнением к херам.

Он удалил функции, я их вернул назад. Без патчинга исходников, просто скопировал символы - https://github.com/pg83/ix/commit/632e40fdcb56917c19f9299c165b56d77052675b#diff-d0dfd80046e1a8679abbcdebbc7ee3984b5b75653d63cc2469ec0ee6427b7c20R25

Думаю, я в хорошей компании!
😁21👍114
Больше всего проблем с обновлением #musl (https://t.iss.one/itpgchannel/1721) мне доставил их отказ от эмуляции "GNU basename".

Коротенько расскажу, что это такое.

Вот basename от POSIX:

https://www.opennet.ru/man.shtml?topic=basename&category=3&russian=2

#include <libgen.h>

char *dirname(char *path);
char *basename(char *path);


Обратите внимание, что этот basename принимает mutable path, и он реально его может иногда модифицировать!

Проекту #GNU этого показалось мало, и они соорудили херобору:

https://man7.org/linux/man-pages/man3/basename.3.html

#define _GNU_SOURCE
#include <string.h>


There are two different versions of basename() - the POSIX version described above, and the GNU version, which one gets after. The GNU version never modifies its argument, and returns the empty string when path has a trailing slash, and in particular also when it is "/". There is no GNU version of dirname(). With glibc, one gets the POSIX version of basename() when <libgen.h> is included, and the GNU version otherwise.

Подумайте над следующим:

* Как это, блядь, вообще работает?

* Как работают configure скрипты, которые пытаются понять, какой же basename будет реально вызван?

* Что будет, если какой-то проект забудет у себя принудительно выставить _GNU_SOURCE, и (если!) сконпелируется с POSIX вариантом?

* Наоборот, случайно выставит _GNU_SOURCE, когда он не ожидается?

Ну, вот, musl убрал из string.h эту магию, и, ВНЕЗАПНО, это сломало сборку какого-то количества софта.

На самом деле, изменение так-то неплохое, потому что фанаты Alpine набигут на upstream проекты, и пофиксят их, чтобы в них выбор реализации не зависел от libc/всратых макросов/порядка включения заголовков.
😁11👍9🔥4🤔2🤯2