Ломать ли совместимость в недокументированной области?
От: Michael7 Россия  
Дата: 11.11.10 09:17
Оценка: 40 (9) +1
Предположим есть некий давно присутствующий на рынке программный продукт, с API, которое использует огромное число разработчиков.

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

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

И вот кто тут прав?

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

Вкратце произошло вот что.

Есть важнейшая системная библиотека glibc (ее разработчики работают в основном в RedHat), в которой содержится сишный рантайм. В ней есть функция memcpy, копирующая память и описанная в документации как:

MEMCPY(3) Linux Programmer's Manual MEMCPY(3)

NAME
memcpy — copy memory area

SYNOPSIS
#include <string.h>

void *memcpy(void *dest, const void *src, size_t n);

DESCRIPTION
The memcpy() function copies n bytes from memory area src to memory
area dest. The memory areas should not overlap. Use memmove(3) if the
memory areas do overlap.


Она копирует из одной области памяти в другую заданное число байт. Специально указывается, что источник и приемник не должны пересекаться, если пересекаются необходимо использовать вместо memcpy функцию memmove. При том такое описание было с весьма древних пор, минимум с 1993-ого года или вообще с самого начала.

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

Это привело к неправильному воспроизведению звука в плагине Adobe Flash player и к сбоям в некоторых других менее известных программах.

Разработчики glibc закрыли сообщение об ошибке по причине, что это не ошибка. Дискуссия развернулась довольно серьезная. В ней даже отметился лично Линус Торвальдс, который отнюдь не считает, что в glibc были правы, и даже ехидно спрашивает, собираются ли они выпустить дистрибутив Fedora 14 с заведомо неработоспособным флеш плеером?

В принципе, ошибка не в glibc, а в прикладных программах и для исправления достаточно банально заменить memcpy(...) на memmove(...) и заново откомпилировать программу. Для OpenSource — это особо не проблема, но в Linux-e работают и проприетарные программы, которые производители могут и не спешить исправлять. Правда Линус предложил способ решить проблему путем использования своей реализации memcpy и подкладывании своей библиотеки для конкретной программы. Но это костыль.

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