Re[11]: Ломать ли совместимость в недокументированной област
От: vdimas Россия  
Дата: 15.11.10 08:31
Оценка:
Здравствуйте, FR, Вы писали:

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

FR>Когда длина известна и небольшая обычно несколькими mov обходятся.
FR>Даже эта "одна" инструкция с REP префиксом по сути цикл.

Давай конкретней, про какие компиляторы речь. А то для MS VC всё что ты написал — неверно.
Re[3]: Ломать ли совместимость в недокументированной области
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 15.11.10 08:37
Оценка:
Здравствуйте, DOOM, Вы писали:

I>>Эдак и про Виндовс можно сказать — ошибки не в Виндовсе а в прикладных программах. Каково ?

DOO>Ну ты обычно так и говоришь

Гонишь ведь.
Re[10]: Ломать ли совместимость в недокументированной област
От: March_rabbit  
Дата: 15.11.10 10:40
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, March_rabbit, Вы писали:


M_>>Думаю, скорее всего у них юнит-тесты проверяют документированный интерфейс. Не должна функция memcpy сохранять живым кусок памяти при копировании пересекающихся блоков — не будет на это юнит-теста. Такой юнит-тест будет у функции memmove. И нельзя оправдываться инвариантами, когда речь идет о наружении контракта фукнции (в котором сказано: работаю только с непересекаюшимися блоками памяти).


Vi2>К тому же, и у memcpy, и у memmove будут одинаковые тесты.

почему? Точнее, зачем в тесты для memcpy совать тест на правильную обработку пересекающихся областей? А потом еще проверять, чтобы он сломался? Ибо он может сломаться, а может и не сломаться (ибо в контракте не оговорено, что должно произойти).
Re[8]: Ломать ли совместимость в недокументированной области
От: March_rabbit  
Дата: 15.11.10 10:43
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, March_rabbit, Вы писали:


M_>>Оно и в ассемблере выглядит почти так же (там будет что-то типа to[i] = from[i]; ++i ).


V>Нет, там будет одна инструкция ассемблера по копированию блока памяти.

ну да. примерно такой цикл она и будет выполнять, только со счетом от значения ECX до 0. Если со времен 386 процессора не появилось принципиально новых команд в основной линейке. Я со времен универа ассемблером не осень занимаюсь.
Re[12]: Ломать ли совместимость в недокументированной област
От: FR  
Дата: 15.11.10 14:51
Оценка: 8 (1)
Здравствуйте, vdimas, Вы писали:

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

FR>>Когда длина известна и небольшая обычно несколькими mov обходятся.
FR>>Даже эта "одна" инструкция с REP префиксом по сути цикл.

V>Давай конкретней, про какие компиляторы речь. А то для MS VC всё что ты написал — неверно.


Как раз для VC все справедливо, находишь memcpy.asm практически я ее выше и описал.

Вот такой код:

#include <stdio.h>
#include <memory.h>
#include <string>
#include <vector>

int main()
{
wchar_t Dst[10];

// Для фиксированной небольшой длины.
wchar_t *a0 = L"Test";
memcpy(Dst, a0, 5 * sizeof(wchar_t));
printf("%S\n", Dst);

// Неизвестная при компиляции длина
std::wstring a1 = L"TesT";
memcpy(Dst, a1.c_str(), (a1.size() + 1) * sizeof(wchar_t));
printf("%S\n", Dst);
}


для VC 2009 c /O2 дает такой выхлоп:

_main    PROC                        ; COMDAT

