FreeBSD Debug — различия между версиями

Материал из OpenWiki
Перейти к: навигация, поиск
(Проверка оборудования)
(Поиск в Интернете)
Строка 84: Строка 84:
  
 
== Поиск в Интернете ==
 
== Поиск в Интернете ==
 +
 +
После получения хоть какой-то отладочной информации из вывода программы или из системных журналов нужно проанализировать её. Если причина ошибки остаётся непонятной, то надо воспользоваться поиском  в Интернете, в архивах специализированных списков рассылок и форумов. Поиск в Интернете, это вообще искусство, которым овладевают со временем, но чтобы им овладеть, нужно хотя бы пытаться найти ответ по возникшей проблеме, прежде чем просить помощи у разработчиков. Простейшее «copy/paste» сообщения об ошибке в поисковик очень часто помогает найти советы по решению проблемы и сокращает время на ожидание, когда какой-нибудь «гуру» в форуме найдёт свободную минутку для ответа на ваши вопросы. Из поисковиков, по личному опыту, всем рекомендую http://google.com, и как частные случаи – http://groups.google.com и http://google.com/bsd. Так же, неплохой сервис поиска по спискам рассылок проекта FreeBSD есть у Рамблера – http://freebsd.rambler.ru, и на официальном сайте проекта есть поисковая система, как по всему сайту в целом, так и по конференциям.
  
 
= Введение в gdb =
 
= Введение в gdb =

Версия 07:30, 30 июля 2009

Отладка проблем во FreeBSD


Введение

Эта статья была написана уже довольно давно, так что частично она уже может устареть.

Говорят, что программ без ошибок не существует. Когда же речь идёт о крупных проектах, у которых сотни разработчиков и продолжительная история развития, в этом утверждении имеется значимая доля правды. Одним из таких крупных проектов является FreeBSD. Хотя модель разработки FreeBSD и позволяет проводить аудит кода тысячами разработчиков во всём мире, некоторые ошибки остаются незамеченными и проявляются только при определённых обстоятельствах. Так же, что наиболее актуально для данной статьи, когда в проект вводится значительное количество нового кода, требуется его тщательная отладка в реальных условиях и на реальных задачах. В этой статье я попытаюсь раскрыть основы методов отладки и нахождения ошибок в программах и ядре операционной системы FreeBSD на уровне, достаточном для написания содержательного отчёта об обнаруженной проблеме. Такие отчёты являются хорошим подспорьем разработчикам для локализации и устранения проблемы.

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

Большинство приводимых в этой статье методик, утилит, имён переменных и других специфических данных ориентировано на использование в последних версиях FreeBSD, к моменту написания статьи это FreeBSD 6.2-RELEASE и 7.0-CURRENT. Но практически всё это будет работать и на более старых версиях системы. Если у вас по каким-то причинам не получается воспроизвести примеры или аналогичные статье действия, проверьте правильность параметров и имён в соответствующих руководствах пользователя.

Косвенные методы отладки

Бывает так, что программы работают некорректно или завершаются с ошибкой по причине неверной конфигурации. В этом случае конечно можно обвинить разработчиков в том, что не предусмотрели такой ситуации, но с другой стороны это ошибка администратора. Да и к тому же, программа может и не иметь прямого отношения к проекту FreeBSD. Из широко распространённых ошибок такого типа можно отметить: отсутствие файлов конфигурации, отсутствие каких-либо файлов специальных устройств (/dev/null, /dev/random и т.п.), неверные права доступа, отсутствие разделяемых библиотек, либо несоответствие их версий. Такие ошибки можно обнаружить и исправить без помощи отладчика и разработчиков. Но даже если не получается это сделать, информация, полученная при этом, будет очень полезна разработчикам.

Проверка оборудования

Файлы журналов

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

