Нейл Мэтью - Основы программирования в Linux
[email protected]:~/BLP4e/chapter10> splint -strict debug0.c
Splint 3.1.1 --- 19 Mar 2005
debug0.c:7:18: Read-only string literal storage used as initial value for
unqualified storage: array[0].data = "bill"
A read-only string literal is assigned to a non-observer reference. (Use -readonlytrans to inhibit warning)
debug0.c:8:18: Read-only string literal storage used as initial value for
unqualified storage: array[1].data = "neil"
debug0.c:9:18: Read-only string literal storage used as initial value for
unqualified storage: array[2].data = "john"
debug0.с:10:18: Read-only string literal storage used as initial value for
unqualified storage: array[3].data = "rick"
debug0.c:11:18: Read-only string literal storage used as initial value for
unqualified storage: array[4].data = "alex"
debug0.с:14:22: Old style function declaration
Function definition is in old style syntax. Standard prototype syntax is
preferred. (Use -oldstyle to inhibit warning)
debug0.с: (in function sort)
debug0.c:20:31: Variable s used before definition
An rvalue is used that may not be initialized to a value on some execution
path. (Use -usedef to inhibit warning)
debug0.с:20:23: Left operand of & is not unsigned value (boolean):
i < n & s != 0
An operand to a bitwise operator is not an unsigned values. This may have
unexpected results depending on the signed representations. (Use
-bitwisesigned to inhibit warning).
debug0.c:20:23: Test expression for for not boolean, type unsigned int:
i < n & s != 0
Test expression type is not boolean or int. (Use -predboolint to inhibit
warning);
debug0.с:25:41: Undocumented modification of a[]: a[j] = a[j + 1]
An externally-visible object is modified by a function with no /*@ [email protected]*/
comment. The /*@modifies ... @*/ control comment can be used to give a
modifies list for an unspecified function. (Use -modnomods to inhibit
warning)
debug0.c:26:41: Undocumented modification of a[]: a[j + 1] = t
debug0.c:20:23: Operands of & are non-integer (boolean) (in post loop test):
i < n & s != 0
A primitive operation does not type check strictly. (Use -strictops to
inhibit warning)
debug0.с:32:14: Path with no return in function declared to return int
There is a path through a function declared to return a value on which there
is no return statement. This means the execution may fall through without
returning a meaningful result to the caller. (Use -noret to inhibit
warning)
debug0.с:34:13: Function main declared without parameter list
A function declaration does not have a parameter list. (Use -noparams
to inhibit warning)
debug0.с: (in function main)
debug0.с:36:22: Undocumented use of global array
A checked global variable is used in the function, but not listed in its
globals clause. By default, only globals specified in .lcl files are
checked.
To check all globals, use +allglobals. To check globals selectively use
/*@ [email protected]*/ in the global declaration. (Use -globs to inhibit warning)
debug0.с:36:17: Undetected modification possible from call to unconstrained
function sort: sort
An unconstrained function is called in a function body where
modifications are checked. Since the unconstrained function may modify
anything, there may be undetected modifications in the checked function.
(Use -modunconnomods to inhibit warning)
debug0.c:36:17: Return value (type int) ignored: sort(array, 5)
Result returned by function call is not used. If this is intended, can
cast result to (void) to eliminate message. (Use -retvalint to inhibit
warning)
debug0.c:37:14: Path with no return in function declared to return int
debug0.c:6:18: Variable exported but not used outside debug0: array
A declaration is exported, but not used outside this module. Declaration
can use static qualifier. (Use -exportlocal to inhibit warning)
debug0.c:14:13: Function exported but not used outside debug0: sort
debug0.c:15:17: Definition of sort
debug0.c:6:18: Variable array exported but not declared in header file
A variable declaration is exported, but does not appear in a header
file. (Used with exportheader.) (Use -exportheadervar to inhibit warning)
debug0.c:14:13: Function sort exported but not declared in header file
A declaration is exported, but does not appear in a header file. (Use
-exportheader to inhibit warning)
debug0.c:15:17: Definition of sort
Finished checking - 22 code warnings
$
Утилита выражает неудовольствие по поводу объявления функций в старом стиле (не ANSI) и несоответствия типов значений, возвращаемых функциями, и самими величинами, которые они возвращают (или нет) в действительности. Эти предупреждения не влияют на работу программы, но должны быть выведены.
Она также обнаружила две реальные ошибки в следующем фрагменте кода:
/* 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 создает алфавитный указатель функций. Для каждой функции вы получаете перечень мест в программе, где она применяется, как алфавитный указатель к книге.
ctags [-a] [-f filename] sourcefile sourcefile ...
ctags -x sourcefile sourcefile ...
По умолчанию 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 могут работать с объектными файлами так же, как с исходными. Подробности см. в интерактивном справочном руководстве.