; 7    : {

    sub    esp, 52                    ; 00000034H
    mov    eax, DWORD PTR ___security_cookie
    xor    eax, esp
    mov    DWORD PTR __$ArrayPad$[esp+52], eax

; 8    : wchar_t Dst[10];
; 9    : 
; 10   : // Для фиксированной небольшой длины.
; 11   : wchar_t *a0 = L"Test";
; 12   : memcpy(Dst, a0, 5 * sizeof(wchar_t));

    mov    eax, DWORD PTR ??_C@_19FNGKFHMA@?$AAT?$AAe?$AAs?$AAt?$AA?$AA@
    mov    ecx, DWORD PTR ??_C@_19FNGKFHMA@?$AAT?$AAe?$AAs?$AAt?$AA?$AA@+4
    mov    dx, WORD PTR ??_C@_19FNGKFHMA@?$AAT?$AAe?$AAs?$AAt?$AA?$AA@+8
    mov    DWORD PTR _Dst$[esp+52], eax
    push    esi

; 13   : printf("%S\n", Dst);

    lea    eax, DWORD PTR _Dst$[esp+56]
    push    eax
    push    OFFSET ??_C@_03NNECAHIM@?$CFS?6?$AA@
    mov    DWORD PTR _Dst$[esp+68], ecx
    mov    WORD PTR _Dst$[esp+72], dx
    call    _printf

; 14   : 
; 15   : // Неизвестная при компиляции длина
; 16   : std::wstring a1 = L"TesT";

    xor    ecx, ecx
    add    esp, 8
    lea    eax, DWORD PTR [ecx+4]
    lea    esi, DWORD PTR _a1$[esp+56]
    mov    DWORD PTR _a1$[esp+80], 7
    mov    DWORD PTR _a1$[esp+76], 0
    mov    WORD PTR _a1$[esp+60], cx
    call    ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_WI@Z ; std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >::assign

; 17   : memcpy(Dst, a1.c_str(), (a1.size() + 1) * sizeof(wchar_t));

    mov    eax, DWORD PTR _a1$[esp+60]
    mov    esi, 8
    cmp    DWORD PTR _a1$[esp+80], esi
    jae    SHORT $LN49@main
    lea    eax, DWORD PTR _a1$[esp+60]
$LN49@main:
    mov    edx, DWORD PTR _a1$[esp+76]
    lea    ecx, DWORD PTR [edx+edx+2]
    push    ecx
    push    eax
    lea    edx, DWORD PTR _Dst$[esp+64]
    push    edx
    call    _memcpy

; 18   : printf("%S\n", Dst);

    lea    eax, DWORD PTR _Dst$[esp+68]
    push    eax
    push    OFFSET ??_C@_03NNECAHIM@?$CFS?6?$AA@
    call    _printf
    add    esp, 20                    ; 00000014H

; 19   : }

    cmp    DWORD PTR _a1$[esp+80], esi
    pop    esi
    jb    SHORT $LN78@main
    mov    ecx, DWORD PTR _a1$[esp+56]
    push    ecx
    call    ??3@YAXPAX@Z                ; operator delete
    add    esp, 4
$LN78@main:
    mov    ecx, DWORD PTR __$ArrayPad$[esp+52]
    xor    ecx, esp
    xor    eax, eax
    call    @__security_check_cookie@4
    add    esp, 52                    ; 00000034H
    ret    0
_main    ENDP


В общем все как я и говорил.
Re[5]: Ломать ли совместимость в недокументированной области
От: Игoрь Украина  
Дата: 15.11.10 22:53
Оценка:
Здравствуйте, DOOM, Вы писали:

DOO>Это самый интересный вопрос. Потому что во многих языках подобные функции вообще не являются частью библиотек, а относятся к выражениям самого языка. Здесь сработала низкоуровневость C.

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


DOO>Я приводил сравнение с протоколами. Сколько сегодня существует реализаций того же TCP — никто никогда не скажет. Если завтра потребуется наконец-то использовать какое-то зарезервированное поле TCP заголовка, то что делать? Никакой хоть сколько-то адекватный анализ провести невозможно. Для glibc это корректное сравнение — она ведь черт знает где используется, никто даже всех дистрибутивов линукса перечислить не сможет.

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

И>>б) объяснить свою мотивацию пользователям; в) о breaking changes следовало бы информировать заранее.

DOO>А может это и было сделано?
DOO>Вообще, конечно, стоило бы.
Хз, но судя по первому сообщению не похоже.
Re: Ломать ли совместимость в недокументированной области?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 16.11.10 08:26
Оценка: +5 -1
Здравствуйте, Michael7, Вы писали:

M>Предположим есть некий давно присутствующий на рынке программный продукт, с API, которое использует огромное число разработчиков.

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

Разработчики, которые использовали функцию, нарушая контракт, однозначно долбодолбы. Но исправлять ситуацию все равно придется разработчикам glibc. Как бы ни хотелось поставить дебилов на место, но суровая реальность такова, что ПО создается для конечных пользователей. И не важно по каким причинам оно перестанет работать, в мозгах отложится "Новый линукс не совместим со флешем". Заставить сонмище говнокодеров следовать спецификациям и переписать свои поделки за неделю нереально.
Re[2]: Ломать ли совместимость в недокументированной области
От: COFF  
Дата: 16.11.10 10:10
Оценка: +3
Здравствуйте, Donz, Вы писали:

D>Разработчики, которые использовали функцию, нарушая контракт, однозначно долбодолбы.


Вас можно поздравить — судя по всему Вы давно забыли о том, что такое баги и разогнали отдел тестирования? ))
На самом же деле это чистая статистика. Если есть возможность использовать что-то неправильно, и это что-то используется достаточно широко, то оно будет использовано неправильно. Даже не по злой воле неких долбодолбов, а просто потому, что человеку свойственно ошибаться.
Re: Ломать ли совместимость в недокументированной области?
От: Кодёнок  
Дата: 16.11.10 10:43
Оценка:
Здравствуйте, Michael7, Вы писали:

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


