Суббота для человека или человек для субботы?

Со всевозрастающим изумлением читаю дискуссии про memcpy, glibc, Линуса, Adobe и Дреппера:

(русскоязычные - они свежие, на LWN все уже отшумело три месяца назад).

И думаю я следующую думу: сама тема не оставляет (девелоперов) равнодушной, раз столько понаписали, делит девелоперов на 10 две группы очень четко. Причем, для меня ответ очевиден, равно как он столь же очевиден (но другой) для другой группы.

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

Для тех кто в танке, суть проблемы (при взгляде с одной из сторон):

  • memcpy() может вести себя "непонятно как" при копировании overlapped-регионов. И это описано в спецификации функции (не менявшейся много лет) именно такими словами, undefined behaviour.
  • Но по факту, поведение было детерминированным и копирование было в одну сторону.
  • Новая реализация стала недетерминированной, отчего сломалось некоторое количество программ. В число сломанных программ попал Adobe Flash Player, который очень распространенный и при этом распространяется в бинарях т.е. быстро починить нельзя. Более того, сломалась неподдерживаемая (но более хорошая) 64-битная версия, которую чинить и не будут скорее всего.
  • При этом, новая реализация быстрее (это тоже подвергается сомнению, но допустим что быстрее).
А, да, помимо этого, направление копирования зависит от архитектуры процессора и размера копируемых данных, поэтому вы можете обтестироваться на одном горшке и не увидеть проблемы.

Что должен делать разработчик библиотеки?

То, что под раздачу попал Adobe - добавляет веселухи, потому как их не любят.

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

Comments

Нууу, я бы не стал ставить вопрос как «не надо собирать в одной команде (компании, стране, вселенной) людей, отвечающих на этот вопрос по-разному». Если отвечают по-разному, но признают в определённых ситуациях правоту второй точки зрения — это может быть допустимо.

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

"существуют ситуации", когда ответ менее очевидный (скажем, можно легко добраться до userbase, до всех трех человек).

Но данная ситуация хороша именно своей остротой: затронуто много пользователей, добраться до них нельзя, починить - нельзя. И ответ "пусть Adobe чинит свой кривой варез" очень показателен.

Боюсь, что в современном мире линукс любое изменение у кого-нибудь что-нибудь да сломает, и на каждый чих не наздравствуешься :)

Все же Adobe, который единственный в этой ситуации ВООБЩЕ В ПОЛОВОЙ ЧЛЕН НЕ ДУЕТ, вызывает у меня немое восхищение.

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

Данную ситуацию, усилиями обеих сторон доведённую до абсолюта, вполне можно использовать как лакмусовую бумажку. Менеджер по работе с клиентами (и менеджер проекта) должен быть «Линус-положительный», тимлид — «Дреппер-положительный». Тогда есть шанс соблюсти интересы клиентов и не сильно удалиться от идеологической стройности. В этом плане я поддерживаю комментарий ниже

Но вообще я считаю, что причина слабой общественной популярности линукса (в сегменте домохозяек) — именно подход Дреппера.

"разноположительность" чревата конфликтами. Потому что или PM (всегда) может продавить юзеро-ориентированное решение и тогда тимлид будет (всегда) унижен и оскорблен. Либо не может (никогда), тогда юзер будет без флеша по полгода.

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

Отсутствие в команде Дреппер-положительного программиста приведёт к спагетти-коду и наплевательству на контракты. Видел такое, знаю. Отсутствие у него прав на продавливание изменений приведёт к тому, что он сам уйдёт.

В результате или код скатится в спагетти и/или общую недетерминированность, или будет стройно соблюдать все контракты, несмотря на интересы бизнеса (который, заметим, платит деньги).

Что делать?

Оглядываясь на прожитые годы ("25-й год в коммерческом программировании"), я бы про себя лично сказал, что Линус-положительность в данном примере - это понимание приоритетов поддержки в частности и юзера - вообще. При этом я знаю из личного опыта, что хороший код в long run - окупается.

Другими словами, Линус-положительность - не синоним совсем плохого кода или чего-то подобного. Что, собственно, Линус успешно доказал собственными делами.

