LINUX.ORG.RU

Избранные сообщения Bfgeshka

Поломался Gentoo при переезде на другой профиль

Форум — General

Переезжал на другой профиль, пересобирал sys-libs/glibc-2.26-r5 и при установке получил:

>>> needed    sym /lib32/libm.so.6
>>> needed    obj /lib32/libpthread-2.26.so
>>> needed    sym /lib32/libpthread.so.0
>>> needed    obj /lib32/librt-2.26.so
>>> needed    sym /lib32/librt.so.1
>>> Safely unmerging already-installed instance...
[Errno 80] Accessing a corrupted shared library: b'/bin/bash':
   /bin/bash -c /usr/lib/portage/python3.6/ebuild.sh clean
Traceback (most recent call last):
  File "/usr/lib64/python3.6/site-packages/portage/dbapi/vartree.py", line 2127, in unmerge
    preserve_paths=preserve_paths)
  File "/usr/lib64/python3.6/site-packages/portage/dbapi/vartree.py", line 1935, in _prune_plib_registry
    include_file=needed, preserve_paths=preserve_paths)
  File "/usr/lib64/python3.6/site-packages/portage/dbapi/vartree.py", line 3074, in _linkmap_rebuild
    self.vartree.dbapi._linkmap.rebuild(**kwargs)
  File "/usr/lib64/python3.6/site-packages/portage/util/_dyn_libs/LinkageMapELF.py", line 275, in rebuild
    proc = subprocess.Popen(args, stdout=subprocess.PIPE)
  File "/usr/lib64/python3.6/subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "/usr/lib64/python3.6/subprocess.py", line 1344, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
OSError: [Errno 80] Accessing a corrupted shared library: '/usr/bin/scanelf'

During handling of the above exception, another exception occurred:

Теперь ничего не запускается, говорит:

└─[127] <> uname
zsh: accessing a corrupted shared library: uname

Что делать?

 ,

panter_dsd
()

Красивый способ превращать числа в строки, заданные подобным #define IAC 0x01

Форум — Development

Не придумывается ничего, кроме массива строк. Массив сформировать sed/awk из #define

#include <stdio.h>

void main ()
{
  char * a[3] = {"DO",
		 "IAC",
		 "F\0z"};
  int i;

  for (i=0; i<3; i++) {
    printf("%s\n", a[i]);
  }
}

А в common lisp как можно?

 ,

panzerito
()

Академическая игрушка или вполне себе релальный поэкт? Запускаем GTA5 на видеокарте 2005 года

Форум — General

Примечание : все что здесь написанно - это всего лишь мои фантазии и бредни. На это мне не хватит ни мозгов, ни денег, ни вермени.

В общем, валялся я однажды на диване и залипал в потолок. Со временем, когда мне начало уже надоедать, меня озарила мысль :«А вижу то я херово». У меня отличное зрение, но я не могу видеть, как допустим камера. В центре находиться четкая точка, а отальное, чем дальше оно от этой точки все больше и больше размывается. Я начал гуглить. Эта точка называется фовеа и составляет всего лишь 1% процент, от поверхности, которая регистрирует свет. 1%!!!! Мне подумалось, что это могло бы пригодиться в computer science. Если сделать так, что бы компьютер (камеры на мониторах, либо специальные линзы, либо то и другое одновременно) будет регистрировать двежения глаз и определять куда человек смотрит, делая эту точку куда направленна фовеа четкой, а все более и более размытым, то это могло бы сильно снизить нагрузку на железо. Поскольку движение глаз слишком быстрые и аппаратура, которая потребовалась бы для того, что бы регистрировать передвижение глаз и показывать только один процент - это было бы слишком накадным. Можно было бы показывать десять процентов. Возможно, достигался бы 5-8 кратный выигрыш от этой технологии. Единственное, что смущает, что очень много ресурсов тратилось бы на отслеживание движений глаз, учитывая, что скорость их передвижения очень высокая, потребовались бы очень хорошие камеры. Это слишком накладно. Хотя возможно, такую штуку можно было бы применять в VR, ибо не надо прибавлять к скорости движения глаз, еще и поворот головы, и глаза могут находиться значительно ближе к камерам. Там отследить эти движения, было бы гораздо проще. Как вам идея?

lrusifikator
()

О неопределённом поведении и багах оптимизатора clang на примере разбора цикла статей Криса Латтнера, разработчика clang.

Форум — Development

про ud2 - лень читать комменты - но кто-то должен был оставить вот этот цикл из трех постов:

http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_21.html

stevejobs, спасибо за ссылки. С интересом почитал. Ответ получился довольно длинным, даже движок форума не хочет принимать его в таком виде в качестве простого камента, поэтому я решил, что он тянет на отдельную тему. Тем более, что здесь разбирается не какой-то мелкий баг/фича clang'а, а общий подход к созданию оптимизатора, основанный на изложении и анализе статей одного из разработчиков этого компилятора Криса Латтнера (Chris Lattner). Ну и ещё мне пришлось полностью переписать один из его примеров, чтоб он начал работать и иллюстрировать излагаемые им идеи. Если хочешь, можешь послать ему код, чтоб вставил в свою статью вместо своего, не рабочего. Я не возражаю.

А для тех, кто не в теме, это продолжение темы Вызов никогда не вызываемой функции.

Основная мысль автора цикла статей, как я понял, выражена ближе к концу 3-ей статьи в короткой фразе:

c) is a lot of work to implement.

Т. е. автор, по сути, соглашается, что они реализовали какую-то дичь с этими оптимизациями, объясняя некоторые причины: что де оптимизатор не знает, что на входе получает компилятор и даже не знает, что получает он сам на предыдущем проходе, ну и некоторые другие причины. А в конце говорит: но переделывать эту неудачную архитектуру нам лень, поэтому пользуйтесь тем, что есть. Что ж, fixed. В любом случае, статьи полезны, т. к. проливают свет на реальное (и довольно печальное) положение дел, связанных с оптимизациями в компиляторе clang.

Теперь разберу примеры из статей.

1. В первом примере автор пытается показать, почему к указателю на int нельзя обращаться как к указателю на float:

float *P;
 void zero_array() {
   int i;
   for (i = 0; i < 10000; ++i)
     P[i] = 0.0f;
 }

int main() {
  P = (float*)&P;  // cast causes TBAA violation in zero_array.
  zero_array();
}

