?

Log in

No account? Create an account
баг (программистское) - баг (программистское) - По делам сюда приплыл, а не за этим Page 2 — ЖЖ [entries|archive|friends|userinfo]
Anatoly Vorobey

[ website | Website ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Links
[Links:| English-language weblog ]

баг (программистское) [май. 3, 2018|02:39 pm]
Anatoly Vorobey
[Tags|]

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

Missing red channel in Chrome Remote Desktop

Если вы разбираетесь в C++, почитайте сами, а если нет, то вот краткий пересказ:

1. В Хроме, когда он используется для удаленного захода на другой компьютер (Chrome Remote Desktop), внезапно пропал красный цвет, в том числе из комбинаций цветов (так что белый фон стал сине-зеленым, например).

2. Идем по истории изменений, находим, что это произошло в изменении, которое не меняло исходники, а вместо этого перешло к новой версии компилятора ("roll clang"). Вечер перестает быть томным.

3. Ищем и находим способ "дешево" воссоздать проблему для данного набора исходников (в данном случае - как сделать "удаленный" вход внутри одного компьютера).

4. Берем исходники в этот момент, строим две версии компилятора, старую и новую. Компилируем все дерево исходников старой - бага нет, новой - баг есть. Компилируем все дерево старой, и начинаем искать, какие исходники приводят к проблеме, если только их построить новой.

4. Постепенно сужаемся до большой компоненты дерева...

5. ...до конкретной директории...

6. ...до нескольких файлов...

7. ...до одного файла...

8. Находим массивы констант, которые используются для перевода цветов из режима YUV в режим RGB. Массивы определены внутри функции и внутри блока кода, но не помечены static. При этом используются уже после выхода из этого блока кода, через указатель, естественно.

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

И так каждый день! (примечание: не всегда так цветисто).
СсылкаОтветить

Comments:
Страница 2 из 3
<<[1] [2] [3] >>
[User Picture]From: _pg_
2018-05-03 04:00 pm
"Массивы определены внутри функции и внутри блока кода, но не помечены static. При этом используются уже после выхода из этого блока кода."

А виноват, естественно, компилятор. :)
(Ответить) (Thread)
[User Picture]From: aosypov
2018-05-04 03:38 pm
++
(Ответить) (Parent) (Thread)
[User Picture]From: prol_prolych
2018-05-03 04:12 pm
а через пару лет всплывёт какой-нить баг из-за статика в "глубине сибирских руд" :о))) Отета будет номер.
(Ответить) (Thread)
From: caztd
2018-05-03 04:26 pm
А вот руки оторвать разработчикам компилятора, которые вводят такую оптимизацию и не делают чекер, который подобные баги ловит.
Зачем им руки если мозгов все-равно нету?
По идее это должен быть -Werror по умолчанию.
(Ответить) (Thread)
From: (Anonymous)
2018-05-03 04:29 pm
Это сущая ерунда по сравнению с теми кабанами, которых может подложить излишне вумный оптимизатор :)

Ну типа - вот начиная с этой строчки весь код UB, а значит берем и молча выкидываем.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: kray_zemli
2018-05-03 05:28 pm
На мой взгляд, это про то, как НЕ надо. Есть же инструменты для поиска проблем, связанных с памятью. Нужно периодически прогонять тесты с включенными инструментами.
(Ответить) (Thread)
[User Picture]From: archaicos
2018-05-04 04:55 am
Ещё есть ревью и тесты. Но и их не хватило.
(Ответить) (Parent) (Thread)
From: caztd
2018-05-03 07:42 pm
Если кому-то интересно, как обстоят дела с выявлением подобных багов компилятором:
https://stackoverflow.com/questions/44706699/detecting-access-to-out-of-scope-variables

Короткое резюме: Не умеют, потому что до недавних пор выделение стека для локальных переменных делалось в один проход. И такие баги очевидно не вылезали.
(Ответить) (Thread)
[User Picture]From: avva
2018-05-03 09:39 pm
О, спасибо, это весьма интересно!
(Ответить) (Parent) (Thread)
[User Picture]From: 0ptr
2018-05-03 09:56 pm
>Берем исходники в этот момент, строим две версии компилятора, старую и новую. Компилируем все дерево исходников старой - бага нет, новой - баг есть. Компилируем все дерево старой, и начинаем искать, какие исходники приводят к проблеме, если только их построить новой.

Сложно как-то очень. ПО нужно постоянно компилировать разными компиляторами в разной конфигурации (debug & release) и тестировать. Тогда бы эта ошибка наверняка вылезла еще когда ее внесли.
(Ответить) (Thread)
[User Picture]From: archaicos
2018-05-04 05:01 am
Эт хорошо, но нужно поддерживать исходник и все эти разные makefile'ы в состоянии чтобы всё компилировалось и работало. Когда везде есть gcc, как-то лениво чтобы ещё и clang, и msvc++, и ещё бог знает что.
(Ответить) (Parent) (Thread) (Развернуть)
From: (Anonymous)
2018-05-04 12:39 am
Анатолий, вы - поэт. Замечательный пересказ истории.
(Ответить) (Thread)
From: vfork
2018-05-04 05:47 am
Очень красиво, хотя баг в обшщем-то детский. Меня смущает другое:

