bash.im ithappens.me zadolba.li

Программизмы

1421

Удаляй и распределяй

Я — программист. Пишу на «плюсах», фортране и питоне. Веб-программирование недолюбливаю, а флэш терпеть не мог никогда.

Как-то раз позвонила (!) мне приятельница, отличный веб-дизайнер из Москвы. Есть, говорит, проект, платят много. Срок — двое суток, Платформа — флэш. Подумал я и придавил своё самолюбие — раз столько платят, можно и взяться.

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

Так и сидели мы 36 часов подряд за компьютерами: я в Самаре, подругав Москве. Связь держали через джаббер. У меня открыты текстовый редактор и руководство по ActionScript в PDF; у неё — родная среда разработки (тогда еще, кажется, от Macromedia). Я вслепую писал код, опираясь только на описание языка, и отправлял его дизайнеру. Она вставляла код, привязывала его к фреймам и объектам, компилировала, сообщала мне ошибки компиляции, а полученный SWF выкладывала на сайт, где и я мог посмотреть результаты нашей совместной работы.

Проект мы сдали в срок. Такие вот чудеса удаленной компиляции и распределённой отладки.

1383

Счастливой отладки!

Однажды мне довелось «подхватывать» проект на C++, оставшийся от одного программиста, уволенного несправедливо (по его личному мнению). Впрочем, проект был почти завершён, и мне оставалось лишь немного дописать интерфейс, провести тестирование, отладку и сдать всё заказчику.

Как обычно, сроки поджимают, а я всё никак не могу разделаться с «ловлей блох»: приложение то работает нормально, то вдруг начинает глючить и вылетать на ровном месте. Как выяснилось, периодически возникало std::exception, но отследить, откуда оно бралось, у меня никак не получалось: казалось, что таинственная ошибка присутствует буквально всюду, при этом появляясь далеко не при каждом запуске.

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

Дома первым делом в надежде на чудо запускаю экзешник — вылетает, сволочь. Ладно, запускаю полную компиляцию и иду чистить картошку. Возвращаюсь — ошибка!

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

#include <cfdc.h>

Гугление результата не даёт; просто комментирую эту строку и компилирую заново — успешно! Запускаю — программа работает как часы.

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

#ifndef CFDC_H
#define CFDC_H

#include <cstdlib>
#include <exceptio.h>

#define return if (std::random(1000) < 2) throw std::exception(); else return

//Счастливой отладки!

#endif


Надо ли говорить, что наш проект использовал в одном незначительном месте стандартный генератор случайных чисел, а вызываемый при инициализации std::randomize() успешно заметал любые следы?..

1381

Потоковый эксплойт

Обучаясь на первом курсе, попал я на зачёте по программированию к преподавателю нестрогому, но весьма вольно понимающему задания из листка «к зачёту». В итоге моя программа была забракована, хотя и работала правильно, и соответствовала заданию. После этого мне было выдано новое задание: написать прогу, складывающую две вводимые строки в одну без использования кошерных функций.

Маленький экскурс в компьютерную систему здания: все студенты работают на тонких клиентах, подключенных к могучему серверу с неадекватным поведением. Одной из черт его характера было то, что потоковый ввод надо закрывать дважды. Тёмные увлечения, а также нежелание сидеть на зачёте лишнее время не позволили пропустить такой шанс воспользоваться глобальной уязвимостью. Мной был написан код:

cin >> SumString;
cout << "Сумма строк: " << SumString;

На экране же это выглядело так:

> Это полов <Enter>
> ина строки <Enter>
> Сумма строк: Это половина строки
> Press any key to continue...

Пока препод в ведомости не расписался, нажимать на Any Key я не давал.

1378

А по вечерам хешируемся

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

— Что это с вами? — спрашивает препод.
— Связный взвешенный граф! Мы вершины, он — ребро, а это (взмах руками) — петли!
— Ага, я ребро весом 55, — соглашается одногруппник. Препод смеётся.
— А недавно мы были массивом и хотели покьюсортиться, но тренер нам не разрешил, — заявляет одна из вершин.

1319

Мёртвая говядина

Отлаживали как-то код (написанный не нами) на многопроцессной системе. «Плавающих» глюков было много, большинство проблем оказывалось в одном и том же процессе. Весь отдел курил листинги сутками, впрочем, мало результативно.

Какой-то добрый человек обратил внимание на дизассемблированный код процесса. В шестнадцатиричном виде проблемный сегмент записывался как «DEAD».

1305

Шестиразрядное сиденье

Часто «забавности» возникают на стыке IT-культуры и быта. В институте преподавали нам предмет «Вычислительные машины, системы и сети». Пары делились на лекции и лабораторные, вели их разные преподаватели, при этом планы занятий не были согласованы. В результате на лекциях читали одно, а на лабораторных требовали совершенно другое. На одной лабе заставили написать программу сложения двух чисел на эмуляторе микроассемблера. Имелся небольшой набор простейших микрокоманд, выполняемых процессором, и из них нужно собрать некую последовательность. При этом в программе необходимо было учитывать различные вариации исходных чисел — вроде бы задача несложная, но требует глубокого и осмысленного погружения в бинарное восьмиразрядное море.

Возвращаясь домой с одной такой пары, я, естественно, думал о прелестях двоичных чисел. Спускаюсь в метро, захожу в полупустой вагон, сажусь. Напротив меня ряд из шести сидений; на некоторых местах люди сидят, на некоторых — нет. В голове это осмыслилось как «100101». В вагон заходит еще один «бит» и уверенно встает слева от сидений, рядом с дверью.
Щ-щёлк! В голове моей что-то отчётливо хрустнуло: «Переполнение!»

1268

Суровая ASCII-правда

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

Так вот, после очередного запуска программы я лезу проверять результат, нахожу в памяти нужную переменную и обнаруживаю, что записано в ней не что-нибудь, а «xy☺». И правда — результат был действительно неверным.

1260

...а в военное время достигает четырёх

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

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

long double a1, a2;
a1 = PI / 2 + alp;
a2 = PI / 2 - alp;

После выполнения оказывается, что и a1, и a2 меньше, чем 1,57. Долго думали. Ещё думали. В итоге посмотрели в начало кода:
const int PI = 3.1415926535897932384626433832795;

Вот уж действительно: «Для простоты вычислений примем Пи равным трём»...

1241

d-_-b

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

Никогда не забуду выражение лица товарища, обнаружившего причину мучений. Оказалось, что я, в первый раз правя код, вместо переменной b в одном из операторов влепил d. С тех пор я стараюсь называть переменные осмысленно, а однобуквенных имён и вовсе избегать.