Этот код — полная дичь. Он будет вылетать и с оптимизациями, и без них, потому что в переменную P (которая по умолчанию инициализируется 0), записывается её собственный адрес, а дальше, начиная с этого адреса, записываются ещё 40000 байт, которые непременно выдут за границы выделенной памяти.

Я немного переделал этот пример, чтоб он заработал, добавив сразу после P массив достаточного размера, в который и будут записываться числа (тоже undefined, но по факту работает с обоими компиляторами — clang и gcc), и заменив запись 0 на запись адреса &P+1, для чего ввёл объединение ufp, т. к. иначе на первой же итерации P будет указывать на 0, после чего на 2-й итерации произойдёт сегфолт. Ну и ещё добавил printf'ы для вывода информации и return, как того требует gcc и стандарт. Тут же отмечу, что мне пришлось слегка повозиться с unsigned *p, объявленным внутри функции print_array(). Сначала я сделал его глобальным, объявив до указателя float *P, и получил похожий на приведённый, но не совсем верный вывод: вместо ожидаемого 0x601268, 0x0, 0x0, 0x601268 программа без оптимизаций выдавала 0x601268, 0x0, 0x601268, 0x0. После установки watchpoint'а в дебагере выяснилось, что массив повторно модифицируется функцией print_array(). Просмотр адресов глобальных переменных &P и &p показал, что и clang, и gcc вставляют p после P и перед массивом arr, хотя в тексте программы она была объявлена первой. Видимо, компиляторы зачем-то сортируют переменные по типам и располагают указатели на float раньше указателей на unsigned. После переноса unsigned *p внутрь функции, всё стало работать, как и ожидалось. Вот мой рабочий (хоть и намеренно некорректный) вариант:

#include <stdio.h>

float *P;

float arr[10000];

union ufp
{
  float** p; float f;
} fp={&P+1};

void zero_array() {
   int i;
   for (i = 0; i < 10000; ++i)
     P[i] = fp.f;
 }

void print_array() {
   int i;
   unsigned *p;
   printf("&P==%p, P==%p\n", &P, P);
   for(i = -2; i < 10000; ++i)
    {
      p=(unsigned*)P;
      printf("&P[%i]==%p, P[%i]==%f (%p: 0x%X)\n", i, &P[i], i, P[i], p+i, *(p+i));
    }
}

int main() {
  P = (float*)&P;  // cast causes TBAA violation in zero_array.
  zero_array();
  //P=(float*)(&P+1); // restoring P for optimizer
  print_array();
  return 0;
}

При компиляции clang'ом без оптимизации:

clang -o zero_array zero_array.c

этот вариант выдаёт следующее:

&P==0x601260, P==0x601268
&P[-2]==0x601260, P[-2]==0.000000 (0x601260: 0x601268)
&P[-1]==0x601264, P[-1]==0.000000 (0x601264: 0x0)
&P[0]==0x601268, P[0]==0.000000 (0x601268: 0x0)
&P[1]==0x60126c, P[1]==0.000000 (0x60126c: 0x601268)
&P[2]==0x601270, P[2]==0.000000 (0x601270: 0x601268)
&P[3]==0x601274, P[3]==0.000000 (0x601274: 0x601268)
&P[4]==0x601278, P[4]==0.000000 (0x601278: 0x601268)
[skip]
&P[9994]==0x60ae90, P[9994]==0.000000 (0x60ae90: 0x601268)
&P[9995]==0x60ae94, P[9995]==0.000000 (0x60ae94: 0x601268)
&P[9996]==0x60ae98, P[9996]==0.000000 (0x60ae98: 0x601268)
&P[9997]==0x60ae9c, P[9997]==0.000000 (0x60ae9c: 0x601268)
&P[9998]==0x60aea0, P[9998]==0.000000 (0x60aea0: 0x601268)
&P[9999]==0x60aea4, P[9999]==0.000000 (0x60aea4: 0x601268)

и корректно завершается.

Если же включить оптимизацию:

clang -o zero_array -O2 zero_array.c

то получаем следующее:

$ ./zero_array
&P==0x601260, P==0x60126800601268
Ошибка сегментирования

Кстати, такой же результат будет, если откомпилировать эту программу компилятором gcc с включённой оптимизацией (там только адреса будут немного другими). Избавиться от этой ошибки можно 2 способами:

  1. Закомментировав вызов print_array() в функции main().

    Очевидно, что в этом случае никакого вывода мы не получим.

  2. Раскомментировав в main() строчку
    P=(float*)(&P+1); // restoring P for optimizer

    Тогда мы получим такой вывод:

    &P==0x601260, P==0x601268
    &P[-2]==0x601260, P[-2]==0.000000 (0x601260: 0x601268)
    &P[-1]==0x601264, P[-1]==0.000000 (0x601264: 0x0)
    &P[0]==0x601268, P[0]==0.000000 (0x601268: 0x601268)
    &P[1]==0x60126c, P[1]==0.000000 (0x60126c: 0x601268)
    &P[2]==0x601270, P[2]==0.000000 (0x601270: 0x601268)
    &P[3]==0x601274, P[3]==0.000000 (0x601274: 0x601268)
    &P[4]==0x601278, P[4]==0.000000 (0x601278: 0x601268)
    [skip]
    &P[9994]==0x60ae90, P[9994]==0.000000 (0x60ae90: 0x601268)
    &P[9995]==0x60ae94, P[9995]==0.000000 (0x60ae94: 0x601268)
    &P[9996]==0x60ae98, P[9996]==0.000000 (0x60ae98: 0x601268)
    &P[9997]==0x60ae9c, P[9997]==0.000000 (0x60ae9c: 0x601268)
    &P[9998]==0x60aea0, P[9998]==0.000000 (0x60aea0: 0x0)
    &P[9999]==0x60aea4, P[9999]==0.000000 (0x60aea4: 0x0)
    

Проблема тут очевидна: в цикле в P[i] записывается адрес &P+1. Но указатель P указывает на самого себя благодаря присвоению P = (float*)&P. Соответственно, элемент P[0] находится по тому же адресу, что и P. Когда при 1-й итерации цикла мы записываем туда адрес следующего элемента, указатель P меняется. В 64-битной ОС размер указателя равен 8 байтам, а размер float — 4, т. е. P у нас теперь указывает на начало arr. Дальше мы записываем 1-ый элемент от нового начала массива, т. е. по сути 3-й элемент, пропуская таким образом 2 элемента.

