LINUX.ORG.RU
ФорумTalks

[ничего не поделаешь, это...] доставляющая история про memcpy


0

2

http://avva.livejournal.com/2323823.html

Для Ъ будут спойлеры:

29 сентября 2010 года. Пользователь "JCHuynh" открывает новый баг на сайте Федоры о том, что 64-битный флэш-плагин от Adobe перестал нормально проигрывать mp3-файлы, выдает все время какой-то треск вместо правильного звука.
В Интеле работают хорошие программисты
А в новой, при копировании от конца к началу, выходит ошибка. Но не всегда, а лишь на некоторых процессорах и в некоторых условиях. И пока что никто этого еще не знает, в конце июня прошлого лета. 

Чипсы это яд. Не жри чипсы, не жри!

★★★★☆
Ответ на: комментарий от geekless

>а вторая — нет

Ты ошибаешься. Нужно смотреть шире. Клиентские приложения ломают обе реализации.

|src|dst|src+size|dst+size|

Если dst-src = size/2, то область применения, надеюсь понятна. Нельзя утверждать, что никто этим сейчас не пользуется.

Т.е. Линусов патч тоже способен выявить огромное количество бажных аппликаций.

Именно поэтому нужно руководствоваться стандартом, как последней инстанцией. И не делать фанатичных выпадок в сторону адекватных людей.

ttnl ★★★★★
()
Ответ на: комментарий от stevejobs

набор автотестов, которые воспринимать как спецификацию

NO WAY! Писать тесты, по ним писать программу, по ней писать спецификацию? NO WAY!

Xellos ★★★★★
()
Ответ на: комментарий от geekless

одна из которых ломает неизвестное количество клиентского кода

одна из которых еще сильнее ломает неизвестное количество уже сломанного клиентского кода

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от Pavval

Как и в случаях, когда надо забить на пользователей и думать о фанатизме (когда у него 12309 не воспроизвелся)

devl547 ★★★★★
()
Ответ на: комментарий от Xellos

> NO WAY! Писать тесты, по ним писать программу, по ней писать спецификацию? NO WAY!

this way is TDD: http://ru.wikipedia.org/wiki/Разработка_через_тестирование

один из самых крутейших методов, если его асилить. Это нелегко, но уж точно не сложнее, чем через 20 лет чинить костыли, авторы которых давно умерли.

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от leave

Может, им вообще отдельный глибц написать?

Только вот не надо гиперболизировать. А то так любое утверждение можно довести до абсурда. Ф-я, которая копирует байтики из одного места в другое и glibc. Чувствуете разницу?

nanoo_linux
()

*тихонечко*
а freebsd и netbsd libc memcpy и memmove одно и тоже, на асме писано с проверкой overlapping-а ^_^

hizel ★★★★★
()
Ответ на: комментарий от geekless

Что ANSI C? Номер параграфа из спецификации языка и библиотеки покажи.

легко

2.14.4 memcpy

Declaration:

void *memcpy(void *str1, const void *str2, size_t n);

Copies n characters from str2 to str1. If str1 and str2 overlap the behavior is undefined. Returns the argument str1.

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от nanoo_linux

>RIP

В том-то и проблема, что оно не «упокоилось с миром». Зловещие мертвецы иногда просыпаются и всех пугают своим видом.

ttnl ★★★★★
()
Ответ на: комментарий от nanoo_linux

>и в RIP

Ты это, на NetBSD руку то не поднимай. Кто знает, в каком девайсе она работает у тебя в доме.

devl547 ★★★★★
()
Ответ на: комментарий от leave

Интересно, такое только у Федоры? Или это общая проблема для всех дистрибутивов?

LongLiveUbuntu ★★★★★
()
Ответ на: комментарий от ttnl

> Ты ошибаешься. Нужно смотреть шире. Клиентские приложения ломают обе реализации.

Хорошо, уточним. Имеется три варианта реализации memcpy.

1. Классическая реализация ничего не ломает по определению.

2. Реализация Торвальдса ломает код разработчиков, которые сознательно закладывались на текущую на тот момент реализацию функции. Мне лично не верится, что такие сказочные долбогрызы существуют в природе, но предположим, что они есть. В любом случае, их явно намного меньше, чем тех, кто просто случайно использовал memcpy вместо memmove.