Ну да, согласен. Упустил в предыдущем комментарии слова может привести к спагетти-коду.

Спасибо.

А чтобы усугубить: склонность к инженерному подходу (торжество спецификаций над юзером) может привести к другой беде: hello world на 500 килобайт кода и иерархию из 18 классов (500к возьмутся из юнит-тестов к этим классам).
Но код будет совершенно отличным!

Кстати о "контрактах" в смысле интерфейсов.

У обсуждаемой memcpy() было нестрогое писаное описание ("хрен знает как оно работает на overlapped") и более строгое фактическое описание ("всегда в одну сторону").

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

Такие дела.

Да, я уже отмечал этот момент, что есть стандарт «де-юре» (сиречь POSIX), и есть — «де-факто», тот самый, который копировал от src до src+n, и позволял использовать заполнение паттернами и т.п.

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

Вообще, в такой ситуации есть ещё вариант — в порядке бреда — подправить стандарт, чтобы определить неопределённое поведение memcpy :)

Вот насчет "не надо" - это ты зря. Как раз надо. Т.е. придется разруливать споры, но в результате будет некий баланс между перфекционизмом и реальным миром.

С языка снял :) И хотя в одну телегу если и не неможно, но всё же трудно впрячь эти две точки зрения как-то гармонизировать ситуацию выглядит заманчиво :)

Макс, ну как ты ее гармонизируешь?

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

Ну мы бы друг другу горло не перегрызли бы, так что к чему-нибудь да пришли. :)

По прямому вопросу -- у меня два прямых ответа. В коммерческом софте -- откатить изменения. В ОСС -- послать Адоб. Просто для меня тут два разных устава, а ответ в том, что ломать устав плохо.

Ну то есть в OSS - "человек для субботы". Неудивительно, что линукс на десктопе идет так туго :)

Для меня такая расстановка приоритетов очень странна. При том, что я сижу сразу на всех четырех стульях: "платный/бесплатный" и "OSS/closed source". Но я не переключаю голову в зависимости от проекта, тем более что им свойственно мигрировать по этим стульям.

Мотивации совершенно разные.

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

И представь, что Федя Полукедов добавил классную фичу в свой новый тоссер. И тут на него наехали, что в relcom.commerce у кого-то что-то отвалилось. Мне смешно уже сейчас.

Аналогия кривая, как любая аналогия, ибо отвалилось не на "коммерческих сайтах", а просто типа флэш. Интернет-радиостанции, например.

Выправленная аналогия такая: после правок феди полукедова перестали распаковываться RAR-ы, что из relcom.porno, что из su.books. Причина проблемы известна, но поправить RAR нельзя, ибо Рошаль на все забил.

Что касается мотиваций, они вообще разные (в моем конкретном случае мотивация вообще примерно одна, а вот способы достижения промежуточной цели зависят от цели)

Наверно кривая, я её переупростил. :) Меня в ней интересовала иллюстративность того, что люди и сообщества могут свободно пересекаться оставаясь собой. То есть и люди и стулья, конечно.

И о мотивациях. Конечно своя, но совпадение фрагментов мотивация и усилий и используются в сообществе.

Я всё сделал хорошо и даже лучше, из-за чьей-то криворукости где-то что-то отвалилось и теперь от меня требуют, чтобы я обратно сделал плохо. Зачем это мне? Кому я тут должен?

И для коммерса масштаб проблемы измеряется не количеством абстрактных людей. Если у миллионов пользователей OpenOffice перестанут открываться документы их собственных пользователей, разве это остановит коммерческих разработчиков? :)

Ну и да, по этому примеру, "человек для субботы" в лице Тимура Цыганко (который запомнился более всех) и вообще всех битв за гейтование и против гейтования - они меня и тогда, скоро будет 20 лет как, изумляли до полного изумления.

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

Ну это маятник. На транспорте вдруг вырастает ЖЖ, гейтование в ЖЖ и всё такое прочее :)