Единственный косяк со стороны glibc — отсутствие предупреждения о внесении ломающих изменений. Впрочем, они не майкрософт, у них нет целого отдела, тестирующего на совместимость — могли просто не знать. В остальном, разработчики ПО сами себе продемонстрировали свою же поговорку: “читайте доки, они рулез”
Re[2]: Ломать ли совместимость в недокументированной области
От: Кодёнок  
Дата: 16.11.10 10:45
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Единственный косяк со стороны glibc — отсутствие предупреждения о внесении ломающих изменений. Впрочем, они не майкрософт, у них нет целого отдела, тестирующего на совместимость — могли просто не знать. В остальном, разработчики ПО сами себе продемонстрировали свою же поговорку: “читайте доки, они рулез”


Хотя если подумать, еще дебажная версия memcpy могла бы проверять контракт, на всякий случай.
Re[2]: Ломать ли совместимость в недокументированной области
От: COFF  
Дата: 16.11.10 12:29
Оценка: 1 (1) +2
Здравствуйте, Кодёнок, Вы писали:

Кё>В остальном, разработчики ПО сами себе продемонстрировали свою же поговорку: “читайте доки, они рулез”


Все здесь такие непогрешимые, что я даже удивляюсь, зачем вообще такая профессия как тестер нужна? Казалось бы, проще некуда — прочитали доки и написали софт ))
Re[3]: Ломать ли совместимость в недокументированной области
От: Donz Россия http://donz-ru.livejournal.com
Дата: 16.11.10 15:54
Оценка:
Здравствуйте, COFF, Вы писали:

D>>Разработчики, которые использовали функцию, нарушая контракт, однозначно долбодолбы.

COF>Вас можно поздравить — судя по всему Вы давно забыли о том, что такое баги и разогнали отдел тестирования? ))

Не понял связи. Баги надо исправлять, а не обвинять разработчиков core API, что они вовремя не отшлепали тех, кому плевать на явное указание в документации, что таким способом функцию использовать нельзя.

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


То есть запрещаем молотки только потому, что есть некоторые люди, которые будут бить им по пальцам, а не по гвоздям?
Я так понимаю, это был намек, что разработчики glibc должны были сделать проверку правильности аргументов. А вот теперь вопрос: должны ли разработчики одной из основных функций ядра максимально ее оптимизировать, или же они должны позаботиться об особо одаренных, кто не в состоянии понять документацию, и добавить все возможные проверки (учти, что данный конфликт учитывает только один из возможных неправильных вариантов значений аргументов)?
И еще вопрос: как бы вы оценивали ситуацию, если бы разработчики Flash'а в свое время прочитали бы документацию и с новой версией glibc не было проблем? Вам не кажется, что вопроса то не было бы, а всех остальных просто отправили бы выпускать новые версии своего ПО под новую версию glibc, как это делает Микрософт со многими продуктами?
Re[4]: Ломать ли совместимость в недокументированной области
От: COFF  
Дата: 16.11.10 21:50
Оценка: +5
Здравствуйте, Donz, Вы писали:

D>То есть запрещаем молотки только потому, что есть некоторые люди, которые будут бить им по пальцам, а не по гвоздям?

D>Я так понимаю, это был намек, что разработчики glibc должны были сделать проверку правильности аргументов. А вот теперь вопрос: должны ли разработчики одной из основных функций ядра максимально ее оптимизировать, или же они должны позаботиться об особо одаренных, кто не в состоянии понять документацию, и добавить все возможные проверки (учти, что данный конфликт учитывает только один из возможных неправильных вариантов значений аргументов)?

Почему все сводится к пониманию документации? Я могу прекрасно знать, что в memcpy нельзя передавать пересекающиеся области памяти, но я могу банально пропустить ситуацию, когда две области все-таки пересекаются, хотя мне кажется совсем иначе. Найти и исправить эту ошибку практически невозможно. А так как продолжалась эта ситуация достаточно долго, то и вероятность того, что эта ошибка проявится была высокой. Кстати, именно во Flash'е она проявилась только потому, что его много кто использует, а не потому, что он плохо написан. Наверняка она есть и во многих других местах, просто пока ее не нашли. Виноваты в этом только разработчики glibc — это классическая ситуация типа "мы в ответе за тех, кого приручили". По моему, они поступили абсолютно безответственно. Почему, например, нельзя было ввести какой-то define типа FAST_MEMCPY и вызывать старую или новую функцию в зависимости от него? Кому надо, тот его поставит, а старый код работал бы без изменений.
Re: Еще раз подтверждает, что линупсоиды - воинственные дроч
От: пыщьх http://rsdn_user.livejournal.com
Дата: 16.11.10 21:57
Оценка: 2 (1) +10
Типичный догматичный за@б линупсоидов — поставить раком собственных юзеров из-за того, что индокодеры священные маны не читали.
Что бы сделал пыщьх? Элементарно:
1. На уровне молока матери билд-системы разделение на DEBUG и RELEASE билды, вместо самописных велосипедов в половине make-файлов.
2. За год до изменения модифицируем debug-версию memcpy(), чтобы там вылетал ASSERT() в случае пересекаюшихся буферов.
3. Даем девелоперам год на фикс. Пишем об этом явно и везде.
4. Спустя год, меняем release-реализацию.

