?

Log in

No account? Create an account
баг (программистское) - По делам сюда приплыл, а не за этим — ЖЖ [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:
[User Picture]From: prol_prolych
2018-05-03 11:56 am
Массивы констант используются через указатель после выхода из блока кода, в котором они объявлены? :о)))
За такое убивать надо!
Причём и кодера, который такое пишет и тех, кто такой компилятор накосолапил, который такое пропускает.


(Ответить) (Thread)
[User Picture]From: dzz
2018-05-03 12:03 pm
Принципиально, что не просто указатель, а на стек.
(Ответить) (Parent) (Thread)
[User Picture]From: prol_prolych
2018-05-03 12:08 pm
Подозреваю, что если в компиляторе поиграть ключами оптимизации, то ошибка может исчезнуть :о))) Когда компилятор решит, шо не стоит так агрессивно юзать стек в целях оптимизации.
(Ответить) (Parent) (Thread)
[User Picture]From: dzz
2018-05-03 12:52 pm
"Мерцательные" баги - самые неприятные. Если ошибка при одних настройках компилятора воспроизводится, а при других - нет, то порой можно убиться веником, докапываясь до причин.

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

Edited at 2018-05-03 12:53 (UTC)
(Ответить) (Parent) (Thread)
[User Picture]From: prol_prolych
2018-05-03 01:10 pm
О да... мерцающие баги - ето уровень вхождения в мифы, легенды, тосты :о)
(Ответить) (Parent) (Thread)
From: karajel
2018-05-03 12:10 pm
Это язык такой. Способы выстрелить себе в ногу не ограничены даже фантазией.
(Ответить) (Parent) (Thread)
[User Picture]From: prol_prolych
2018-05-03 12:14 pm
Разве в спецификации С++ нету правила, что объявления внутри блока не видны наружу?
(Ответить) (Parent) (Thread)
[User Picture]From: mopexod
2018-05-03 12:17 pm
Использовали указатель, видимо, из внешнего скопа. А сами переменные снаружи скопа, конечно, не видны.
(Ответить) (Parent) (Thread)
[User Picture]From: prol_prolych
2018-05-03 12:20 pm
Да, я уже вспомнил, шо так тоже можно :о)))
(Ответить) (Parent) (Thread)
[User Picture]From: dzz
2018-05-03 01:31 pm
Достаточно из функции возвращать указатель.
(Ответить) (Parent) (Thread)
From: ichthuss
2018-05-03 06:00 pm
Объявлени, разумеется, не видны. А вот указатель может указывать на что угодно, в том числе на уже пропавший объект.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: pargentum
2018-05-03 12:17 pm
Компилятору такое отловить затруднительно, кроме совсем уж тупых ситуаций.
(Ответить) (Parent) (Thread)
[User Picture]From: prol_prolych
2018-05-03 12:19 pm
ну да, из-за указателя :о)))

Слава Богу, шо есть Го, и не нужно паранойить за самим собой :о)))
(Ответить) (Parent) (Thread)
[User Picture]From: mynine
2018-05-03 01:13 pm
В C++ тоже есть смарт-указатели, если их пользовать, то тоже такие баги исключены. Беда что пользовать их не слишком удобно.

В Go еще надо настраивать GC, у меня уже были случаи когда при интенсивной работе выжиралась вся память.
(Ответить) (Parent) (Thread)
From: karpion
2018-05-03 04:12 pm
При раздельной компиляции процедур, находящихся в разных файлах, это довольно трудно заметить и отследить, на что был дан указатель.

Язык Си - довольно опасный. Он был написан крутыми парнями и предназначался для крутых парней - которые знают+понимают, что делают.
(Ответить) (Parent) (Thread)