Когда же мы включаем оптимизатор (и в clang, и в gcc), он записывает все двойные слова подряд, начиная с 0-ого (в P[-1] у нас 0 потому, что мы перезаписали его после вызова zero_array(), чтобы программа не вылетела при вызове print_array()). Поэтому в первых 2 элементах у нас записано число 0x601268 (если представлять его как беззнаковое целое длиной в 4 байта), но 1-ые 2 элемента одновременно являются адресом, на который указывает P, т. е. адресом 0x0060126800601268 (0x601268 повторенное 2 раза). Если ничего не выводить, то всё тоже проходит успешно. Но как только мы вызываем print_array() (не модифицировав этот дикий адрес), программа сразу пытается отобразить содержимое не валидного адреса 0x601268, а того самого 0x0060126800601268, которого в нашем адресном пространстве просто нет. И получает сегфолт.

Почему printf отображает значения с плавающей точкой, которые в целочисленном виде выглядят как 0x601268, нулями, а не NAN, как по идее должно бы было быть, я не знаю. Видимо, это баг стандартной библиотеки (надо будет послать багрепорт, если никто мне не объяснит, что они правы).

Кстати, оба компилятора по неведомым мне причинам при оптимизации (а я пробовал разные уровни оптимизации) почему-то вместо записи поля fp.f memset'ом продолжают генерить цикл, только более короткий, чем без оптимизации (ассемблерные листинги я тут приводить не буду, кому интересно, могут сами откомпилировать с опцией -S). Хотя при записи константы 0 компилятор clang с вкючённой оптимизацией вместо цикла вызывает memset (gcc и в этом случае генерит цикл).

На всякий случай укажу версии использованных компиляторов:

$ clang --version
Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
Target: x86_64-pc-linux-gnu
Thread model: posix

$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах. Без гарантии каких-либо качеств, включая 
коммерческую ценность и применимость для каких-либо целей.

К сожалению, мне пришлось писать рабочую программу за автора статьи, который не удосужился даже проверить тот код, который опубликовал (хотя там и без проверки видно, что код по-любому не рабочий, хоть оптимизируй, хоть нет). Впрочем, автор всё честно объяснил:

c) is a lot of work to implement.

Такие они, разработчики clang'а.

Но идею я понял: при заполнении массива 0 или другими значениями в цикле, опасно одновременно менять указатель на этот массив. Но при чём тут изначальное утверждение о том, что

It is undefined behavior to cast an int* to a float* and dereference it (accessing the «int» as if it were a «float»).

Как это утверждение иллюстрируется данным примером?

Я уже не говорю о том, что оптимизировать циклы в memset нет никакой необходимости, потому что программист и сам может это сделать, сократив не только получившийся бинарник, но и исходник. А если программисту до этого нет дела, то почему компилятору должно быть дело? Тем более, если программист сделал цикл намеренно, то компилятору совсем незачем это исправлять. Думаю, именно поэтому gcc и не сворачивает циклы в memset. Я уже не говорю о том, что если уж вы сворачиваете их в memset, то будьте последовательны. Почему при заполнении массива константой 0 вместо цикла clang вызывает memset, а при заполнении того же массива одной не меняющейся переменной длиной в 4 байта оставляет цикл? Грош цена такой оптимизации.

Вот заменить вызов memset на ассемблерную команду rep stos действительно было бы полезно, но почему-то ни clang, ни gcc этого не делают.

2. Во втором примере автор цикла показывает, как смертельный указатель может запутать оптимизатор clang так, что тот сгенерит очередную фигню вместо исполняемого кода. Вот пример смертельного кода из 2-й статьи:

void contains_null_check(int *P) {
  int dead = *P;
  if (P == 0)
    return;
  *P = 4;
}

Очевидно, что если передать функции contains_null_check() NULL, то код будет непереносимым (undefined behavior). В защищённом режиме при попытке разыменования такого указателя произойдёт сегфолт. (UPD: практически аналогичная ошибка в ядре Linux 2.6.30 и 2.6.18 для Red Hat привела к серьёзной уязвимости, причём при разыменовании указателя система не падала.) Однако в реальном режиме такой код вполне законный. Более того, если мы рассматриваем язык си как системный язык, то в некоторых случаях без подобного кода в реальном режиме не обойтись. Что у нас лежит по адресу 0 в реальном режиме? — Указатель на обработчик 0-ого прерывания (деление на 0). А что если я хочу зарегистрировать свой обработчик? Для этого и существует неопределённое поведение: в одних системах оно работает так, а в других иначе. Но разработчики clang'а считают, что «неопределённое поведение» — это индульгенция на генерацию разного бреда вместо нормального кода.

Но вернёмся к статье. Автор описывает 2 варианта поведения оптимизатора.

  1. В первом варианте сначала проверяется избыточный код, а затем избыточные проверки. Выглядит это примерно так:
    void contains_null_check_after_DCE(int *P) {
      //int dead = *P;     // deleted by the optimizer.
      if (P == 0)
        return;
      *P = 4;
    }
    

    На этом этапе совершенно справедливо выпилили переменную dead, т. к. она нигде не используется.

    Далее идёт проверка избыточности проверок и делается правильный вывод о том, что проверка P на равенство 0 нужна. Она остаётся. Всё работает, как и задумывалось (и даже не падает в защищённом режиме на радость быдлокодерам).

  2. Во втором варианте оптимизатор сначала проверяет проверки программиста на избыточность, а затем выпиливает ненужные переменные:
    void contains_null_check_after_RNCE(int *P) {
      int dead = *P;
      if (false)  // P was dereferenced by this point, so it can't be null 
        return;
      *P = 4;
    }
    

    Здесь оптимизатор почему-то решил, что раз *P разыменовывается без проверки, то он априори 0 быть не может и проверять его необходимости нет. А то, что программист мог ошибиться, разработчикам оптимизатора даже в голову не приходит. Как и то, что помимо защищённого режима есть ещё и реальный. А бывают ещё компиляторы для разных контроллеров и встроенных специализированных систем, где разыменовывать 0 указатели бывает нужно и иногда даже необходимо. Или clang такие системы не поддерживает? И никогда не сможет поддержать с подобным подходом, ориентированным на работу только защищённых многозадачных ОС.

    Но вернёмся к статье. На следующем этапе выпиливается переменная dead и проверка на 0 и остаётся:

    void contains_null_check_after_RNCE_and_DCE(int *P) {
      *P = 4;
    }
    

    Если раньше программа корректно работала в реальном режиме, а в защищённом падала, то теперь в реальном режиме вектор 0-ого прерывания перезаписывается адресом 4. В результате при любой ошибке деления компьютер намертво зависает (хотя реальный режим clang, как я понимаю, не поддерживает и никогда не сможет поддержать с таким шикарным легаси).