Немогу не вспомнить, как как-то в конце 90-х -- начале нулевых Мозилла ВНЕЗАПНО начала печатать в постскрипт юникодом. Ничего так, что на тот момент НИ ОДИН растеризатор, ни программный ни аппаратный этого не понимал. Нихера не работает, зато "правильно".

а с чего бы уставам быть разным?
в осс пользователь -- не человек, что ли?

От этих пользователей одно огорчение, руки у них кривые, пропатчить KDE под FreeBSD не могут

ох да. свиньи не кормлены, поля не паханы, а они...

а что такое KDE? (навно хлопая глазками)

это такая штука, которую надо всё время патчить. и непременно под FreeBSD!

Конечно, не человек. В OSS человек - это только разработчик, ну или хотя бы человек, который грамотные багрепорты контрибьютит. Чистый пользователь, который ничего не контрибьютит, это даже не вроде пойнта в фидо. Это кошка, которая питается выброшенными на помойку объедками. Ну да, бывает еще домашняя кошка, которую какой-нибудь челвоека специально кормит.

Но надо учитывать, что любой разработчик ОДНОВРЕМЕННО является пользователем.

А он нигде не человек. :)

Просто одних интересует шерсть, а других -- мясо. :) Или менее грубо -- пользователь тут не субъект, а объект.

Нет, когда Вы общаетесь с человеком лично -- это конечно человек. Когда Вы работаете в команде более десяти человек и пользователей у вас не одна тысяча, то общаетесь Вы не столько c человеком, столько с тысячами записей в БД. Вы работаете с запросами на изменения.

А на уровне индустрии -- человек и пользователь это какой-то маркетинговый миф и условность.

Тут проблема интереснее.

Вот представь Firefox и его пользователей. Допустим, версия 7.18.42 перестала отображать какой-то достаточно популярный сайт, вроде cnn.com (не гугл, но тоже много). Допустим, даже, на cnn кривая верстка, но IE и прочие Operы его отображают. Разработчики FF не будут кричать "пусть эти уроды переделают сайт", а постараются вернуть совместимость с версией 7.18.41.

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

Реальная проблема -- FF 3.6 перестал открывать плагин консоли VMWare. Это не заинтересовало ни FF ни VmWare. И что?

Не очень большой масштаб? Хорошо.

Сколько лет интеграция сквида и спамасасина делалась какими-то студенческими соплями на пхп?

А про всякие выверты в html и его обработке -- это да. Возможно что скорее всего поправят стандарт, а не сайт. Но такая практика не пошла на пользу ни разработчикам браузеров ни разработчикам сайтов. :)

А зачем сквид со спамассасином скрещивать?

clamav

Это у меня оговорка, видно по Фрейду, спасибо что поправили. :)

Масштабы важны. Флэш касается примерно каждого первого, а vmware - сам понимаешь.

Ну на Федоре вообще-то далеко не каждый первый -- десктоп. И не на каждом десктопе Федоры флеш, есть и технологические консоли.

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

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

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

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

А как поступать на практике - это совсем другой вопрос. Маловероятно, что на практике придется столкнуться с такой же чистой ситуацией, "прочих равных" будет больше и реальное решение в похожей (но другой) задачке у меня может оказаться иным. Я против фанатизьму.

"В OSS человек - это только разработчик, ну или"

вот и было выше мудро сказано - фида, такая фида

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

По счастью, есть и нормальные люди. В смысле, разработчики, которые считают людей - людьми.

Без этого тот же Firefox не взлетел бы.

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

В коммерческом софте пользователь - человек, потому что он может ХОТЯ БЫ проголосовать рублем. Другое дело что для интерпретации действий таких людей нужне авгур-маркетолог, который позволит перевести "знамения" на понятный разработчикам язык.

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

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

Не рублем единым. Точнее, бесплатная userbase тоже прекрасно конвертируется в рубли, просто курс ниже.

Поэтому пользователь, который голосует просто установкой (и использованием) firefox или chrome или линукса - он тоже проголосовал. Вниманием. Экономика внимания, туды ее растуды.

Но, конечно, разработчики библиотек эту экономику внимания чувствуют меньше