>>> Компилируем все дерево старой, и начинаем искать, какие исходники приводят к проблеме, если только их построить новой.

Эээ? Вам очень повезло, что они совместимы по ABI и библиотекам...
(Ответить) (Thread)
From: (Anonymous)
2018-05-04 11:45 am
Это не повезло, это нормально. Если вы имеете дело с MSVC, это вам не повезло, у остального мира таких проблем нет (ну, практически, не надо мне рассказывать про gcc dual ABI saga).
(Ответить) (Parent) (Thread)
[User Picture]From: shadow_ru
2018-05-04 06:10 am
Так не надо использовать языки с сайд-эффектами.)
(Ответить) (Thread)
From: (Anonymous)
2018-05-04 11:51 am
А сайд-эффекта там как раз и нет.
(Ответить) (Parent) (Thread)
[User Picture]From: aosypov
2018-05-04 03:35 pm
гы...

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

Угадаете, куда добавили новый номер?
(Ответить) (Thread)
From: (Anonymous)
2018-05-05 06:15 am

В середину?

Ну или в начало.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: polenova
2018-05-05 11:43 am
Я не пишу на С/С++ больше 20 лет. Но когда я еще работала на С, в моей компании за такие баги "убивали на месте". Нет, у нас не увольняли, мы были старт-ап, но могли понизить, урезать зарплату, а мордой об стол возили бы еще год, не меньше. Может быть дело именно в том, что компиляторы были глупые, и вернуть указатель на массив, не помеченный static - ошибка вылетала быстро ( по умолчанию массив хранится в стеке, но полагаться на это нельзя, это вбивалось в голову, как употребление неинициализированных переменных, курс молодого бойца).. Поскольку в те времена и стэк был маленький - нас за статики гнобили. Я сильно расслабилась в мире, где не надо думать о размере стека, о памяти, но до сих пор интуитивно избегаю подобных ситуаций. Сначала даже не поняла, что можно вернуть указатель на локальную переменную, а потом вспомнила - мы ж под разными версиями Юникса работали на 13 платформах, у всех разные возможности, да еще поддерживали версии на японском, казалось бы локаль не влияет, но у них был немного другой компилятор. Хоть на одной версии слетит.
А константы вообще в одном месте кода держат и минимизируют их использования - это же очень сладкий источник багов.
Так написан Хром? Кошмар.
(Ответить) (Thread)
From: (Anonymous)
2018-05-05 01:57 pm
Стартап ваш развалился?
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: bookworm_the
2018-05-06 09:54 am
неплохо бы компилятору, при таких нововведениях, проверять-таки код на подобные "изменения поведения" - и хотя бы информировать "ворнингами"

или даже отдельная группа ворнингов - "переходные", например

Edited at 2018-05-06 09:54 (UTC)
(Ответить) (Thread)
[User Picture]From: urod
2018-05-08 09:29 pm
+100

Очень плохо, если за 30 лет существования С++ компилятора он не научился предупреждать о таких вещах. Ещё хуже, если, как тут пишут, ни один из четырёх компиляторов этого не умеет.

Edited at 2018-05-08 22:54 (UTC)
(Ответить) (Parent) (Thread)
From: kikzan
2018-05-06 07:49 pm
Оффтоп. Вы же вроде интересуетесь математикой? Не в курсе, как считали раньше синусы и косинусы в библиотеках через exp()? Т.е., что через степени числа е. Я один раз видел это в библиотеках борланд С, но это было предельно давно.
(Ответить) (Thread)
[User Picture]From: avva
2018-05-07 01:07 pm
Если есть поддержка комплексных чисел, и для них уже есть exp, то это легко: например cos(x) это вещественная часть комплексного числа exp(ix).

Если есть только exp() для вещественных чисел, то по-моему он не помогает вычислять синусы и косинусы.

Возможно, вы видели этот алгоритм или его вариант:
https://ru.wikipedia.org/wiki/CORDIC
(Ответить) (Parent) (Thread) (Развернуть)
From: bopstr
2018-05-08 03:00 pm
"Помечаем массивы static, проблема решена."
Интересно, что такое решение проблемы не создаёт проблему с параллельным выполнением только благодаря "Magic statics" - начиная с c++11, компилятор синзронизирует инициализацию статических переменных. Без "magic statics" получился бы initialization race condition.

(Ответить) (Thread)
[User Picture]From: trotil
2018-05-10 08:22 am
C++11 ввели модификатор thread_local показывающий что каждый тред будет иметь свою версию этой пере-
менной, и её можно инициализировать, и она расположена в TLS (Thread Local Storage)

thread_local int tmp=3;

(из книги Юричева Д.)
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: criblycrablybum
2018-05-08 08:13 pm
теперь-то мы знаем, что архитекторы в гугле сами пишут и отлаживают скрипты
(Ответить) (Thread)
Страница 2 из 3
<<[1] [2] [3] >>