3. Наконец, текущая реализация может ломать любой код, который пользуется неспецифированным поведением memcpy — независимо, случилось ли это случайно или намеренно.

Если подходить с такой меркой, то единственным приемлимым для всех решением является откатиться на классическую реализацию memcpy, после чего закрепить данное поведение в стандарте. Пусть эта функция лежит там древним говном мамонта для миллионов строк уже написанного кода, который её использует. Новому коду рекомендовать использовать memmove, и только её.
В новой же версии спецификации C, если она когда-нибудь в будущем появится, и вовсе объявить её deprecated.

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

Напомню, что POSIX основывался всегда именно на этом принципе: учёту существующих практик и имеющегося кода, вместо абстрактной корректности и идеальности. Вопящие же про windows-way могут и дальше окукливаться в своей скорлупке, наплевав на факты.

geekless ★★
()
Ответ на: комментарий от stevejobs

Здесь сказано только про кодирование. Про сбор требований и создание спецификации ничего не сказано.

Xellos ★★★★★
()
Ответ на: комментарий от hizel

> а freebsd и netbsd libc memcpy и memmove одно и тоже, на асме писано с проверкой overlapping-а ^_^

Просто над *bsd тихо и спокойно работают серьёзные люди, которые понимают, что компьютер для человека, а не человек для компьютера.

geekless ★★
()
Ответ на: комментарий от Xellos

Стандартный вокрфолу такой: обсуждение -> требования в печатном (бумажном) виде -> задача для разработчика -> описанный цикл кодирования (задача превращается в тест, и дальше по накатаной)

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от stevejobs

Ну и еще:

3.4.3
undefined behavior
   behavior, upon use of a nonportable or erroneous program construct or of erroneous data,
   for which this International Standard imposes no requirements
   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).
EXAMPLE
   An example of undefined behavior is the behavior on integer overflow.
geekless ★★
()
Ответ на: комментарий от Shlyapa

И если поведение всегда будет defined, то это будет нарушение стандарта? Лол.

если поведение undefined, значит на него нельзя рассчитывать. И обижаться, когда ты лоханулся. Это написано в самом начале стандарта, кстати, но я сейчас не найду где. Времена, когда для сдачи экзамена по Си нужно было учить этот стандарт наизусть, безвозвратно прошли.

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от geekless

> А я утверждал, что реализация glibc нарушает спецификацию?

Нет. Ты утверждал, что изменение в glibc нужно откатить. А я тебе намекнул, что изменение не нарушает стандарт, и откатывать его нет оснований.

Вы хоть смотрите, на что отвечаете...

Попытайся думать над тем, что тебе пишут.

tailgunner ★★★★★
()
Ответ на: комментарий от stevejobs

если поведение undefined, значит на него нельзя рассчитывать. И обижаться, когда ты лоханулся. Это написано в самом начале стандарта, кстати, но я сейчас не найду где. Времена, когда для сдачи экзамена по Си нужно было учить этот стандарт наизусть, безвозвратно прошли.

То есть: Если вызов memcpy(a, a + 1, 10) может приводить к стиранию таблицы разделов, то он обязан это делать? А ведь он может...

Это задача разработчика клиентского кода — никогда не использовать undefined поведение. А задача разработчика реализации — как можно корректнее обрабатывать ситуации undefined behavior, когда они всё имеют место. А они будут иметь место в силу несовершенности этого мира. Иной подход — безответственность.

geekless ★★
()
Ответ на: комментарий от tailgunner

> Нет. Ты утверждал, что изменение в glibc нужно откатить. А я тебе намекнул, что изменение не нарушает стандарт, и откатывать его нет оснований.

Моя аргументация за откат не основана на утверждении о нарушении спецификации. Значит и ваш «аргумент» служить аргументом не может. Не разводите демагогию и не прикидывайтесь шлангом.

geekless ★★
()
Ответ на: комментарий от stevejobs

Что тебе мешает в случае, когда куски памяти могут перекрываться, не использовать memcpy, даже если это будет просто алиас для memmove? Продолжай использовать в одних местах memcpy, в других - memmove, в соответствии со стандартом :)

Shlyapa ★★
()
Ответ на: комментарий от geekless