# cd /path/to/program/src
# grep –rnE "openlog|syslog" *
main.c:44:#include <syslog.h>
main.c:203:             syslog(LOG_CRIT, "cannot allocate buffer");
main.c:235:             syslog(LOG_ERR, "cannot encode message");
main.c:1425:    openlog(prefix, LOG_PID | (background ? 0 : LOG_PERROR), LOG_USER);
main.c:1480:            syslog(LOG_ERR, "atexit failed: %m");
main.c:1484:            syslog(LOG_WARNING, "cannot start UDP transport");
main.c:1486:            syslog(LOG_WARNING, "cannot start LSOCK transport");
main.c:1493:            syslog(LOG_ERR, "evCreate: %m");
main.c:1501:            syslog(LOG_ERR, "error in config file"); 

Из этого вывода видно, что программа взаимодействует с демоном syslogd с помощью сообщений, тип которых определяется как LOG_USER, а уровни – LOG_CRIT, LOG_ERR, LOG_WARNING. Эти сообщения могут сохраняться сервисом syslogd в файлы, для которых в /etc/syslog.conf определена маска, например user.*, *.crit, *.warning или user.err.

Более простой метод – включить в syslog.conf сохранение всех сообщений в один файл, либо настроить выборочное сохранение сообщений для конкретной программы. Подробнее об этом можно почитать в руководствах syslog(3) и syslog.conf(5).

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

# cd /path/to/program/src
# grep –rnE "DEBUG|DBG" *
snmp_mibII/mibII_route.c:138:#ifdef DEBUG_ROUTE
snmp_mibII/mibII_route.c:152:#ifdef DEBUG_ROUTE 
...
snmpd/config.c:359:#ifdef DEBUGGING
snmpd/config.c:365:#ifdef DEBUGGING
...
snmpd/main.c:76:      LOG_DEBUG,      /* log_pri */
snmpd/main.c:1123:    syslog(LOG_DEBUG, "Dump of SNMPd %lu\n", (u_long)getpid());

Здесь среди прочего вывода есть конструкции условной компиляции препроцессора языка Си #ifdef DEBUGGING и #ifdef DEBUG_ROUTE. Если посмотреть в код, то там будет нечто похожее:

#ifdef DEBUGGING
  fprintf(stderr, "EOF");
#endif

/* ... */

#ifdef DEBUG_ROUTE
  syslog(LOG_WARNING, "%s: DELETE: %u.%u.%u.%u "
        "%u.%u.%u.%u %u %u.%u.%u.%u not found", __func__,
        key.index[0], key.index[1], key.index[2],
        key.index[3], key.index[4], key.index[5],
        key.index[6], key.index[7], key.index[8],
        key.index[9], key.index[10], key.index[11],
        key.index[12]);
#endif

То есть, если на этапе обработки программы препроцессором языка Си определить константы DEBUGGING и DEBUG_ROUTE, то код, выводящий дополнительные сообщения будет включён в компилируемую программу, иначе он будет пропущен. Имена констант по негласному соглашению разработчиков обычно содержат в себе слова DEBUG или DBG. Так как эти соглашения являются негласными, то поиск перечисленных сочетаний может не дать результатов. Тогда можно попытаться использовать подобную команду:

# grep -rn -B2 -A2 -E "#\s*(ifdef|ifndef|if)" * | less

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

#ifndef DEBUGGING
#define DEBUGGING 1
#endif
#ifndef DEBUG_ROUTE
#define DEBUG_ROUTE 1
#endif

Только делать это нужно именно в тех файлах, где встречаются соответствующие директивы и желательно в самом начале файлов.

Более правильный, но в тоже время более сложный способ – перекомпилирование программы с заданием нужных констант в командной строке компилятора. Сложность здесь заключается в том, что программы могут конфигурироваться и компилироваться с помощью множества различных методов, для которых определение этих констант может оказаться различным. В случае если это системная программа или поставленное из портов ПО, можно переустановить его поместив строку CFLAGS+= –DDEBUGGING –DDEBUG_ROUTE в /etc/make.conf. Параметр –D<имя константы> в строке CFLAGS указывает компилятору (подразумевается gcc) на необходимость определить в заданное значение (если значение не указано, то подразумевается единица) соответствующую константу препроцессора. Сама же переменная CFLAGS содержит параметры, с которыми make(1) будет вызывать компилятор языка Си. В большинстве случаев этого должно быть достаточно. Что бы не изменять make.conf, можно попытаться указать утилите make дополнительные параметры через коммандную строку:

# make DEBUG_FLAGS="-DDEBUGGING –DDEBUG_ROUTE" install

Переменная DEBUG_FLAGS будет добавлена к CFLAGS, и, соответсвенно, компилятор будет вызван с нужными параметрами.

Для большинства программ, устанавливаемых из исходных текстов с использованием configure и gmake, аналогичных результатов можно добиться путём установки переменных окружения CFLAGS или CPPFLAGS (CXXFLAGS). Стоит так же проверить наличие дополнительных параметров с подобным функционалом у скрипта configure (при помощи ./configure --help), если конечно configure существует. Удостовериться в том, что константы установились, и программа будет верно скомпилирована, можно по выводу утилиты make. В параметрах компилятора обязательно должны присутствовать заданные константы, например:

...
==> lib
/bin/sh ..//libtool --mode=compile cc -c -O2 -fno-strict-aliasing -pipe  -DDEBUGGING -DDEBUG_ROUTE -o asn1.lo asn1.c
...

Когда программа выполняется в изолированном окружении, нужно помнить, что для работы с сервисом syslogd у неё должен быть доступ к нему. Сервис syslogd(8) может принимать сообщения от программ через UNIX сокеты и через сеть. Обычно это /var/run/log, /var/run/logpriv и 514 UDP порт. Но syslogd может быть сконфигурирован для прослушивания дополнительных сокетов (подробнее об этом можно прочитать в руководстве).

Поиск в Интернете

После получения хоть какой-то отладочной информации из вывода программы или из системных журналов нужно проанализировать её. Если причина ошибки остаётся непонятной, то надо воспользоваться поиском в Интернете, в архивах специализированных списков рассылок и форумов. Поиск в Интернете, это вообще искусство, которым овладевают со временем, но чтобы им овладеть, нужно хотя бы пытаться найти ответ по возникшей проблеме, прежде чем просить помощи у разработчиков. Простейшее «copy/paste» сообщения об ошибке в поисковик очень часто помогает найти советы по решению проблемы и сокращает время на ожидание, когда какой-нибудь «гуру» в форуме найдёт свободную минутку для ответа на ваши вопросы. Из поисковиков, по личному опыту, всем рекомендую http://google.com, и как частные случаи – http://groups.google.com и http://google.com/bsd. Так же, неплохой сервис поиска по спискам рассылок проекта FreeBSD есть у Рамблера – http://freebsd.rambler.ru, и на официальном сайте проекта есть поисковая система, как по всему сайту в целом, так и по конференциям.

Введение в gdb

Основные термины и команды, необходиме для минимальных действий (сделать бэктрейс, например) :)

Отладка системных утилит

core-файлы

Для чего, как управляются, какие особенности (suid, права доступа, sysctl и т.п.)

Что нужно для облегчения отладки

Как собрать с отладочными символами и т.п. Просмотр спец опций отладки в исходниках, /etc/malloc.conf, трассировка..

Пару слов о программах из портов

Как собирать и устанавливать, куда обращаться с вопросами

Отладка ядра

Отладочные опции

Назначение отдельных опций, как собирать, что подкрутить для сохранения дампа

элементарное введение в DDB

какие команды, call doadump, panic, tr..

загрузка и отладка через serial консоль

как и что

исследование корки ядра

Что ещё можно попробовать

на цифровик сфоткать :)

Отладка модулей ядра

asf, особенности

Как правильно делать send-pr

Что писать, куда, кому. Как отвечать на feedback'и и т.п.

Литература и благодарности