Firefox - несколько особый случай. Его присутствие можно хотя бы по строчке user-agent в логах web-серверов вычислить.

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

C тех пор и прошло лет 10-12. Они одумались - и получили market share.

В такой четко очерченой острой ситуации (и только в ней), когда работоспособность ю юзера (здесь и сейчас) разменивается на потенциальное ускорение (небось, на 2% или даже на 5)?
И все это длится три месяца, если мы смотрим на реальную ситуации с glibc? И все это время flash player не работает?
По факту - спор не разруливается (ну то есть текущее состояние "пусть адоб сам чинит свое говно" - не есть компромисс ради юзера).

Я вот вообще не вижу "о чем тут спорить". Именно в данной конкретной острой ситуации. И жизненные силы на данный спор тратить не хочу.

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

Она не всегда такая простая. Иногда битва за 2% производительности имеет приоритет, иногда сохранение совместимости. Но всегда пользователь, это да :)

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

В данном случае я всецело на стороне Линуса, просто потому, что он здесь выглядит единственным, кто находится на стороне пользователя.

ИМХО пользователей, которым НУЖНА свежая glibc и flashplayer одновременно - единицы.
а через полгода adobe починит flashplayer в этом отношении.

PS: а вообще flashplayer пожалуй самая глючная штука у меня на десктопе.

> И все это длится три месяца, если мы смотрим
> на реальную ситуации с glibc?
> И все это время flash player не работает?

А какой реально процент пользователей установили новую&поломанную glibc ?

Она (glibc) им скорее всего не нужна, но приехала к ним в апдейте.

А flash им нужен т.к. они хотят страшные ролики про Фукусиму смотреть.

если приехала в апдейте - то что мешает приехать в апдейте обёртки к flashplayer с LD_PRELOAD?
зачем было впутывать в эту историю разработчииков glibc?

Я так понимаю, это же плагины к браузерам, т.е. обертка должна приехать ко всем бывшим и будущим браузерам, правильно? И во всех дистрибутивах?

И ко всем другим программам, которые оказались поломаны (кроме флэша есть еще найденные, а сколько еще не найденных?) ?

Не, если уж быть формалистами и действовать по процедуре, то
а) откатить изменение, выпустить апдейт
б) вернуть изменение; выпустить апдейт с другим major version
Потому что бинарная совместимость то - нарушена.

Ну а дальше, да, можно разбираться, что же делать на самом деле.

Думаю что реально - пока небольшой. Но будет расти. Апдейты, то-се.

Про найм хорошее замечание. Именно так.

Мне как то не ясно чем могут быть полезны чуваки, которым кажется, что правы разрабы либси. Я несколько раз встречался с подобными дебилами. Это феерические кони. Им абсолютно насрать на других девелоперов и юзеров, они сами создают себе какие то рамки-правила а потом следуют им как божьим заповедям. Там кстати в камментах Siamashka Siarhei не увидел профита от изменения, а комрад из интела как то не сказал тестили они или им казалось что чисто теоретически должно быть быстрее.
Я теперь понимаю где находится реальное зло :)
А все кричали микрософт, микрософт.

Проблема не в следовании (выдуманным) правилам, при отсутствии дополнительных обстоятельств следовать им надо, ибо вовсе без правил сильно хуже.

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

Чуваки ж тычут в спеку где написано, что behavior undefined. Если оно undefined, то оно может быть и таким, когда все работает, ан нет, они придумали себе, что нужно именно undefined и типо где то там быстрее. Заметь, про бенефиты никто и не говорил.

> Проблема в том, что при возникновении конфликтов между правилами и реальной жизнью - должен быть какой-то внятный механизм
> разрешения этих конфликтов
Для нормальных людей, как Линус такие механизмы не нужны, собсно об этом и был мой пост. Не берите на работу людей которые программируют (или там еще чего делают) для компьютеров и плюют на окружающих. А то потом получаются всякие http://www.eglibc.org/home :)

я ж вроде зареганый, а капчу спрашивает.

Да, я тоже согласен, что Линус в данной ситуации выглядит разумно, а Дреппер - нет.

