Она также обнаружила две реальные ошибки в следующем фрагменте кода:
/* 18 */ int s;
/* 19 */
/* 20 */ for(; i < n & s != 0; i++) {
/* 21 */ s = 0;
Средство splint определило (выделенные цветом строки предыдущего вывода), что переменная
s
используется в строке 20, но не была при этом инициализирована, и что оператор
&
стоит на месте более обычного оператора
&&.
В данном случае старшинство оператора изменяет значение условия и создает проблему в программе.
Обе эти ошибки были исправлены при чтении исходного текста программы до запуска процесса отладки. Несмотря на то, что пример мало изобретателен и служит только для демонстрации, подобные ошибки регулярно возникают в реальных программах."
Средства, отслеживающие вызовы функций
Три утилиты —
ctags
,
cxref
и
cflow
— формируют часть стандарта X/Open и, следовательно, должны включаться в системы, представляемые как системы UNIX с программными средствами разработки.
Примечание
Эти утилиты и другие, упоминаемые в этой главе, могут не входить в состав вашего дистрибутива Linux. Если они пропущены, можно поискать их реализации в Интернете. Хорошая отправная точка (для дистрибутивов Linux, поддерживающих формат RPM-пакетов) — Web-сайты http://rpmfind.net и http://rpm.pbone.net. Можно попытаться поискать в нескольких репозитариях для конкретных дистрибутивов, включая http://ftp.gwdg.de/pub/opensuse/ для openSUSE, http://rpm.livna.org для Fedora и http://packages.slackware.it/ для Slackware.
ctags
Программа
ctags
создает алфавитный указатель функций. Для каждой функции вы получаете перечень мест в программе, где она применяется, как алфавитный указатель к книге.
создает в текущем каталоге файл с именем tags, содержащий для каждой функции, объявленной в любом из входных файлов исходного кода, строки следующего вида:
announce app_ui.c /^static void announce(void) /
Каждая строка файла содержит имя функции, файл, в котором она объявлена, и регулярное выражение, которое можно использовать для поиска описания функции в файле. Некоторые редакторы, например Emacs, могут применять файлы этого вида для навигации в исходном тексте программы.
Кроме того, с помощью опции
– х
в программе
ctags
(если она доступна в вашей версии программы) вы можете формировать строки аналогичного вида в стандартном файле вывода.
find_cat 403 appui.с static cdc_entry find_cat(
Можно
перенаправить вывод в другой файл с помощью опции
– f filename
и добавить его в конец существующего файла, указав опцию
– а
.
cxref
Программа
cxref
анализирует исходный текст на языке С и формирует перекрестные ссылки. Она показывает, где в программе упоминается каждое символическое имя (переменная, директива
#define
и функция). Программа создает отсортированный список с указанием места определения каждого идентификатора, которое помечается звездочкой, как показано далее:
SYMBOL FILE FUNCTION LINE
BASENID prog.с -- *12 *96 124 126 146 156 166
BINSIZE prog.с -- *30 197 198 199. 206
BUFMAX prog.с -- *44 45 90
BUFSIZ /usr/include/stdio.h -- *4
EOF /usr/include/stdio.h -- *27
argc prog.с -- 36
prog.с main *37 61 81
argv prog.с -- 36
prog.с main *38 61
calldata prog.с -- *5
prog.с main 64 188
calls prog.с -- *19
prog.с main 54
На машине одного из авторов этой книги предыдущий вывод был сгенерирован в каталоге с исходными файлами приложения с помощью команды
$ cxref *.с *.h
но точный синтаксис зависит от версии. См. документацию к вашей системе и интерактивное справочное руководство для получения дополнительной информации о том, включена ли программа
cxref
и как ее применять.
cflow
Программа
cflow
выводит дерево вызовов функций — схему, показывающую, какие функции вызывают другие функции, какие функции вызываются этими другими и т.д. Эта схема полезна для выяснения структуры программы, понимания ее принципов действия и наблюдения за влиянием изменений, внесенных в функцию. Некоторые версии программы
cflow
могут работать с объектными файлами так же, как с исходными. Подробности см. в интерактивном справочном руководстве.
Далее приведен пример вывода, полученный версией
cflow
(cflow-2.0), которая есть в Интернете и поддерживается Марти Лейснером (Marty Leisner).