3. Третий пример я разбирать не буду, т. к. согласен с автором, что оптимизация «x > x+1 всегда false» может быть полезна при использовании макросов. А для проверки переполнения существуют константы MAX_*.

4. Четвёртый пример — почти из поста Вызов никогда не вызываемой функции. Его уже разобрали по полочкам, сломали все копья, какие только можно было сломать, в т. ч. и я, поэтому здесь повторяться не буду. Единственно, скажу, что мне было непонятно, зачем заменять вызов функции по 0-ому адресу с неизбежным сегфолтом на недопустимую инструкцию ud2. Автор поясняет во 2-й статье:

2. Clang has an experimental -fcatch-undefined-behavior mode that inserts runtime checks to find violations like shift amounts out of range, some simple array out of range errors, etc. This is limited because it slows down the application's runtime and it can't help you with random pointer dereferences (like Valgrind can), but it can find other important bugs. Clang also fully supports the -ftrapv flag (not to be confused with -fwrapv) which causes signed integer overflow bugs to trap at runtime (GCC also has this flag, but it is completely unreliable/buggy in my experience). Here is a quick demo of -fcatch-undefined-behavior:

В вольном пересказе: мы всегда так делаем, чтобы показать, что код содержит участки с неопределённым поведением. И плевать, что недопустимая инструкция не указывает на некорректный код. Просто ничего лучшего мы не придумали.

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

И напоследок 2 эпические цитаты. Первая из начала 1-ой статьи. Она очень понравилась dzidzitop:

It turns out that C is not a «high level assembler» like many experienced C programmers (particularly folks with a low-level focus) like to think

Вот оно что оказывается. Си — это та же ява, чуть более быстрая и более опасная. А для написания системных вещей переходите на настоящий ассемблер! Кен Томпсон гомерически хохочет и Деннис Ритчи переворачивается в гробу.

А вторая из 3-ей, заключительной статьи:

Ultimately, undefined behavior is valuable to the optimizer because it is saying «this operation is invalid - you can assume it never happens».

В вольном пересказе это обозначает: «Вау! Неопределённое поведение! Ворочу куда хочу!»

UPD: Вот хочу добавить сюда ещё несколько ответов на вопросы, на которые приходится отвечать по всему треду одно и то же:

1. То, что ub обозначает «делай, что хочешь!», мягко говоря, неправда. Вот, что написано в стандарте C99:

3.4.3

1 undefined behavior

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

3 EXAMPLE An example of undefined behavior is the behavior on integer overflow.

Т. е. в стандарте чётко прописаны 3 действия, из которых разработчики компиляторов могут выбрать любое:

1. Игнорировать ситуацию. Смотрим в Ожегове, что обозначает слово «игнорировать»:

Умышленно не заметить, не принять во внимание.

Т. е. «игнорировать» — это сделать вид, что всё нормально и пройти мимо, а не модифицировать или удалять такой код, и уж тем более делать на его основе какие-то бредовые предположения.

2. Компилировать и выполнять такой код в соответствии с документацией, с выводом предупреждающих сообщений или без них. Т. е. напишите явно в документации, что если мы встречаем 0 указатель, то делаем то-то и то-то, и делайте. Но не в тихую.

3. Прерывать компиляцию и/или выполнение с обязательным выводом диагностических сообщений.

И всё. Ни о каком «что хочешь» в стандарте речи не идёт. Вот тут мне в каментах подсказали, что «with unpredictable results» обозначает «что хочешь». Но на самом деле это обозначает лишь то, что результаты могут быть непредсказуемыми, а совсем не то, что компилятор может делать всё, что угодно (хотя разработчикам таких компиляторов подобная трактовка очень удобна).

Ну и тот же человек считает, что «это notes», а значит неважно, что там написано. Но т. н. неопределённое поведение при переполнении целого — вообще example из того же пункта:

EXAMPLE An example of undefined behavior is the behavior on integer overflow.

И больше я нигде никаких упоминаний об ub при арифметическом переполнении не нашёл. Про переполнение при сдвигах — нашёл. А в других случаях — нет. Но все почему-то на этот example ссылаются.

2. Многие говорят, что быдлокодеры должны страдать. Но серьёзные уязвимости, связанные с ub, а точнее с непредсказуемой реакцией компилятора на ub, в разное время обнаруживались в ядре Linux, во FreeBSD и в GDK-Pixbuf, затрагивающая Chromium, Firefox и VLC. Подробнее см. в этом комментарии, чтоб не раздувать и без того длинный верхний пост. Здесь только скажу, что уязвимость в ядре Linux связана с ошибкой, идентичной со 2-м примером из разбираемых статей.

3. Автор статей и многие в этом треде утверждают, что автоматически отыскать такие ошибки очень сложно и дорого, а то и вовсе невозможно. Но это тоже не так. В Интернете я нашёл такой пример си++ программы с ub:

#include <iostream>
int main()
{
    for (int i = 0; i < 300; i++)
        std::cout << i << " " << i * 12345678 << std::endl;
}

Программа из-за переполнения временного результата на 174-й итерации при использовании ключа оптимизации -O2 в g++ попадает в бесконечный цикл.

Запустив компиляцию, я получил следующие предупреждения (причём безо всяких опций -W что-то_там):

$ g++ -o infinity_loop -O2 infinity_loop.cpp
infinity_loop.cpp: В функции «int main()»:
infinity_loop.cpp:5:38: предупреждение: iteration 174u invokes undefined behavior [-Waggressive-loop-optimizations]
         std::cout << i << " " << i * 12345678 << std::endl;
                                      ^
infinity_loop.cpp:4:5: замечание: containing loop
     for (int i = 0; i < 300; i++)
     ^

А ведь здесь случай куда менее очевидный, чем простое разыменование NULL-указателя.

4. Наконец, на Хабре я вычитал, что стандартный макрос

#define offsetof(st, m) ((size_t)(&((st *)0)->m))

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

UPD 2: Вот тут Sorcerer в комментарии кинул ссылку на письмо Линуса Торвальдса в рассылке от 12 января 2009 года, где он пишет о том, что думает о некоторых оптимизациях. Приведу несколько фрагментов этого письма в своём переводе:

Type-based aliasing — это тупость. Это такая невероятная тупость, что даже не смешно. Оно испорчено. И gcc взял испорченную концепцию и настолько её раздул, следуя букве-закона, что получилась бессмысленная вещь.

[skip]

Это НЕНОРМАЛЬНО. Это так невероятно безумно, что люди, которые делают это, просто должны избавиться от своего убожества, прежде чем они смогут восстановить. Но реальные gcc программисты действительно думали, что это имеет смысл, потому что стандарт это позволяет и даёт компилятору максимальную свободу, — потому что он может делать теперь вещи БЕЗУСЛОВНО АБСУРДНЫЕ.

И компиляторщикам абсолютно абсурдные вещи часто кажутся действительно хорошими, потому что им больше не надо беспокоиться о конечном результате: работает оно или нет, — они просто получили добро тупить во имя оптимизации.

[skip] И если кто-то жалуется, что компилятор невменяемый, компиляторщики скажут «ня, ня, разработчики стандарта сказали, что так можно», с абсолютным отсутствием анализа, имеет ли оно СМЫСЛ.

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

[skip]

Угадайте, что произойдёт, если вы имеете такой безумный склад ума и пытаетесь сделать безопасный код без alias'а, — вы займёте лишнее пространство на стеке.

По факту, Linux использует -fno-strict-aliasing из-за чертовски веской причины: потому что в gcc понятие «strict aliasing» является огромной зловонной кучей д-рьма. Linux использует этот флаг не потому, что Linux исполняется быстро и свободно, он использует этот флаг, потому что _не_ использует тот безумный флаг.

Type-based aliasing неприемлемо тупо для начала, и gcc вознёс этот идиотизм до совершенно новых высот, фактически не обращая внимания даже на статически видимый aliasing.

Линус

Оригинал (на английском):

( читать дальше... )

И ещё спасибо anonymous'у за камент с ещё одним сообщением на ту же тему того же автора от 26 февраля 2003 года.

Ну и от себя добавлю, что не только Линусу не нравится aliasing. Microsoft тоже не спешит реализовывать его в своём Visual C++. Т. е. не нравится это тем, кто помимо разработки компиляторов создаёт и другой софт с использованием этого компилятора, например ОС. А те, кто создают только компиляторы для сферических программистов в вакууме, рьяно эту фичу реализуют, хоть их и никто не заставляет.

Ну и напоследок оставлю несколько полезных ссылок на память:

Стандарт C11 (последний) (pdf), Стандарт C99 (pdf),

http: //read.pudn.com/downloads133/doc/565041/ANSI_ISO%2B9899-1990%2B%5B1%5D.pdf (Стандарт C89) (pdf),

http: //web.archive.org/web/20030222051144/http: //home.earthlink.net/~bobbitts/c89.txt (Стандарт C89) (txt),

https: //web.archive.org/web/20170325025026/http: // www .open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4660.pdf (Стандарт C++17) (последний) (pdf),

Стандарт C++14 (pdf), Стандарт C++11 (pdf),

бумажный перевод стандарта C++17, выполненный Зуевым и Чуприновым, Москва, 2016, на основе Working Draft, Standard for Programming Language C++ от 22 мая 2015 года (номер документа n4527) за 4945 руб. (надеюсь, что эту ссылку не сочтут за рекламу, т. к. к авторам я никакого отношения не имею), а здесь можно скачать начало перевода (предисловие и содержание), ну и ещё торрент-ссылку видел на эту книгу, но здесь её публиковать не буду,

статья на Хабре (из песочницы) от 2014 г. Неопределенное поведение в C++, ещё одна статья там же от 2016 года Находим ошибки в коде компилятора GCC с помощью анализатора PVS-Studio, Разыменовывание нулевого указателя приводит к неопределённому поведению и Про C++ алиасинг, ловкие оптимизации и подлые баги. Это так, ссылки на заметку.

Некоторые ссылки парсер ЛОР'а не принял, поэтому мне пришлось разделить их пробелами, превратив в текст, который можно скопировать в адресную строку браузера, удалив пробелы. Там, где http встречается дважды в 1 строке — не ошибка, а именно такие ссылки.

 , , , ,

aureliano15
()

Парсинг вывода make для построения списка исходников

Форум — Development

Привет

Имеется несколько C-проектов с кучей общих исходников с makefile-ами, собирается ок.

Хочу сгенерировать списки .c и .h для каждого запуска `make target123`. Т.е. списки используемых исходников для каждого проекта.

Встречал такую приблуду, но сейчас не могу найти. Гугл молчит.

Пока пишу простую парсилку вывода `make -n`, может кто-то вспомнит, что есть готового.

Спасибо

 ,

Deleted
()

Где лучше публиковать снимки для форума?

Форум — Talks

Как известно, на LOR нельзя добавлять фото в сообщения на форуме, поэтому приходится пользоваться сторонними сервисами.

Я знаю следующие (большая часть подсказана в этом треде, большое спасибо всем за помощь, я добавляю ваши ссылки в список):

, а какие вы знаете и пользуетесь? Опишите их преимущества и недостатки.

Перемещено leave из general

 , ,

Vsevolod-linuxoid
()

[ПЕРЕЗАПУСК] LOR-servers minetest 0.4.17 [MODS]

Форум — Games

Два сервера minetest:

  • Test — test.minetestserver.ga
  • Lor  — lor.minetestserver.ga

Таки да! Как феникс, из пепла порушенных мечтаний восстали сервера!

Запилена няшная страничка серворов с мониторингом их состояния, проект на гитхабе и баг-трекер (там же)

Lor работает на сервере ravdinve, за что ему огромное спасибо. Тестовый сервер отваливается когда угодно, в основном когда отваливаюсь я от инета.

Достать админа также можно на #lor-minetest на фриноде.

 , , , ,

timdorohin
()

Леннарт Поттеринг удостоен премии Pwnie Awards 2017

Новости — Безопасность
Группа Безопасность

На церемонии, ежегодно проходящей в рамках конференции Black Hat USA в Лас–Вегасе, объявлены победители премии Pwnie Awards 2017, присуждаемой за выдающиеся достижения либо провалы в области компьютерной безопасности.

В категории «Самая дурацкая реакция разработчика» (Lamest Vendor Response) премии удостоен Леннарт Поттеринг за реакцию на ошибки в systemd и отказ документировать уязвимости, получившие индекс CVE: 5998 (новость), 6225, 6214, 5144, 6237 (обсуждение в Talks).