И, пожалуй, Дреппера на работу к себе я не хочу.

+1, согласен про найм. Не нужно пытаться объять необъятное и впихнуть невпихуемое (с). Важно достижение результата, а оно будет получено быстрее, когда команда работает как единый организм (а значит - одинаково мыслит), чем когда вместе трудятся лебедь, рак и щука.

Ну если не монополист в своей области и продаётся продукт юзерам, то, конечно надо к ним лицом "чтобы работало" а не попой "вас много а я одна/насовали тут а мне разбирайся/конец квартала, напильником сами доработаете".

Если, скажем, продукт для контор, и есть возможность поставить человека с плёткой "чтобы муштровал" и всё было идеологически правильно, то битте шон, конечно :)

А смысл? Может лучше всё равно исправить, а лишнего этого человека отправить искать новых клиентов? :)

Ну как, моральное удовлетворение от правильности, и даже наверное какая-то экономия если строгий человек заставляет всех пользующихся продуктом людей следовать идеологии :) Теоретически это "правильный путь", но практически -- конь в нечистом вакууме :(

Мне лично симпатичнее "чтобы работало" -- у нас контора с клиентами напрямую общается, и главный приоритет -- счастливый клиент :)

Аналогичный случай имел место в городе Тбилиси в Windows. И там пользователи однозначно считают виноватыми вовсе не криворуких разработчиков софта, а разработчиков Windows.. Но это отдельный вопрос.

А на твой вопрос "что должен делать разработчик библиотеки" там ответ однозначный: делать так, чтоб у пользователя всё работало.
Вот пример: http://deadracoon.livejournal.com/51397.html
У него там ещё более показательные случаи были, но я сейчас найти не могу.

p.s. быстро починить можно, принудительно подсовывая библиотеку посредством LD_PRELOAD со старым вариантом memcpy. Что не отменяет всего остального.

> Новая реализация стала недетерминированной, отчего сломалось некоторое количество программ. В число сломанных программ попал Adobe Flash Player, который очень распространенный и при этом распространяется в бинарях т.е. быстро починить нельзя. Более того, сломалась неподдерживаемая (но более хорошая) 64-битная версия, которую чинить и не будут скорее всего.

Гентушники с помощью ломика, objdump, dd и какой-то там матери это при установке чинят подменой вызовов memcpy(2) на memmove(2). Хотя это тот ещё хак, конечно...

Это очень плохой хак, потому что memmove работает хоть и идеологически правильно, но скорее всего, не так, как прежний memcpy.

Это нормальный хак. Да, memmove всегда работает "правильно" (memcpy и старый непредсказуемое что-то выдавал в случае dst = src + 1), но если кто-то закладывался на поведение старого memcpy — то это такой ССЗБ, что я в такое не верю. Во всех остальных случаях они работают одинаково (ну, кроме скорости, очевидно).

PS: что не отменяет того факта, что это всё-таки грязный хак, как не крути.

Так в том-то и дело, что программы сломались именно оттого, что закладывались на поведение старого memcpy.
Конечно, они не специально закладывались, но так уж получилось, что с ним они работают нормально. А с новым - ломаются, потому что он работает по-другому. Но ведь и memmove работает по-другому, так что они и с ним могут ломаться. Поэтому хак не просто грязный, а неправильный.

Нет.

Поведение memcpy в случае пересекающихся регионов неопределено. "Старый" memcpy(char *dst, const char *src, size_t len) работал правильно* в случае dst = src - N (где N < len), новый выдаёт условно непредсказуемый результат, а в случае dst = src + N они оба делают непредсказуемые вещи. memmove всегда работает правильно*. Таким образом, заменой memcpy на memmove мы добиваемся всегда правильной* работы.

Если кто-то закладывался на гарантированно непредсказуемый результат memcpy при dst = src + N, то это гарантированно неправильная программа. И была, и есть. Хотя бы просто потому, что результат зависит от ОС и даже от архитектуры.

То есть хак грязный, но правильный.

----
* В данном случае под "правильной работой" подразумевается, что по адресу dst после выполнения функции будет ровно то содержимое длиной len, что было в src до выполнения.

