HOW-TO: Программа на Си. Часть 7 Сравнение версий

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
fullcircle:23:программа_на_си_ч7 [2010/04/15 13:49]
fullcircle:23:программа_на_си_ч7 [2010/05/02 16:48] (текущий)
Строка 16: Строка 16:
 </​style>​ </​style>​
  
 +===== =====
 В шестой части этой серии я показал вам несложные способы исследования приложений. В этой статье я представлю инструмент,​ который позволит вам копнуть глубже,​ сделать post-mortem анализ и изучить внутреннюю работу приложения. strace/​ltrace/​valgrind – действительно отличные инструменты,​ но они покажут вам только часть того, что происходит на самом деле; strace например,​ показывает только системные вызовы,​ а valgrind – что происходит с выделением/​освобождением памяти. Инструмент,​ обсуждаемый здесь, называется gdb (The GNU debugger), и для него не существует пределов – если есть что-то,​ относящееся к приложению,​ которое вы хотите исследовать,​ GDB – это то, что вам нужно. На обычной Ubuntu-системе gdb может быть установлен командой:​ В шестой части этой серии я показал вам несложные способы исследования приложений. В этой статье я представлю инструмент,​ который позволит вам копнуть глубже,​ сделать post-mortem анализ и изучить внутреннюю работу приложения. strace/​ltrace/​valgrind – действительно отличные инструменты,​ но они покажут вам только часть того, что происходит на самом деле; strace например,​ показывает только системные вызовы,​ а valgrind – что происходит с выделением/​освобождением памяти. Инструмент,​ обсуждаемый здесь, называется gdb (The GNU debugger), и для него не существует пределов – если есть что-то,​ относящееся к приложению,​ которое вы хотите исследовать,​ GDB – это то, что вам нужно. На обычной Ubuntu-системе gdb может быть установлен командой:​
 <​code>​sudo apt-get install gdb</​code>​ <​code>​sudo apt-get install gdb</​code>​
Строка 210: Строка 211:
 ПРИМЕЧАНИЕ:​ и ещё несколько ошибок 'line = 0x9e20170'​. ПРИМЕЧАНИЕ:​ и ещё несколько ошибок 'line = 0x9e20170'​.
 </​code>​ </​code>​
-Когда мы запускаем приложение + 
-с параметром '​bla',​ мы видим, что +Когда мы запускаем приложение с параметром '​bla',​ мы видим, что все значения скорости равны нулю. И мы решаем разобраться,​ в чём дело. Если что-то идет не так, мы подозреваем,​ что проблема находится в parseDevFile,​ и c помощью команды break parseDevFile указываем отладчику установить точку останова в том месте, где эта функция 
-все значения скорости равны нулю. +вызывается. Это означает,​ что приложение будет запускаться и работать как обычно,​ но будет остановлено и отобразит оболочку отладчика gdb, как только встретится точка останова. После установки точки останова мы запускаем приложение и получаем сообщение отладчика,​ когда программа достигнет точки останова. Мы решаем пошагово пройти выполнение функции,​ используя команды пошаговой отладки (это соответствует выполнению одной 
-И мы решаем разобраться,​ в чём +строчки кода). После вызова fopen() мы проверяем,​ действителен и правилен ли указатель на файл. Похоже,​ что да. Мы решаем вызвать команду display (чтобы выражение каждый раз выводилось на экран) для указателя line, который содержит нашу строку (экранный вывод немного обрезан из соображений форматирования). Но мы видим, что цикл while выполняется без вызова sscanf. Итак, мы можем сделать вывод, что устройство «bla» не существует. Когда мы вызываем cont для продолжения выполнения,​ мы видим, что в следующий раз программа,​ обнаруживая точку останова,​ возвращает нас в оболочку отладчика gdb. 
-дело. Если что-то идет не так, мы + 
-подозреваем,​ что проблема +===== Выводы ===== 
-находится в parseDevFile,​ и c + 
-помощью команды break +В этой статье я ввёл понятие C-стиль I/O и использовал getline(), а также сделал обзор gdb с высоты птичьего полёта. Из-за ограниченного места мне удалось лишь поверхностно рассмотреть gdb. Но я надеюсь,​ что этого достаточно,​ чтобы читатель понял: gdb позволяет исследовать,​ как выполняется приложение,​ как оно использует систему. Я настоятельно рекомендую всем, кто работает с приложениями на C, уделить время на изучение gdb, поскольку он окажется крайне полезным инструментом,​ когда речь зайдёт об устранении неполадок приложений. Когда дело дойдет до упражнений из этой статьи,​ исправьте приложение! Убедитесь,​ что программа выдаёт предупреждение,​ когда интерфейс не найден,​ и сделайте распознавание интерфейса более рациональным. 
-parseDevFile указываем отладчику + 
-установить точку останова в том +<note tip> **Eli De Brauwer** - фанатик Linux из Бельгии. Когда он не со своей семьёй,​ он любит играть с технологиями и проводит дни ожидая,​ когда Blizzard наконец выпустит Diablo III.</​note>​ 
-месте, где эта функция + 
-вызывается. Это означает,​ что +---- 
-приложение будет запускаться и +<style center>​ 
-работать как обычно,​ но будет +  - [[..:​17:​программа_на_си_ч1|Программа на Си. Часть 1]] 
-остановлено и отобразит оболочку +  - [[..:​18:​программа_на_си_ч2|Программа на Си. Часть 2]] 
-отладчика gdb, как только +  - [[..:​19:​программа_на_си_ч3|Программа на Си. Часть 3]] 
-встретится точка останова. После +  - [[..:​20:​программа_на_си_ч4|Программа на Си. Часть 4]] 
-установки точки останова мы +  - [[..:​21:​программа_на_си_ч5|Программа на Си. Часть 5]] 
-запускаем приложение и получаем +  - [[..:​22:​программа_на_си_ч6|Программа на Си. Часть 6]] 
-сообщение отладчика,​ когда +  - [[..:​23:​программа_на_си_ч7|Программа на Си. Часть 7]] 
-программа достигнет точки останова. +  - [[..:​24:​программа_на_си_ч8|Программа на Си. Часть 8]] 
-Мы решаем пошагово пройти + 
-выполнение функции,​ используя +---- 
-команды пошаговой отладки (это + 
-соответствует выполнению одной +//​[[..:​23|К содержанию номера]]//​ 
-строчки кода). После вызова fopen() мы + 
-проверяем,​ действителен и +//​[[:​fullcircle|К архиву журналов]]//​ 
-правилен ли указатель на файл. +</​style>​ 
-Похоже,​ что да. Мы решаем + 
-вызвать команду display (чтобы +{{tag>​howto Си Программирование Full_Circle}}
-выражение каждый раз +
-выводилось на экран) для +
-указателя line, который +
-содержит нашу строку (экранный +
-вывод немного обрезан из +
-соображений форматирования). Но мы видим, что цикл while +
-выполняется без вызова sscanf. +
-Итак, мы можем сделать вывод, что +
-устройство «bla» не существует. +
-Когда мы вызываем cont для +
-продолжения выполнения,​ мы +
-видим, что в следующий раз +
-программа,​ обнаруживая точку +
-останова,​ возвращает нас в +
-оболочку отладчика gdb.+