>>> Подробности

 , , ,

Quote
()

Царю про 10к в надежде перевести дискуссию в конструктив

Форум — Development

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

Если ты готов померять реальный перформанс, пиши, я налабаю на еполле аналоги твоих тестовых серверов, чтобы не ты один тратил своё время. Меня например больше в всего в контексте этого спора интересует, как поведёт себя сервер с 10к потоков например на 4 ядрах против еполльного на одном таком же ядре, в вариантах без локов и с.

Результаты исследования можешь запостить на ЛОРе и восстановить честь среди пятизвездочных 😝

Начало дискуссии где-то рядом в удаленных по инициативе какого-то наркомана.

PS скорее всего я отвечу не раньше ночи или следующего утра.

 ,

staseg
()

Проблема с чипсетом i915

Форум — Linux-hardware

Валятся ошибки в syslog. Дистрибутив - свежеустановленный Xubuntu 16.04, пакеты обновлены. Материнка ASUS H110M-R, процессор Pentium G4400, 4GB оперативки, видео только встроенное.

Jul 13 00:06:41 Comp18 kernel: [    2.160892] [drm:intel_dp_link_training_clock_recovery [i915]] *ERROR* too many full retries, give up
Jul 13 00:06:41 Comp18 kernel: [    2.170388] Adding 4088828k swap on /dev/sdb3.  Priority:-1 extents:1 across:4088828k SSFS
Jul 13 00:06:41 Comp18 kernel: [    2.210572] [drm:intel_dp_link_training_clock_recovery [i915]] *ERROR* too many full retries, give up
Jul 13 00:06:41 Comp18 kernel: [    2.260249] [drm:intel_dp_link_training_clock_recovery [i915]] *ERROR* too many full retries, give up
Jul 13 00:06:41 Comp18 kernel: [    2.302892] [drm:intel_dp_link_training_clock_recovery [i915]] *ERROR* too many full retries, give up
Jul 13 00:06:41 Comp18 kernel: [    2.346597] [drm:intel_dp_link_training_clock_recovery [i915]] *ERROR* too many full retries, give up
Jul 13 00:06:41 Comp18 kernel: [    2.391042] [drm:intel_dp_link_training_clock_recovery [i915]] *ERROR* too many full retries, give up
Jul 13 00:06:41 Comp18 kernel: [    2.435420] [drm:intel_dp_link_training_clock_recovery [i915]] *ERROR* too many full retries, give up
Jul 13 00:06:41 Comp18 kernel: [    2.435886] [drm:intel_dp_start_link_train [i915]] *ERROR* failed to train DP, aborting
Jul 13 00:06:41 Comp18 kernel: [    2.480417] snd_hda_intel 0000:00:1f.3: bound 0000:00:02.0 (ops i915_audio_component_bind_ops [i915])

Будут ли проблемы с аппаратным ускорением? И как добиться нормальной инициализации.

 ,

tlx
()

Какой у него ник на ЛОРе?

Форум — Talks

На сайте, который называть не буду, чтобы не провоцировать нацпол, наткнулся на ссылку на профиль московского айтишника с шизотипическим расстройством: https://github.com/saniv По ссылке — небезызвестная на ЛОРе недописанная игра Spell of Mastery, много идеологической борьбы за лицензионную чистоту и мизантропные тексты, попадающие под статью «экстремизм».

Вряд ли такой человек мог пройти мимо ЛОРа. Какой у него ник?

 

question4
()

Месседжер мне запили!

Форум — Talks

Тема для толксов конечно же. На ЛОРе по другому никак. В общем расклад такой... Я не кодер и не дизайнер. Однако умею управлять, понимаю в маркетинге, менеджменте, у меня есть чёткая концепция и стратегический план к чему идти. Но я нищеброд. [/thread] :)
В общем хочу запилить месседжер, но нужны бесплатные крутые кодеры и пара дизайнеров. Пока работа даже не за еду. Если проект взлетит, то все, стоявшие в основании, получат жирный кусок.
В чём суть (тезисно, основные концепции для начала проекта):

  • Проект опенсорсный (полностью). Базирование на гитхабе. Свой сайт конечно будет, как же без него.
  • Клиенты под оффтоп (в т.ч. и для Windows Phone 8),онтоп,Android,iOS и даже в будущем всякие Tizen и сайлфиш.
  • Реализация всамделешного end-to-end.
  • Мультилогин
  • Регистрация юзера по UserID. Однако для домохозяек этот момент будет не явным, они могут просто на номер телефона, но это лишь для тех кто в логин-пароль не умеет.
  • Клиенты могут работать как с сервером (центральным или любым подкроватным), так и без него.
  • Возможность работы через TOR
  • Коммуникация между подкроватными серверами с серверами проекта через сервер координации. Т.е. если ты хочешь общаться с миром, говоришь своему подкроватному серверу стучаться на сервер координации, если нет, то работай в пределах своего подкроватного сервера дальше. В случае безсерверной архитектуры все будет работать по методу TOXа, но это сугубо опциональный момент.
  • Возможность звонков в т.ч. видео (для начала на десктопных клиентах)
  • Никакого хранения истории на сервере и никакого сбора данных. Распределенная структура базовых серверов в разных юрисдикциях.
  • В начале планируется бесплатное распространение. Сбор донатов для поддержания серверной архитектуры. Далее переход на 1$ в год для официальных мобильных приложух. Сторонние клиенты будут работать.
  • Реализация микро денежных переводов в месседжере. Сначала в криптовалюте, затем в денгах. В крипте комиссии не будет. В деньгах будет минимальная комиссия на вывод (в зависимости от затрат проекта на вывод средств).
  • Никакой рекламы
  • Двухфакторая аутентификация
  • Реализация ботов (по примеру пашкограмма).

Вот такие начальные концепции. Если описывать все, то будет много букаф.
Есть желающие? Инвесторы? Хейтеры? Присоединяйтесь =) . Если вы впечатлены, то можно уже начинать пилить... =) . Я возьму на себя стратегические решения и координацию проекта. Админить так же умею, не переживайте. Проект опенсорсный многие вопросы будут решаться путем обсуждения рабочей группы и мнение общественности будет приоритетным. У меня в этом направлении есть множество планов и развитая стратегия. Так что если вы первокласный кодер или дизайнер, или переводчик можем начать делать шаги вперед вместе.

 , , ,