"Всегда правильная работа" != "поведение старого memcpy"

"Поведение memcpy в случае пересекающихся регионов неопределено" - это оно стандартом не определено, а конкретной реализацией вполне определено. И вот с этой конкретной реализацией программы работали правильно. Если эту реализацию заменить на "правильную", но другую, программы тоже могут работать неправильно.

Ещё раз: конкретной реализацией это не определено. Точка. В том случае, который поменяли — да, было определено (на уровне сложившийся традиции), в обратном случае это всегда был UB, конкретно выливавшийся в разное поведение на (вот только по тому, что у меня под рукой есть) FreeBSD@x86, FreeBSD@amd64, glibc@x86, glibc@x86_64. Во всех трёх случаях будет разный выхлоп. Я не верю, что в здравом уме и трезвой памяти можно на такое закладываться.

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

Да конечно, программы кривые, об этом никто и не спорит.
Там вообще никто не думал, как написать правильно (если б думали, сразу бы и использовали memmove). Уж как написали, так и написали. Но речь-то сейчас не об этом, а только о том, как сделать, чтоб они продолжали работать.

А я может чего-то не знаю? Это "фактическое" поведение memcpy() - оно действительно насколько строго выполнялось всегда и везде? И до этого бага существовали люди которые достоверно знали что в мане-то написано, но memcpy() работает вот так.

Фактически всегда копировали от головы к хвосту.

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

вы сейчас пытаетесь сорвать злость на интеле. Наверняка у них нет в тесткейзах адобовского флеша, и их сложно за это винить. А где можно прочитать о каких-то объективных данных что "всегда копировали от головы к хвосту"?

Откуда у меня злость, если я не пользуюсь линуксом на десктопе?
Мне вся эта история, сама по себе, безразлична, а вот то, какие бездны открылись в человечестве - любопытно да.

Пруфлинк же простой, "оно работало".

Тогда зачем писать про траву? По спецификации можно, вещь элементарная, зачем кому-то использовать memcpy() на потенциально перекрывающейся памяти, непонятно. По факту, действительно, очень немного программ оказались с проблемами.

Я удивляюсь что на gcc никто не наезжает что delete вместо delete[] падает. Тоже, говорят, где-то работает.

В смысле, "зачем"? Хочу и пишу, руки есть, клавиатура, блог собственный.

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

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

Кудато делся мой предыдущий ответ, може потер кто то...

Ответ нашелся - он был со ссылкой, а антиспам у меня теперь дюже подозрительный (потому как достали)

Я его оттуда достал, он там выше есть.

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

Вопрос же вообше шире - а зачем такой дурной вызов, если есть нормальный. Ну вот исторически наросло за 40 лет или сколько там языку C

Присоединяюсь к хору голосов о том, что API должно быть задумано изначально так, чтобы его было трудно использовать неправильно. memmove -- вариант правильного API, memcpy надо было назвать memory_unsafe_copy.

Пропатчил свою libflashplayer.so, заработали игрушки вконтакта ;)

Меня в этой истории больше всего поразил факт наличия большого количества людей ЗНАЮЩИХ что memcpy как-то там "обычно" копирует, и в то же время НЕПОДОЗРЕВАЮЩИХ, что однажды это может прекратится. Этакая инфантильная эрудированность. По моему за такое нужно бить линейкой по рукам, причем длинной, железной и ребром.

А это место такое, небанальное. Представим что есть библиотека, получающая два буфера (in и out) и ее закодировали по спекам, используя memcpy и вообще без задней мысли. Скажем, распаковка чего-то

А потом кто-то решает что-то поэкономить и дает туда один и тот же буфер и как источник и как назначение. Тестирует. Работает! Что там внутри memcpy() - никто и не думает.
Ура, мы поэкономили половину памяти, теперь раскодируем прямо in place.

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

Но я немного о другом. Я о довольно массовых стонах про какое-то "дефакто" поведении memcpy. Т.е. эти люди годами совершенно сознательно "юзали фичу". А теперь эти чрезмерно эрудированые личности жалуются, мол, как же так, что ж такое...