>Хорошо, уточним. Имеется три варианта реализации memcpy.

Рад, что стало понятно.

1. Классическая реализация ничего не ломает по определению.

Опять мимо. Есть куча бажного софта, который будет использовать memcpy в случае |src|dst|src+size|dst+size|. Эта ошибка может проявляться один раз из ста или даже из тысячи, но она есть, просто никто её еще не нашел. Для таких программ самым верным выходом будет решение Линуса, но это решение будет ломать другие программы! Замкнутый круг, как видишь.

Удовлетворить всех исправлениями glibc нет никакой возможности. Для этого нужно пойти по пути windows, парсить заголовки окон и искать магические числа в бинарниках. Но такой подход нежизнеспособен, такая библиотека лишена будущего.

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

ttnl ★★★★★
()
Ответ на: комментарий от geekless

> Моя аргументация за откат не основана на утверждении о нарушении спецификации.

Это значит, что технических аргументов у тебя нет.

Не разводите демагогию и не прикидывайтесь шлангом.

Демагогия - это аргументы, не подкрепленные техническими основаниями. Так что разводишь демагогию ты. И прикидываешься шлангом тоже ты.

tailgunner ★★★★★
()
Ответ на: комментарий от geekless

корректнее обрабатывать ситуации undefined behavior

Undefined по определению невозможно обработать корректно. Разве что выстрелить из монитора в лоб программисту.

Xellos ★★★★★
()
Ответ на: комментарий от tailgunner

Это значит, что технических аргументов у тебя нет.

У тебя, в общем-то, тоже нет аргументов в пользу изменения glibc, кроме того, что оно уже сделано.

unsigned ★★★★
()
Ответ на: комментарий от ttnl

Опять мимо. Есть куча бажного софта, который будет использовать memcpy в случае |src|dst|src+size|dst+size|. Эта ошибка может проявляться один раз из ста или даже из тысячи, но она есть, просто никто её еще не нашел. Для таких программ самым верным выходом будет решение Линуса, но это решение будет ломать другие программы! Замкнутый круг, как видишь.

Не так. Вы неверно видите проблему, и в итоге получается много слов ни о чем. Мы рассматриваем только тот массив кода, который корректно работает на классической реализации, что была там десятелетиями. Этот код включает в себя как код корректный (не использующий UB), так и код некорректный, но работающий. В условиях, когда есть 3 корректных реализации, однозначно надо выбирать ту, которая ломает как можно меньше этого кода. Вполне очевидно, что классическая реализация не ломает кода вообще — её и оставляем.

Что касается кода, который работает неверно, то нам нет до него никакого дела. Если он не работал со старой версией libc, нам совершенно не нужно беспокоиться о том, что он не работает с новой. Фактически, этого кода для нас, если смотреть с позиций разработчиков libc на клиентский код, не существует. Этот код для нас попадает в категорию «новый код, который появится в будущем, когда баги поправят».

Удовлетворить всех исправлениями glibc нет никакой возможности. Для этого нужно пойти по пути windows, парсить заголовки окон и искать магические числа в бинарниках. Но такой подход нежизнеспособен, такая библиотека лишена будущего.

Покажите мне место, где я в этом треде предлагал «парсить заголовки окон и искать магические числа в бинарниках», либо не пишите ерунду.

geekless ★★
()
Ответ на: комментарий от Xellos

Undefined по определению невозможно обработать корректно. Разве что выстрелить из монитора в лоб программисту.

Т.е. ты согласен, что memcpy(a, a + 1, 10) будет стирать таблицу разделов потому что может? Прямой ответ: да или нет.

geekless ★★
()
Ответ на: комментарий от geekless

Но ведь любая из этих реализаций не ломает корректного кода. А адобы, что пишут некорректный код - ССЗБ.

Yareg ★★★
()
Ответ на: комментарий от Yareg

Вы тоже не отличаете [i]код, который корректно работает[/i], от кода не использующего UB?

А адобы, что пишут некорректный код - ССЗБ.

Адобами проблема не ограничивается. Нам совершенно не известно, какие приложения может затронуть это изменение. В посте по ссылке ТСа как раз приводится пример со Squashfs, в которой бага появилась в процессе многократного изменения изначально правильного кода. Никто от этого не застрахован, тем более, что memcpy никогда не проверяла свои праметры на правильность и никак не давала знать разработчику об ошибке.