Promusik
()

LTO+PGO Firefox/Chromium builds

Форум — Development

Дано: собрать браузер с удалением Telemetry и ненужных плюшек. Быстро-браузер, с CXXFLAGS += "-flto -fprofile-generate -fprofile-dir=${PGO_DATA_DIR} -Wl,-O3,-plugin-opt=O3"

Опции компилятора CC clang и линкера LD ld.gold - арийско верные.

Получается: over 100пицот часов линкер теребит писю при LTO линке xul.lib. Теребит так, что занимает RAM >8GB и постоянная работа с SSD ~200MB read/write в это время.

Что суть правильно. Chromium team вообще требует комп с 40GB РАМ - просто для начала компиляции ботнета своего.

Вопрос: почему я хочу невозможного и советы из первых рук, кто пробовал компилировать сходное на Amazon?

 , ,

blitz
()

Ищу живую альтернативу libui

Форум — Development

Нужна минимальная либа-обёртка над системный GUI фреймворком для создания GUI приложения из 2.5 кнопок. Самая сложная часть в нём - TreeView.

Сейчас использую Qt, но это перебор.

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

Всякие fltk и прочая маргинальщина из 90-х не подходит. Прога должна использовать системную тему.

PS: я знаю что альтернатив нет, но писать три отдельные реализации - боль.

 , ,

RazrFalcon
()

Игры, Linux, Steam, обзоры

Форум — Games

Список 1000+ игр со ссылками на обзоры от GNU/Linux пользователей. Здесь список больше не обновляется.

Список на базе Steam с оглавлением по прежнему улучшается.

English version of the list Games, Steam, Linux, reviews.

Здесь встречаются обзоры на разных языках: [rus] — русский, [eng] — английский, [fra] — французский, [spa] — испанский, [por] — португальский, [ces] — чешский, [deu] — немецкий, [pol] — польский, [fin] — финский и [ukr] — украинский.

Должен предупредить, что в части обзоров крайне мало информации, кроме того факта, что обзор существует и автор как минимум запустил игру в среде GNU/Linux. Со временем я постараюсь улучшить эту ситуацию.

Деление на жанры довольно условно. Распространение ссылок на перечисленные здесь обзоры всячески приветствуется. «Лайкать» обзоры тоже не возбраняется.

Я готов добавлять ссылки на чужие более другие обзоры. Скажем при условии, что в обзоре (или коротеньком сообщении) будет информация хотя бы о дистрибутиве, видеокарте+драйвере и серьёзных препятствующих прохождению багах (если они есть).

 ,

Evgueni
()

Auto spoiler

Форум — Linux-org-ru

В очередной раз наткнувшись на километровый топик с вставками кода решил откопать свой юзерскрипт для скрытия больших кусков кода.

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

  • префикс перед spoiler, в зависимости от типа
  • умеет скрывать теги [cut], [code], [pre]
  • лимит строк - 15 или 5, если тема засрана вставками (тут можно считать лимиты отдельно для каждого поста, но мне лень).

Скопипастте его уже в лоровский скрипт, там 2.5 строчек кода.

// ==UserScript==
// @name        LOR spoiler
// @namespace   linux.org.ru
// @description Add spoiler functionality
// @include     https://linux.org.ru/*
// @include     https://www.linux.org.ru/*
// @version     2
// @grant       none
// ==/UserScript==

$script.ready('jquery',function(){
  console.log('LOR spoiler is ON');

  // spoiler
  var types = ['cut', 'code', 'pre'];
  var blocks = {
    cut: $('[id ^= cut]'),
    code: $('.code'),
    pre: $('pre:not([class])')
  };

  var total_block_cnt = blocks.cut.length + blocks.code.length + blocks.pre.length;
  var line_limit = total_block_cnt > 2 ? 5 : 15;

  var spoiler_prefix_on = '&gt;&gt;&gt;&nbsp;';
  var spoiler_prefix_off = '&lt;&lt;&lt;&nbsp;';

  var tpl = 
    '<span class="sign">'+
      '<span>'+ spoiler_prefix_on +'</span>'+
      '<a '+
      'id="spoiler-hide-{TYPE}_{ID}" '+
      'href="javascript:void(0);" '+
      'onClick="javascript:var block=$(\'#hide-{TYPE}_{ID}\'); var prefix=this.previousElementSibling;'+
        'if (block.css(\'display\')===\'none\') {'+
          'block.show(); prefix.innerText=\''+spoiler_prefix_off+'\'; } else {'+
          'block.hide(); prefix.innerText=\''+spoiler_prefix_on+'\'; };">'+
      '{TYPE}-spoiler'+
      '</a>'+
    '</span><br/>';

  // change content
  if (total_block_cnt > 0) {
    for (var i = 0; i < types.length; i++) {
      var TYPE = types[i];
      var ID = 0;
      
      blocks[TYPE].each(function() {
        // limit
        var no_hl = $(this).find('pre.no-highlight code');
        var cur_blk = no_hl.length > 0 ?  no_hl : $(this);
        if (cur_blk.text().split("\n").length <= line_limit) return;

        // add spoiler
        var spoiler = tpl.replace(/\{TYPE\}/g, TYPE).replace(/\{ID\}/g, ID);
        $(this).attr('id','hide-'+TYPE+'_'+ ID).hide();
        $(this).before(spoiler);
        
        ID++;
      });
    }
  }
});

з.ы. выглядит так: http://i.imgur.com/SA0ScAO.png
или так: http://i.imgur.com/SGdal6y.png

 , , , ,

anTaRes
()

Ушат помоев в сторону крестолюбов

Форум — Development

Восседая в уютненьком кресле с чашечкой сладкого чая, внезапно ощутил приток жопной боли напополам с лирическим настроением и решил излить сию благодать куда руки дотянулись.

Последние 7 лет я пишу сугубо на C, и только под Linux (да, да -std=gnu99 и accept4, dup3, __attribute__((cleanup(dtor))) и прочие приятности, позволяющие сделать волосы шелковистее на 15.5%) и не понимаю, для чего вообще нужен C++? То, что на сишке делается красиво и элегантно, в крестах напоминает соитие парализованных дцпшников (к сожалению, утерял картинку, но именно этот образ всплывает в голове, когда вижу очередную порцию крестолапши).