Я например за 20 лет ваяния на c/c++ никаким "дефакто" поведением memcpy() не интересовался, даже в голову не приходило закладыватся на такое. Есть опасения - берем memove и все. Поэтому мне поборников "совместимости" нисколько не жаль, наоборот, наказывать нужно за такие вещи, если умом не доходит.

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

И я не думаю, что кто-то осознанно "юзал фичу". Писали просто memcpy() не задумываясь. Оно работало. Даже если и читали описание, то давно и забыли, работает и зашибись. В типовой ситуации спеки же начинаешь читать только если что-то идет не так, как задумано.

Если бы "просто писали" - надо посыпать голову пеплом, извиниться и выкатить фикс своего продукта. А если люди встают в позы и говорить мол десятилетиямы было "вот так" - то мне подобная осведомленность кажется подозрительной.

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

Сильно много времени на детальное изучение не потратил, да :-)
Сама по себе техническая сторона разруливания конкретной ситуации меня как-то не заинтересовала, пусть у вовлеченных сторон голова болит.
Но вот человеки некоторые удивили.

Ну так десятилетиями было так, что реализация memcpy() была строже, чем ее описание. Вместо undefined behaviour на пересекающихся регионах, поведение было вполне defined.

Да, кстати, по результатам истории я теперь точно знаю что
а) memcpy, memmove, bcopy в FreeBSD - просто одно и тоже (но три копии кода! Умножить на три реализации, C, i386, amd64)
б) и так и надо, блин! В смысле, не три реализации, а одно и то же.

Баян, но в чём-то схожая ситуация(а именно наличием Flash и его пользователей):
http://www.apple.com/hotnews/thoughts-on-flash/
http://www.youtube.com/watch?v=YPb9eRNyIrQ&feature=related

Вкратце - пройдя через муки выбора между пользователями довольными официальной поддержкой(даже не поддержкой, а разрешением быть) Flash'а и баблом будущем с открытыми стандартами, Apple выбрала последнее то есть бабло выкинула Flash нах. И ничего, кактусы яблоки как ели так и едят. И это при том, что помимо пользователей, есть ещё и Adobe, которая портирует photoshop и т.п. на их ось.

Что касается моего мнения по поводу обсуждаемого вопроса, то:
Я бы с радостью послал НА всех разработчиков такого софта, пусть пользователи долбят их. Почему мне не трудно глянуть в стандарт при подозрительном случае - дело пары минут, и это при том, что я не участвую в разработке проектов масштаба Flash, где такие проверки должны быть вживлены в сознание каждого индовелопера каждодневной корпоративной молитвой.
Но на практике, я бы конечно принял не волевое решение послать всех к adobe и д.р., а пошёл бы на встречу пользователям.
Правда после такого решения, придётся самому немного полечится, возможно алкоголем... то есть, решение не такое простое как чёрное-белое. точнее ответ-то практически однозначный, но сам процесс принятия решения довольно мучительный..

Я еще раз хочу заметить, что
1) дело не только в флэше.
2) изрядное количество таких неловленных ошибок - обязано еще проявиться, потому что ошибка - типичная.
3) в данном конкретном примере есть способ сделать хорошо во всех смыслах.

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

3) в данном конкретном примере есть способ сделать хорошо во всех смыслах.

В данном случае для меня "хорошо во всех смыслах", это когда и пользователи с работоспособным софтом и разработчики полагающиеся на UB (пусть и без сознательно/не специально/из-за лени) с отбитыми руками и поставленные в угол. Но так как второе, ввиду того, что всех не перебить, не осуществимо, придётся довольствоваться только первым.

Также, я за то, чтобы добавить в debug runtime версию кидание exception'а(либо halt с выводом в stderr, если это чисто C библиотека) (вроде легально, так как такое поведение вполне себе UB).

Да нет же. Хорошо - это сделать memcpy с определенным поведением. В точности как у memmove().