geekless ★★
()
Ответ на: комментарий от Xellos

> да.

Предлагаю вам реализовать это полезное начинание. Пропатчите glibc так, чтобы передача в memcpy некорректных аргументов приводила к описанному поведению. И используйте на своей машине.

geekless ★★
()

ОМГ, сколько людей которые свято верят что glibc должен специально затачиваться под нужды адоба и что «спецификации это всё херня, костыли решают».

Линус тоже отжигает, притянул за уши «мнение» конечных пользователей. Ну да, ну да, миллионы мух не могут ошибаться.

Линус уже не то(р)т.

true_admin ★★★★★
()
Ответ на: комментарий от geekless

Адобами проблема не ограничивается.

да, говнокода — тонны. Он не нужен ) В Apple сабжевого вопроса вообще бы не возникло.

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от geekless

Адобами проблема не ограничивается

Пациентов лечить надо а не прогибаться под них. Сегодня они не прочитали маны и посадили не совсем очевидный баг а завтра... Короче, будет тенденция.

true_admin ★★★★★
()
Ответ на: комментарий от stevejobs

Я не понял, для нас теперь фантазия со ссылкой на Apple стала техническим аргументом?

Он не нужен )

Это фанатики из glibc не нужны.

geekless ★★
()
Ответ на: комментарий от geekless

и никак не давала знать разработчику об ошибке.

Потому что это C а не perl, python, php, whatever. Хотя, конечно, могли бы и добавить ОПЦИОНАЛЬНУЮ проверку(типа #define FORTIFY_SOURCE 1 или версия с дебагом, но это уже другая проблема). Но, опять таки, valgrind(на сколько я понял) эту проблему показывает. Если в адобе про valgrind ничего не знают то ой.

Скорей бы флеш окончательно умер.

true_admin ★★★★★
()
Ответ на: комментарий от geekless

Зачем? Я в своих программах не пользуюсь undefined поведением. А если пользуюсь, беру на себя ответственность, что однажды из монитора может вылезти vsl.

Xellos ★★★★★
()
Ответ на: комментарий от geekless

>В условиях, когда есть 3 корректных реализации, однозначно надо выбирать ту, которая ломает как можно меньше этого кода. Вполне очевидно, что классическая реализация не ломает кода вообще — её и оставляем.

Ты оперируешь несуществующими аргументами. Оценить количество потенциально завязанного на ту или иную реализацию софта невозможно, если конечно ты не телепат. Нельзя предсказать выявленное количество таких программ в будущем. И пока мы находимся на сайте linux.org.ru, а не битваэкстрасенсов.рф, давай уж будем оперировать объективными данными.

Что касается кода, который работает неверно, то нам нет до него никакого дела. Если он не работал со старой версией libc, нам совершенно не нужно беспокоиться о том, что он не работает с новой.

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

Если чем-то и нужно руководствоваться, то только стандартом.

Покажите мне место, где я в этом треде предлагал «парсить заголовки окон и искать магические числа в бинарниках», либо не пишите ерунду.

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

ttnl ★★★★★
()
Ответ на: комментарий от Xellos

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

geekless ★★
()
Ответ на: комментарий от geekless

Делают. И ядро падает в корку. И винда падает в синий экран. И РБМК начинает внезапно разгоняться, вместо того чтобы замедлиться. Нормально, пусть ошибаются!

Xellos ★★★★★
()
Ответ на: комментарий от ttnl

> Ты оперируешь несуществующими аргументами. Оценить количество потенциально завязанного на ту или иную реализацию софта невозможно, если конечно ты не телепат.

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

Нельзя предсказать выявленное количество таких программ в будущем.

Их не придётся выявлять. Пусть себе работают спокойно через данную конкретную реализацию UB, а весь новый код в добровольно-принудительном порядке пересадим на полное использование memmove.

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

Поясните, а то ничего не понятно.

Если чем-то и нужно руководствоваться, то только стандартом.

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

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

Это вы сейчас с кем разговаривате? Что именно вы тут собрались отличать и от чего?

geekless ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.