Давайте посмотрим на типичного C++ разработчика: он использует STL, boost, многие любят Qt (не только для GUI), якобы чтобы «писать кроссплатформенный код». В итоге болезный не знает током ни WinAPI, ни POSIX — ничерта. Он абсолютно не разбирается, как работает целевая система, для которой пишет код! Крестокодер просто не осознает, какой лютый ужас кроется за его любимыми iostream-ами, какое лютое говно лежит в boost::filesystem::path, насколько убого-низкоуровневым является boost::asio в 2016 году.

Только крестораб может эпично обосраться и просадить производительность, забыв передавать по ссылке параметры для «горячих» функций (то есть, просто забыв написать «&» в нужном месте).

Также эти убогие завистливо смотрят на type inference в языках, проектировавшихся не как «C на стероидах», и в ответ начинают лепить template и auto не к месту, от чего код адово пухнет и даже IDE перестает его понимать.

Серьезно, просто прекратите писать на этом языке. В следующий раз, начиная новый проект, выберите java (щютка)/go/swift/rust/c. Прекратите насиловать труп и отравлять зловонием все вокруг!

Перемещено true_admin из talks

 , , ловите наркомана,

kawaii_neko
()

2% !!!!

Форум — Talks

Microsoft добились своего выпуском Windows 10, доля Linux на десктопе поднялась до 2% :)

https://www.netmarketshare.com/report.aspx?qprid=11&qpaf=&qpcustom=Li...

 ,

qrck
()

Производительность C++

Форум — Development

Как насчёт производительности у C++ по сравнению с C? Мои предположения на текущий момент:

1) Код, не использующий возможности C++ (то есть по сути plain C), скомпилированный C++ компилятором будет иметь абсолютно ту же производительность, что и код на С.

2) Исключения и dynamic_cast медленные. Если нам важна производительность, лучше их не использовать.

3) Класс без виртуальных методов, должен быть по производительности эквивалентен сишной структуре и функциям, обрабатывающим её. Не считая копирования. Нужно везде, где можно использовать передачу по указателю или ссылке (собственно, если в Си делать memmove при передаче структуры в качестве аргумента, то это вызовет примерно такой же оверхед, как дефолтный конструктор копирования С++. Верно?).

4) Класс с виртуальными методами полностью аналогичен пункту 3, но при вызове виртуальных методов добавляется небольшой оверхед. Сишный эквивалент obj->vtable->func(obj, ...). Если сравнивать с plain C кодом, реализующим ООП в той же манере (каждая структура-объект имеет поле, указывающее на структуру, содержащую адреса функций работы с ней), то оверхеда по сравнению с plain C не должно быть.

5) При использовании атрибута класса final (если компилятор поддерживает соответствующий стандарт) даже при наличии виртуальных методов в нём, их вызов будет превращаться в прямые вызовы функций вместо обращения к vtable, если переменная имеет соответствующий тип, а не указатель/ссылка на его предка (который не final).

6) Шаблоны могут привести к разбуханию кода. Впрочем, #define-ы и inline-функции в C++ могут устроить то же самое. Вопрос: будет ли использование шаблона с одинаковыми параметрами создавать 2 копии реализации или же всё-таки компилятор догадается сделать её лишь один раз. А если шаблон используется с одинаковыми параметрами в нескольких объектных файлах? Будет ли реализация расшариваться между ними или у каждого своя?

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

Я не претендую на правоту, какие-то утверждения могут быть ложными. Хотел бы узнать, как обстоят дела на самом деле. А также какие подводные камни я ещё не знаю. Разумеется, речь идёт о последних версиях gcc/clang с включённой оптимизацией не ниже -O2.

 ,

KivApple
()

btrfs-убийца

Форум — Talks

В общем, мужики, говно и параша этот ваш btrfs. Эрзику и прочим попугаям-популяризаторам привет и "патч Бармина" вам на воротник. Название темы навеяно эпичным топиком имени сеньора mv.

Было дело как, 2 года сидел на кубунте и вчера при попытке sudo apt-get upgrade система выдала, что де «места нет», хотя на ссд было ещё минимум 80гб. ФС по совершенно неведомым причинам улетела в readonly. Когда накатывал, купился на рекламу, дескать, btrfs ну дюже адаптируют и так подгоняют под ssd, что выбор фс должен быть очевиден. Ну и лох. Падений было вагон с тележкой. Каждый раз спасала флешка с Кноппиксом, средствами которого делал btrfsck, в тяжёлых случаях из под чрута перезапиливал grub с ведром, и тому подобные колдунства. А в этот раз не помогло. Из ro вывел, но ненадолго. Хоть хомяк додумался забэкапить.

На восстановление фс уже забил, итак бездарно убил вечер на реанимацию «поциента». Теперь думаю, то ли обратно на Debian и рукопожатную ext4, то ли мигрировать на какую-нибудь ересь типа «Федоры-убийцы» (с). Не, я понимаю, если бы питание было говном, нежданчики с отключением света, и т.п., но падала эта сволочь каждый раз на ровном месте.

Не ведитесь на рекламу, а также слушайте и берегите ребе Bioreactor`а, да избегайте «кульхацкерских поделок для админов локалхостов» (с).

update:

knoppix@Microknoppix:~$ dmesg | grep sda1
[    3.640572] BTRFS error (device sda1): unable to find ref byte nr 738426880 parent 0 root 4  owner 1 offset 0
[    3.640618] BTRFS: error (device sda1) in __btrfs_free_extent:6261: errno=-2 No such entry
[    3.640618] BTRFS info (device sda1): forced readonly
[    3.640620] BTRFS: error (device sda1) in btrfs_run_delayed_refs:2781: errno=-2 No such entry
[    3.640621] BTRFS warning (device sda1): Skipping commit of aborted transaction.
[    3.640622] BTRFS: error (device sda1) in cleanup_transaction:1710: errno=-2 No such entry
[    3.640681] BTRFS error (device sda1): cleaner transaction attach returned -30
update 2:
# smartctl -a /dev/sda1 | grep "202\|173"
173 Wear_Leveling_Count     0x0032   085   085   000    Old_age   Always       -       463
202 Percent_Lifetime_Used   0x0031   085   085   000    Pre-fail  Offline      -       15

update 3:

# btrfs check --repair /dev/sda1
enabling repair mode
Error: could not find extent items for root 257

update 4: btrfs-убийца (комментарий)
Для труЪ: забил, переразметил ссд (которому, как оказалось, ещё жить и жить) и накатил 23-ю Федору. Интересно же. От deb-based уже как-то устал.

 , ,

Hertz
()