Но, почему-то, в сообществе красноглазиков думать о юзабилити не принято. Так что, слушайте, Василий Иванович, ваши валенки...
Запретное обсуждение модерирования RSDN:
http://rsdn-user.livejournal.com/652.html
Re[5]: Ломать ли совместимость в недокументированной области
От: Donz Россия http://donz-ru.livejournal.com
Дата: 17.11.10 09:32
Оценка: :)
Здравствуйте, COFF, Вы писали:

COF>Почему все сводится к пониманию документации? Я могу прекрасно знать, что в memcpy нельзя передавать пересекающиеся области памяти, но я могу банально пропустить ситуацию, когда две области все-таки пересекаются, хотя мне кажется совсем иначе.


Давно не писал на ся, так что малость не в курсе современных методик разработки. Но судя по форумам и применяя здравый смысл, могу предположить, что как минимум можно сделать свою обертку над memcpy, где и проводить свою проверку непересечения областей. Эту обертку можно обложить юнит-тестами.
Насколько я знаю, немало сишных проектов, где присутствует свой менеджер памяти как раз для того, чтобы не огрести проблем. Разработчики из Адоба этим не озаботились.
Так что, извините за грубость, им можно сказать только одно: "Не можешь срать — не мучай жопу". В смысле, если не в состоянии грамотно писать на си и уследить за памятью, то переквалифицируйся на сишарп или яву, там таких проблем с не будет (хотя могут быть другие, и если избегать нормального процесса тестирования, они будут).

COF>Кстати, именно во Flash'е она проявилась только потому, что его много кто использует, а не потому, что он плохо написан. Наверняка она есть и во многих других местах, просто

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

Это называется перекладывание ответственности. "Меня не научили", "мне не сказали", "я про это не читал". Как уже писал выше, конечные разработчики ПО вполне могли создать свои обертки над системными вызовами, где и проводить все проверки.

COF>Почему, например, нельзя было ввести какой-то define типа FAST_MEMCPY и вызывать старую или новую функцию в зависимости от него? Кому надо, тот его поставит, а старый код работал бы без изменений.


Подозреваю, так и сделают.
Re[6]: Ломать ли совместимость в недокументированной области
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 17.11.10 09:37
Оценка: +1
Здравствуйте, Donz, Вы писали:


COF>>Кстати, именно во Flash'е она проявилась только потому, что его много кто использует, а не потому, что он плохо написан. Наверняка она есть и во многих других местах, просто пока ее не нашли. Виноваты в этом только разработчики glibc — это классическая ситуация типа "мы в ответе за тех, кого приручили". По моему, они поступили абсолютно безответственно.


D>Это называется перекладывание ответственности. "Меня не научили", "мне не сказали", "я про это не читал". Как уже писал выше, конечные разработчики ПО вполне могли создать свои обертки над системными вызовами, где и проводить все проверки.


Не понял. По вашему, надо каждый системный вызов обертывать и параноидально проверять на возможность некорректного использования?
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[7]: Ломать ли совместимость в недокументированной области
От: Donz Россия http://donz-ru.livejournal.com
Дата: 17.11.10 10:22
Оценка:
Здравствуйте, Sshur, Вы писали:

D>>Это называется перекладывание ответственности. "Меня не научили", "мне не сказали", "я про это не читал". Как уже писал выше, конечные разработчики ПО вполне могли создать свои обертки над системными вызовами, где и проводить все проверки.


S>Не понял. По вашему, надо каждый системный вызов обертывать и параноидально проверять на возможность некорректного использования?


Нет, я описал возможное решение проблемы, когда разработчики не могут уследить за использованием памяти. А вы предлагаете в каждом системном вызове делать всевозможные проверки, предполагая что разработчик, который их использует, не в состоянии отследить некорректные значения сам?
Re[5]: Документацию читают только ламеры
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 17.11.10 11:29
Оценка: -1
Здравствуйте, Pzz, Вы писали:

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

Гуманнее надо быть к людям и прощать их ошибки. Тем более, когда это ничего не стоит.
Re[8]: Ломать ли совместимость в недокументированной области
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 17.11.10 11:34
Оценка:
Здравствуйте, Donz, Вы писали:

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


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

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[7]: Ломать ли совместимость в недокументированной области
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 17.11.10 11:46
Оценка:
Здравствуйте, Sshur, Вы писали:

S>Не понял. По вашему, надо каждый системный вызов обертывать и параноидально проверять на возможность некорректного использования?


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