Здравствуйте, _wqwa, Вы писали: _>Самые приятные баги и трудноуловимые баги неотделимы от контекста. Так что оценить их красоту можно только разобравшись в десятках килобайт кода. Мне кажется, большинство сочтет это удовольствие сомнительным...
Вообще конечно да. В жизни хороший баг распределен как минимум по трем исходникам, достаточно далеко разнесенным по структуре проекта, и каждый в отдельности никаких подозрений не вызывает. Лучше всего, когда эти три (или более) "мест" находятся в разных уровнях: например, взаимодействие кода в SQL Stored Procedure с особенностями библиотеки доступа к данным, которая должна автоматически следить за транзакциями, и прикладным кодом, который слегка неожиданным образом к этой библиотеке обращается.
Воспроизводиться он должен только при большой нагрузке, так, чтобы на тестовом серваке его вообще никогда не бывало, а попытка оттрассировать его на рабочем серваке меняла баланс загрузки и баг исчезал.
Да, охота за таким багом — это честная борьба. Я выхожу с ним один на один! Вооруженный только банкой кофе Nescafe Classic, RAdmin, SQL Profiler, пачкой сигарет и WinAmp. На его стороне 54 сервиса на трех серверах, 80 клиентских мест и 150 веб-запросов в минуту. Я обкладываю его ловушками и навешиваю лог райтеры. Я перехожу от медитации над исходниками к пошаговой отладке и обратно. Я уже знаю, как расставить капканы, чтобы не спугнуть его. В самом начале я не знаю о нем ничего — лишь несколько следов да обрывочные свидетельства очевидцев ("я куда-то нажала, и оно сказало мне что-то не то. Вроде там было слово... слово... слово... А! Error 500!") Но постепенно моя интуиция подсказывает мне все больше и больше, флажки отсекают участки исправного кода, я уже почти отождествляю себя с ним, и — оп! Вот он, трепещет в моих руках!
Единственное, в чем я завидую обычным охотникам — это череп над камином. Увы, 6 килограммов распечаток — это не то. Рассказ об охоте быстро утомляет даже коллег, кроме того они зачастую поднимают охотника на смех (что, там был DeadLock? Во первых, в описываемой конфигурации он возникнуть в принципе не может — читайте доку, батенька. Во-вторых, его причина сразу была очевидна — NullPointerException с таким стеком, использование одной и той же таблички слева и справа от UNION и предупреждения в Application Log сразу должны были навести вас на мысль об этом! Я бы отловил его в первые 15 минут, даже не заглядывая в проектную документацию. Ну, и в третьих есть патч к тому JDBC драйверу, который исправляет ошибку с управлением уровнями изоляции).
Но, с другой стороны, написать кусок кода длиной в ~20 строк, содержащий заведомый баг, и при этом неочевидный — это тоже своего рода искусство. Упрощенные примеры можно почерпнуть в любом сертификационном экзамене по девелопменту. Боюсь, что сам я не смогу так ловко придумать хотя бы один нетривиальный пример.
... << RSDN@Home 1.0 beta 7a >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Хочу написать про один баг который учась в институте сотворила моя жена:
простейшее задание ввести А, ввести В сложить их и результат отобразить на экране, язык программированеия фортран, машина ЕС
все написала, запускает, не работает, ругается матерно. Проверяем — все правильно, запускаем, не работает. Зовем лаборанта, эффект тот-же, он в полной панике зовет преподователя, эффект тот-же, постепенно собирается вся кафедра во главе с зав.кафедрой. У всех озабоченные лица.
Потом выяснилось что буквы были русскими, только выяснилось это часов через 6.
Здравствуйте, Awaken, Вы писали:
KS>Это да... вот у нас в конторе есть один специфический тип отчета по неким данным... Спустя пару лет после его >написания, выяснилось, что неправильно был реализован математический алгоритм, считающий ряд стандартных статистик. >Но все заказчики давно привыкли к тем цифрам, и правильный вариант их категорически не устроил... Так и продаем до
A>в любой большой системе есть некоторое количество багов, иногда получается так что некоторые из них "взаимоуничтожают" друг друга и все работает правильно.
Довольно распростронённое убеждение. Но не стоит забывать, что содержание системы не равно сумме содержаний компонентов. И учитывая это замечание, можно найти несколько типичных баговых ситуаций (и пути их решения):
где n — чётное число.
Эта самая благоприятная ситуация для программиста. Особый случай ситуации — когда сумма положительных багов равна сумме отрицательных. В этом случае баги никиа не влияют на работу программы. Задача программиста в этом случае — стараться делать одинаковые по проявлению баги и следить, чтобы сумма багов была чётным числом.
где n — любое целое число.
Это тоже очень распространённая ситуация. В этом случае — задача программиста — свести хотя-бы один баг к нулю или бесконечно малому значению.
2. Проявление_багов = баг1^баг2;
Это уже более серьёзная ситуация. Есть два решения такой проблемы.
1. Попытаться свести баг1 к нулю. Задача, как правило, невыполнимая, т.к. почти всегда баг1 не поддаётся локализации.
2. Прологарифмировать Проявление_багов. В этом случае пропадает экспоненциальная зависимость от 2-го бага.
Как правило, в реальности встречаются все три ситуации в перемешку. Задача программиста — свести Проявление_багов к минимуму, использую вышеприведённые примеры.
S>Господа программисты.
S>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист. Вот примеры:
class Test
{
int x, y, char * s;
public:
Test(int a_x, int a_y, const char * a_s) { x = a_a; y = a_y; s = a_s; }
Test(const Test & t) { *this = t };
Test & operator=(const Test t) { x = t.x; y = t.y; s = strdup(t.s); return *this; }
};
int main()
{
Test t1(0, 0, "test1");
Test t2 = t1;
return 0;
}
Stack overflow
Это, кстати, еще и пример извращенности мышления...
>действительно гениальный баг — это который если пофиксить, программа перестает работать как надо. >такие нельзя ни в коем случае фиксить, а надо сохранять для последующих поколений программистов >(как "мозги компьютерные 32 метра" )
Это да... вот у нас в конторе есть один специфический тип отчета по неким данным... Спустя пару лет после его написания, выяснилось, что неправильно был реализован математический алгоритм, считающий ряд стандартных статистик. Но все заказчики давно привыкли к тем цифрам, и правильный вариант их категорически не устроил... Так и продаем до сих
А что касается моих личных багов, то, работая постоянно сейчас с С# и JavaScript, постоянно натыкаюсь на JavaScript-ошибку в следующей строке:
for( int i = 0; i < nSomeLength; i++ )
_Каждый_ раз тупо смотрю на эту строчку, обычно требуется секунд 30, чтобы сообразить в чем дело. Вот такая тормознутость.
Здравствуйте, Plague, Вы писали:
P>у меня стоит Ninja — рулез необыкновенный, настроил под VC6... P>правда бывают приколы, например: до настройки "this" переводил в "ершы", а затем в "ерши"...
Здравствуйте, Lonely Dog, Вы писали:
LD>Здравствуйте, ArtDenis, Вы писали:
LD>---покусано----
LD>Предлагаю придумать новую науку: Баговедение. Во время изучения этой науки студенты будут обучаться исскуству планирования багов, и пр.
LD>PS: народ, предлагайте новые направления этой науки...
Только не Баговедение, а БагоЛогия.
Выписка из статьи газеты "Практическая БагоЛогия":
Российская Академия Багологии дистанционно присвоила звание Профессора багологических наук Биллу Калиткину...
Здравствуйте, scaramush, Вы писали:
S>Есть вообще высший пилотаж: кусок кода длинной ~20 строк, при взляде на который понимаешь, что он явно содержит ошибки... на самом деле ошибок не содержащий. Во как!
Да ну! Мне студенты постоянно такой код сдают.
... << RSDN@Home 1.0 beta 7a >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
S>Господа программисты.
S>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист.
Жаль, что конкурс будет только среди программистов.
Вот у меня в базах багов около 500, а может даже и побольше.
И среди них есть очень специфичные, начиная от различного поведения на 9х\НТ системах, заканчивая размерами тайм-аутов при работе с факсами и почтой.
Чем сложнее и трудноуловимее баг, тем больше программеры списывают его на ошибку системы, виртуальной машины или ещё что-нибудь, но только это не их ошибка, пока явно не выловишь его
А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист. Вот примеры:
_>Самые приятные баги и трудноуловимые баги неотделимы от контекста. Так что оценить их красоту можно только >разобравшись в десятках килобайт кода. Мне кажется, большинство сочтет это удовольствие сомнительным...
действительно гениальный баг — это который если пофиксить, программа перестает работать как надо.
такие нельзя ни в коем случае фиксить, а надо сохранять для последующих поколений программистов
(как "мозги компьютерные 32 метра" )
Конечно, ключевое слово "register" не использовалось,
имя функции другое было, вроде registerValue или registerID,
за давностью лет такие детали не могу вспомнить
S>Господа программисты.
S>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист.
Твой первый пример -- очевиден, о втором судить не могу (с VCL не знаком)
Самые приятные баги и трудноуловимые баги неотделимы от контекста. Так что оценить их красоту можно только разобравшись в десятках килобайт кода. Мне кажется, большинство сочтет это удовольствие сомнительным...
_>Самые приятные баги и трудноуловимые баги неотделимы от контекста. Так что оценить их красоту можно только разобравшись в десятках килобайт кода. Мне кажется, большинство сочтет это удовольствие сомнительным...
Достаточно описать баг и как его ловили. А код — для сомневающихся.
Здравствуйте, sercher, Вы писали:
_>>Самые приятные баги и трудноуловимые баги неотделимы от контекста. Так что оценить их красоту можно только разобравшись в десятках килобайт кода. Мне кажется, большинство сочтет это удовольствие сомнительным...
S>Достаточно описать баг и как его ловили. А код — для сомневающихся.
Цитирую Синклера: S>
S>Единственное, в чем я завидую обычным охотникам — это череп над камином. Увы, 6 килограммов распечаток — это не то. Рассказ об охоте быстро утомляет даже коллег, кроме того они зачастую поднимают на охотника смех (что, там был DeadLock? Во первых, в описываемой конфигурации он возникнуть в принципе не может — читайте доку, батенька. Во-вторых, его причина сразу была очевидна — NullPointerException с таким стеком, использование одной и той же таблички слева и справа от UNION и предупреждения в Application Log сразу должны были навести вас на мысль об этом! Я бы отловил его в первые 15 минут, даже не заглядывая в проектную документацию. Ну, и в третьих есть патч к тому JDBC лрайверу, который исправляет ошибку с управлением уровнями изоляции).
... к сожалению... А то я и сам бы с три короба наплел
S>Господа программисты.
S>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист. Вот примеры:
Здравствуйте, FireWorm, Вы писали:
FW>Здравствуйте, sercher, Вы писали:
S>>Господа программисты.
S>>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист. Вот примеры:
FW>то ничего не вываливается, если ввести строку более 10 символов, она вводится корректно, а затем не менее корректно оторбражается
это называется ПОВЕЗЛО....
кстати. в новой матрице (сорри за оффтоп) говорят при взломе этой самой матрицы продемонстрировали как-бы реальный взлом какого-то Unix-сервака с использованием какой-то реальной ошибки связанной с переполнением буфера. Т.е кино конечно, но по крайней мере не большие трехмерные вирусы летающие по кислотному экрану с рамочками всех цветов радуги
Здравствуйте, IPv6, Вы писали:
IP>кстати. в новой матрице (сорри за оффтоп) говорят при взломе этой самой матрицы продемонстрировали как-бы реальный взлом какого-то Unix-сервака с использованием какой-то реальной ошибки связанной с переполнением буфера. Т.е кино конечно, но по крайней мере не большие трехмерные вирусы летающие по кислотному экрану с рамочками всех цветов радуги
Здравствуйте, Аноним, Вы писали: А> программированеия фортран, машина ЕС
ЕС это вообще крутая машина была. Знакомая девушка решила свою программу сортировки дат с ЕС-ки перенести на XT (давно это было). Благо Виртовский паскаль понимали оба компьютера. Набивает, компилирует, запускает — не работает. Сравниваем распечатки — идентичны. Идем по шагам — оказалось что для сравнения времени она, не долго думая написала
time := 3600 * hour + 60 * min + sec
Ну и кто мог подумать что на этом продвинутом загранично писюке integer в два раза короче чем у старой советской ЕСки
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, <Аноним>, Вы писали:
А>>Потом выяснилось что буквы были русскими, только выяснилось это часов через 6.
К>Поставь себе PuntoSwitcher или KeyboardNinja — будешь иметь такую же радость (если не настроишь).
у меня стоит Ninja — рулез необыкновенный, настроил под VC6...
правда бывают приколы, например: до настройки "this" переводил в "ершы", а затем в "ерши"...
Здравствуйте, Konstantin Sokolovskiy, Вы писали:
KS>А что касается моих личных багов, то, работая постоянно сейчас с С# и JavaScript, постоянно натыкаюсь на JavaScript-ошибку в следующей строке: KS>
KS>for( int i = 0; i < nSomeLength; i++ )
KS>
KS>_Каждый_ раз тупо смотрю на эту строчку, обычно требуется секунд 30, чтобы сообразить в чем дело. Вот такая тормознутость.
У меня с точностью до наоборот. Много работал на JavaScript, поэтому на Шарпе пишу
KS>Это да... вот у нас в конторе есть один специфический тип отчета по неким данным... Спустя пару лет после его >написания, выяснилось, что неправильно был реализован математический алгоритм, считающий ряд стандартных статистик. >Но все заказчики давно привыкли к тем цифрам, и правильный вариант их категорически не устроил... Так и продаем до
в любой большой системе есть некоторое количество багов, иногда получается так что некоторые из них "взаимоуничтожают" друг друга и все работает правильно.
S>Господа программисты.
S>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист. Вот примеры:
А еще очень долго можно искать вот такую простую ошибку:
S>Но, с другой стороны, написать кусок кода длиной в ~20 строк, содержащий заведомый баг, и при этом неочевидный — это тоже своего рода искусство.
Есть вообще высший пилотаж: кусок кода длинной ~20 строк, при взляде на который понимаешь, что он явно содержит ошибки... на самом деле ошибок не содержащий. Во как!
Здравствуйте, Sinclair, Вы писали:
S>Вообще конечно да. В жизни хороший баг распределен как минимум по трем исходникам, достаточно далеко разнесенным по структуре проекта, и каждый в отдельности никаких подозрений не вызывает.
Однажды на ежемесячном собрании я получил премию от компании за нахождение фатальной ошибки перезаписи памяти, которая была ошибкой "седьмого уровня", а именно, указатель, превращенный в мусор перезаписью поверх него другого валидного (но неверного) указателя, приводил к разрушению другого указателя, что приводило к неверному вычислению индекса, что приводило ... — и так разрушения до седьмого уровня, что в конце-концов вызывало фатальную ошибку доступа. Т.к. для данной системы не было возможности сгенерировать финальную версию с отладочной информацией, я провел чистых 17 часов, пошагово исполняя инструкции, отслеживая обратные связи, и последовательно сужая зону поиска. У меня было 2 терминала — на одном исполнялась отладочная, а на другом финальная версии программы. После того, как я нашел ошибку, по отладочной версии было очевидно, что происходило не так, но в неоптимизированном коде описанное выше явление скрывало истинную ошибку.
S>Господа программисты.
S>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист. Вот примеры:
Вот вы говорите, баги... А у нас в институте народ, натурально, сдает вот такое:
TSPRab = class(TFRSP)
public
function MXTheor: TReal; virtual; abstract;
function DXTheor: TReal; virtual; abstract; // теор. DX
// к-т асимметрииfunction Assym: TReal; virtual; abstract;
// к-т эксцессаfunction Excess: TReal; virtual; abstract;
procedure Model(ALength: Integer; A, B: TReal); reintroduce;
end;
{-----------}implementation
var
Y,X: TArrayX;
a, b, mu, mu3, mu4, gamma, alpha, betta, sigma: Real;
i:word; //счетчикfunction SPRab.MXTheor;
begin
MXTheor:=(a+b)/2;
end;
function SPRab.Assym;
begin
KATheor:=0;
end;
{-----------}Function SPSimp.Model;
begin
For i:=1 to N do
if Random=0 then FArrayX[i]:=a else
if (Random>0) and (Random<0.5) then FArrayX[i]:=(b-a)*sqrt(X[i]/2)+a else
if (Random>=0,5) and (Random<1) then
FArrayX[i]:=b*sqrt((1-X[i])/2)*(b-a) else
if Random=1 then FArrayX[i]:=b;
end;
{-----------}function SPVeyb.Assym;
begin
mu3=(Г(1+3/alpha)- 3*Г(1+1/alpha)* (Г(1+2/alpha)+2*Г{в кубе}(1+1/alpha))
*betta{в степени -2/alpha??}) *betta{в степени -3/alpha??};
KATheor:=mu3/DXTheor{в степени 3/2};
end;
Самый смешной баг была "ленивая" программистка. Был как то баг, в качестве параметра передавалась единичка в место нуля. Так вот эта программистка с этим не стала разбираться, а решила, что проблема эта из за отсутствия нужной функции. Она ее написала, а неправильный вызов с еденичкой выкинула. Ну и началась потом свистопляска, она этот баг пофиксила, а на его месте появился другой. Она его тоже зафиксила и так это длилось полтора месяца и пока она не написала копию той функции вызов которой она закоментировала в самом начале. Потом она ушла, а посадили меня и я неделю удалял, то что она там накОдила, что бы потом в итоге поменять 1 на 0 в уже существующей функции.
C> Test & operator=(const Test t) { x = t.x; y = t.y; s = strdup(t.s); return *this; }
C>Stack overflow
Долго хлопал глазами, потом как дошло, аж больно стало!!!
C>Это, кстати, еще и пример извращенности мышления...
Необязательно: copy-ctor и operator= могут, к примеру, вызывать функцию assign(), которая объявлена именно с такой плюшкой.
S>Господа программисты.
S>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист.
У меня на C++ самый популярный баг
Здравствуйте, ch00k, Вы писали:
C>Здравствуйте, sercher, Вы писали:
S>>Господа программисты.
S>>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист. Вот примеры:
C>
C>class Test
C>{
C> int x, y, char * s;
C>public:
C> Test(int a_x, int a_y, const char * a_s) { x = a_a; y = a_y; s = a_s; }
C> Test(const Test & t) { *this = t };
C> Test & operator=(const Test t) { x = t.x; y = t.y; s = strdup(t.s); return *this; }
C>};
C>int main()
C>{
C> Test t1(0, 0, "test1");
C> Test t2 = t1;
C> return 0;
C>}
C>
C>Stack overflow C>Это, кстати, еще и пример извращенности мышления...
Почему извращенного? Почти классический пример из книжки... Правда я только со второго раза понял что к чему , но с передачей объектов по значению в свое время намучился так что рефлекс остался... Но на собеседовании я бы наверное не сообразил .