Отладка Программ На C Для Начинающих

.

или что делать, если «Привет, мир!» упал.

Все нижеследующее в основном написано для ОС Linux и консольной отладки, хотя кое-что из этого можно использовать и в других условиях.

Это может показаться странным, но начинать написание программы следует с установки системы контроля версий (если она еще не установлена) и создания репозитория.

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

Сегодня наиболее популярными являются svn (subversion), git и mercurial. Последний мне лично нравится больше остальных, поскольку субъективно он проще и удобнее, особенно для личного использования.

Далее вам необходимо убедиться, что доступны команды gdb (отладчик) и strace (монитор системных вызовов).

Если их нет, установите их.

И при компиляции программы не забудьте включить добавление отладочной информации.

Итак, случилось – она упала.

Один из главных моментов, которому меня научили, — внимательно читать то, что пишет система/программа.

Вы можете многому научиться, используя команды:

  • dmesg (информация о ядре), lspci (устройства на шине PCI), lsmod (список загруженных драйверов) — при работе с драйверами;
  • Tail /var/log/messages — показывает десяток строк в конце системного журнала;
  • ps ax — список запущенных процессов (могут быть другие ключи);
Допустим, ничего нужного там не нашлось.

Затем вам следует запустить команду «ulimit -c 50000», ulimit (встроенная команда оболочки, которая устанавливает/показывает ограничения на использование ресурсов оболочки.

Подробное описание можно прочитать с помощью man или здесь ), 50000 - взято у гады, это размер файла ядра, который в большинстве случаев будет создан после краша программы, работающей в той же консоли, и представляет собой дамп памяти крахнувшейся программы.

Далее запускаем программу еще раз, в консоли где был ulimit. Он снова падает, но с образованием корочки (обычно).

Как вариант, все это можно сделать заранее, ведь если ошибка плавает, то второй раз может выпасть не скоро; иногда люди ждали месяцами.

С помощью отладчика нужно попробовать рассмотреть тепленькую корочку:

  • БДБ ядро.

    NNNN

gdb предоставляет интерактивный консольный интерфейс, в котором можно делать много всего, но я не буду здесь описывать все — он доступен в мане и в Интернете на куче языков.

Пока достаточно будет запустить там команду «bt» (из backtrace), которая покажет стек вызовов и, если не было маппинга памяти (мы его рассмотрим ниже), вы сможете увидеть, где он сломался .

А с помощью команды «кадр N», где N — номер вызова (слева), можно посмотреть подробнее.

«Печать Команда ” поможет вам увидеть (не всегда) значение переменной.

Если ваш «Привет, мир!» многопоточный, то тут все сложнее, но можно попробовать с помощью команды отладчика «thread N» перейти в стек N-го потока, хотя, как правило, это мало помогает. Если отладчик только рисует кучу вопросов в стеке вызовов, то это явная запись в память и он (отладчик) вам не поможет. В большинстве таких случаев вам необходимо открыть текст программы и особое внимание обратите на функции memcpy, memset, sprintf и другие подобного типа, работающие с блоками данных, которые могут выходить за пределы массива и писать поверх всего, что идет дальше в памяти.

Скорее всего где-то там ошибка.

Как минимум, стоит заменить их на более безопасные аналоги (при их наличии), например, snprintf. Если и это не помогает, то в бой идут старые, проверенные временем методы:

  • комментирование всего и раскомментирование небольшими частями с последующей компиляцией и проверкой на ошибки;
  • вставка отладочной отпечатки (часто чуть ли не после каждой строчки подозрительного участка кода (memset! memcpy!)) с дальнейшим анализом — после чего пломба сломалась.

Это помогает как для однопоточных, так и для многопоточных программ (как обычно, могут быть танцы с бубном).

Что делать, если программа зашла в бесконечный цикл и система впала в ступор (такое бывает)? Выгружаем оконный менеджер и запускаем его в текстовом режиме на одной из консолей под суперпользователем (root).

Для полной уверенности можно немного повысить ее приоритет с помощью nice/renice и запустить программу на другой консоли/терминале под обычным пользователем.

Потом при зацикливании его можно удалить в консоли суперпользователя (команда «kill») и все равно посмотреть, что он пишет. Что делать, если ничего не помогает? Ответ только один — сядьте и внимательно, очень внимательно изучите код и подумайте.

Если ошибок в программе нет (не видно на 1001 взгляд и анализ), то возможно на разделах закончилось место? (правдивая история) В конце добавлю, что если вы решите переместить кору в другое место, чтобы разобраться там (например, домой), то перенесите ее вместе с теми исходниками и скомпилированной программой как есть, или вывод gdb будет неправильным или вывод вообще не будет выполнен.

P.S. В исходных кодах ядра Linux каталог Documentation содержит файл CodingStyle. Начинающему программисту на языке C необходимо учитывать множество факторов.

П.

П.

С.

Если бы я знал все это с самого начала, мне было бы гораздо легче.

Теги: #программирование #C++ #linux #программирование #C++

Вместе с данным постом часто просматривают: