Основы программирования в Linux
calldata prog.с -- *5prog.с main 64 188calls prog.с -- *19prog.с main 54На машине одного из авторов этой книги предыдущий вывод был сгенерирован в каталоге с исходными файлами приложения с помощью команды
$ <b>cxref *.с *.h</b>но точный синтаксис зависит от версии. См. документацию к вашей системе и интерактивное справочное руководство для получения дополнительной информации о том, включена ли программа
и как ее применять.cxrefcflowПрограмма
выводит дерево вызовов функций — схему, показывающую, какие функции вызывают другие функции, какие функции вызываются этими другими и т.д. Эта схема полезна для выяснения структуры программы, понимания ее принципов действия и наблюдения за влиянием изменений, внесенных в функцию. Некоторые версии программыcflowмогут работать с объектными файлами так же, как с исходными. Подробности см. в интерактивном справочном руководстве.cflowДалее приведен пример вывода, полученный версией
(cflow-2.0), которая есть в Интернете и поддерживается Марти Лейснером (Marty Leisner).cflow0 file_ungetc {prcc.c 997}1 main {prcc.c 70}2 getopt {}3 show_all_lists {prcc.c 1070}4 display_list {prcc.c 1056}5 printf {}6 exit {}7 exit {}9 usage {prcc.c 59}10 fprintf {}11 exit {}Пример информирует о том, что функция
вызывает (среди прочих) функциюmainи чтоshow_all_listsв свою очередь вызывает функциюshow_all_lists, которая вызывает функциюdisplay_list.printfУ этой версии
есть опцияcflow, которая формирует инвертированный потоковый граф. Утилита-iперечисляет для каждой функции другие функции, вызывающие данную. Звучит не очень понятно, но на самом деле все просто. Далее приведен пример:cflow19 display_list {prcc.c 1056}20 show_all_lists {prcc.c 1070}21 exit {}22 main {prcc.c 70}23 show_all_lists {prcc.c 1070}24 usage {prcc.c 59}25 ...74 printf {}75 display_list {prcc.c 1056}76 maketag {prcc.c 4 87}77 show_all_lists {prcc.c 1070}78 main {prcc.c 70}79 ...99 usage {prcc.c 59}100 main {prcc.c 70}В примере показано, что функцию
, например, вызывают функцииexit,mainиshow_all_lists.usageВыполнение профилирования с помощью prof/gprof
Методика, зачастую полезная при попытках выяснить проблемы снижения производительности программы, называется профилированием выполнения (execution profiling). Профиль программы, обычно поддерживаемый специальными опциями компилятора и вспомогательными программами, показывает, где программа тратит время.
Программа
(и ее эквивалент в проекте GNU,prof) выводит отчёт из файла трассировки выполнения, который формируется во время выполнения профилируемой программы. Профилируемый исполняемый файл создается с помощью флага компилятораgprof(для-p) или флагаprof(для-pg).gprof$ <b>cc -pg -о program program.с</b>Программа компонуется со специальной библиотекой С, и в нее включается контрольный код. В конкретных системах он может отличаться, но общая цель — такая организация программы, которая позволяет часто прерывать выполнение и записывать этап выполнения. Контрольные данные записываются в файл mon.out (gmon.out для
) в текущем каталоге.gprof$ <b>./program</b>$ <b>ls -ls</b>2 -rw-r--r-- 1 neil users 1294 Feb 4 11:48 gmon.outПрограмма prof/gprof читает эти контрольные данные и выводит отчет. См. подробности, касающиеся опций программы, в интерактивном справочном руководстве. Далее в качестве примера приведен вывод (сокращенный) программы gprof.
cumulative self self totaltime seconds seconds calls ms/call ms/call name18.5 0.10 0.10 8664 0.01 0.03 doscan [4]18.5 0.20 0.10 mcount (60)14.8 0.28 0.08 43320 0.00 0.00 _number [5]9.3 0.33 0.05 8664 0.01 0.01 _format_arg [6]7.4 0.37 0.04 112632 0.00 0.00 _ungetc [8]7.4 0.41 0.04 8757 0.00 0.00 _memccpy [9]7.4 0.45 0.04 1 40.00 390.02 _main [2]3.7 0.47 0.02 53 0.38 0.38 _read [12]3.7 0.49 0.02 w4str [10]1.9 0.50 0.01 26034 0.00 0.00 _strlen [16]1.9 0.51 0.01 8664 0.00 0.00 strncmp [17]Проверки соблюдения условий
Несмотря на то, что вставка на этапе разработки программы с помощью условной компиляции отладочного кода, такого как вызовы
, распространена, иногда оставлять такие сообщения в поставляемой программе непрактично. Но часто проблемы возникают во время работы программы из-за некорректных допущений или исходных данных, а не из-за ошибок кодирования. Это события, которых "не может быть никогда". Например, функция может быть написана в расчете на то, что ее входные параметры будут в определенном диапазоне. Если передать ей некорректные данные, она может сделать некорректной работу всей системы.printf