Ну нет уж, в стандарте написано - неопределено, значит будет неопределоно! Будем то в шахматном порядке копировать, то задом наперед, то вперед назад! Давайте уже научим этих индусов уважать спеки!

Ты посмотри ж сколько дон кихотов :)

В смысле стандарт менять?
Если не менять стандарт, а делать с определённым поведением, то это просто workaround. То есть грязная игра, но, естественно, продиктованная сильной необходимостью.. Я бы выбрал этот workaround, но это далеко не идеальное решение.

Это грязная игра не только из-за эстетских соображений, но также и потому, что это может обернуться неприятностями в будущем:
Например выходит некая православная BourbakiOS, изменения в которой "продавить" не так легко как в Linux(ну это относительно, так как мы видим что всё-таки не легко). Софт как писался криво до обнаружившей себя бомбе в memcpy, так и продолжал писаться, так как использовали этот workaround. В итоге, имеем на этой новой OS, те же грабли, причём они более "стыдные", так как при обнаружении возможности такой ошибки, пошли на уступки "террористам", и новый софт продолжал писаться с закладкой на UB..

То что предлагае Линус (и я вслед за ним, ибо я являюсь им, у меня справка есть):
1) Не нарушает писаные спеки memcpy
2) Не нарушает неписанные спеки memcpy как они есть в большинстве систем
3) Убирает грабли с пути
4) Не портит производительность т.к. memmove() как более правильный вызов все едино надо ускорять.

Это я понял, топик читал, выбрал бы тоже это решение, но скрипя сердцем (справка тоже есть).

На счёт Линуса, а предлагает ли он менять стандарт? а то без смены может быть
стыдное будущие.

Алиас memcpy на memmove не нарушает текущих писаных стандартов.

да, не нарушает, но это ведёт к тому, что больше софта будет закладываться на UB, разве не так?
А раз так, замена UB на DB только в linux'е, ведёт к тому что, на православных осях, где UB=UB, софт будет глючить ( http://blog.lexa.ru/2011/03/31/subbota_dlya_cheloveka_ili_chelovek_dlya_... ).

P.S. фигасе, не могу редактировать и отправлять сообщения(может в капче немного ошибся), злой пёсик: "Your submission has triggered the spam filter and will not be accepted" . (зашёл с другого канала, с потёртыми печеньками)

Пока мы имеем обратную ситуацию: появление истинного UB в линуксе сломало софт и, я гарантирую, сломает еще.
Удаление этого UB - починит софт. Правильное удаление (не вернуть копирование вперед, а memove) - починит много софта на много лет вперед.

согласен, это правильный workaround который уместно, и даже нужно использовать.
но это отнюдь не "хорошо во всех смыслах"

Стандарт не меняется, а уточняется. Вот такое вот уточнение:
#define memcpy(a,b,c) memmove(a,b,c)
не нарушает существующего стандарта на memcpy никоим образом. И всем становится хорошо.

А ускорение, ради которого весь сыр-бор - внести в memmove в случай копирования непересекающихся регионов

Если уж менять стандарт, то нужно всё-таки добавить функцию соответствующую сегодняшнему memcpy, то есть без проверки пересечения, и добавить к её имени суффикс _У_МЕНЯ_ПРЯМЫЕ_РУКИ . И пусть это проверка на сегодняшних машинах может и ничтожна, но можно представить ситуацию когда вносит весомый вклад (libc не только для x86). Например, будет супер память, в которой данные от одной ячейки непосредственно пойдут в другую, и само копирование будет происходить мгновенно.
Но блин, такие уступки будут ввести к засорению стандарта deprecated хлама (потом будет, _У_МЕНЯ_ТОЧНО_ПРЯМЫЕ_РУКИ, потом _У_МЕНЯ_ТОЧНО_ПРЯМЫЕ_РУКИ_И_РАСТУТ_НЕ_ИЗ_ЖОПЫ_И_Я_НЕ_ИНДУС, и т.д.).
Если не добавлять такую функцию, получится потеря изначальной гибкости(в стандарте!), из-за каких-то индусов.

По хорошему, надо просто memcpy извести под корень. И никаких "у меня прямые руки".

Add new comment