Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #51, ФЕВРАЛЬ 2005 г.

Особенности национальной отладки

Крис Касперски ака мыщъх

Спецвыпуск: Хакер, номер #051, стр. 051-096-1


Знакомимся с механизмами отладки в *nix

Первое знакомство в GDB (что-то вроде debug.com для MS-DOS, только мощнее) вызывает у поклонников Windows смесь разочарования с отвращением, а увесистая документация вгоняет в глубокое экзистенциональное уныние. Отовсюду торчат рычаги управления, но газа и руля нету. Не хватает только звериных шкур для дизайна и каменных топоров. Как юниксоиды выживают в агрессивной среде этого первобытного мира – загадка.

Отладка в исторической перспективе

Несколько строчек исходного кода *nix еще помнят те древние времена, когда ничего похожего на интерактивную отладку не существовало и единственным средством борьбы с ошибками был аварийный дамп памяти. Программистам приходилось месяцами (!) ползать по вороху распечаток, собирая рассыпавшийся код в стройную картину.

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

Отладочная печать сохранила свою актуальность и по сей день. В мире Windows она в основном используется в отладочных версиях программы и ликвидируется из финальной, что не есть хорошо: когда у конечных пользователей происходит сбой, в руках у них остается лишь аварийный дамп, на котором далеко не уедешь. Я согласен с тем, что отладочная печать кушает ресурсы и отнимает много времени. Вот почему в *nix так много систем управления протоколированием – от стандартного syslog, до продвинутого Enterprise Event Logging (http://evlog.sourceforge.net). Они сокращают накладные расходы на вывод и журналирование, значительно увеличивая скорость выполнения программы.

Неправильно

#ifdef __DEBUG__

fprintf(logfile, "a = %x, b = %x, c = %x\n", a, b, c);

#endif

Правильно

if (__DEBUG__)

fprintf(logfile, "a = %x, b = %x, c = %x\n", a, b, c);

Отладочная печать на 80% устраняет потребности в отладке, потому что отладчик используется в основном для определения того, как ведет себя программа в конкретном месте: выполняется ли условной переход, что возвращает функция, какие значения содержатся в переменных и т.д. Просто влепи сюда fprintf/syslog и посмотри на результат!

Человек – не слуга компьютеру! Это компьютер придуман для автоматизации человеческой деятельности (в мире Windows – наоборот!), поэтому *nix-системы на максимально возможном уровне "механизируют" поиск ошибок. Включи максимальный режим предупреждений компилятора или возьми автономные верификаторы кода (самый известный из которых – LINT), и баги побегут из программы как мыщъх'и с тонущего корабля (Windows-компиляторы также могут генерировать сообщения об ошибках, по строгости не уступающие gcc, но большинство программистов пропускает их мимо ушей. Культура программирования, блин!).

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

Содержание  Вперед на стр. 051-096-2