"Если ваш единственный инструмент — молоток, то каждая проблема становится похожей на гвоздь".
Абрахам Маслоу
Так вот в нашем ремесле настала пора заменить молотки на что-то более хирургически точное.
До сих пор мы использовали в качестве "среды" разработки обычный текстовый редактор, для сборки проекта - утилиту make, а отлаживали исключительно путем запуска нашего ядра на виртуальной машине QEMU.
Но наступает момент когда объем кода и сложность алгоритма становятся такими, что этим минимальным набором уже не обойтись. Давайте настроим для нашего проекта среду разработки и отладки.
1. Настройка IDE. Мигрируем проект в Eclipse
Сред разработки для С/С++ под линуксом великое множество, однако после нескольких экспериментов мой выбор пал на Eclipse CDT. Эта среда доступна для скачивания на официальном сайте, но для пользователей Linux она обязательно найдется в репозитории вашего дистрибьютора, как например у меня в Arch Linux
$ sudo pacman -S eclipse eclipse-cdt
и всё ок, ваша IDE уже установлена. Запускаем её командой
$ eclipse
и увидим мы что-то похожее. Но совсем похожим оно станет когда мы настроим наш проект для разработки в Eclipse. Лезем в меню File > New > Project и нам предложат выбрать тип проекта
выбираем Makefile Project with Existing Code - проект на основе make-файла с существующим исходным кодом, именно это и есть у нас в данный момент.
Жмем "Next" на следующем окне нам предлагают ввести имя проекта и указать где взять его исходники, а так же выбрать инструментальные средства для его сборки. Я сделал так, как показано на нижеприведенном скриншоте
Жмем "Finish" - всё, проект готов к работе
Теперь нам доступны все вкусности, которые дает развитая среда разработки - просмотр файлов проекта, продвинутые функции редактирования и прочие маленькие радости жизни. Для сборки или очистки проекта лезем в меню Project и находим там пункты Build All и Clean. Всё будет работать сразу, так как среда произведет сборку по имеющемуся у нас Makefile.
2. Настройка интерфейса к отладчику GDB.
Что ни говори, а GNU Debugger - стандарт де-факто при разработке на линукс-платформе, и пока что вряд ли что-то способно с ним конкурировать. Но наша задача не тривиальна - мы разрабатываем ядро ОС, можно ли использовать GDB для такого проекта? Нужно!
Эмулятор QEMU, который мы использовали, поддерживает отладку с помощью GDB, для этого к команде запуска надо добавить ключи -s -S. У себя я проделывал сие многократно, ВМ останавливалась, ожидая подключения отладчика, реагировала на точки останова но... пошаговую отладку напрочь отказывалась производить. Не знаю почему.
Та же ситуация повторилась и с Bochs, хотя давным давно я использовал его для этой цели, не помогли и статьи Криса Касперски о сборке этого эмулятора для поддержки отладки в 64-битной хост-системе... Может делов 64-разрядности моей линукс-платформы, может ещё в чем, но почти потеряв надежду я обратился к VMware Workstation 9.
Этот проприетарный эмулятор, один из старейших и мощнейщих на сегодняшний день (позволяющий даже играть под ним в WoT) не сплоховал и тут.
Прежде всего конвертируем наш виртуальный HDD в формат *.vmdk, который использует VMware
$ qemu-img convert -f raw -O vmdk ~/MyOSkernel/hard_disk.img ~/MyOSkernel/hdd/hard_disk.vmdk
используем утилиту qemu-img для работы с образами HDD. При объеме нашего винта в 2 Гб конвертация займет мгновение.
Создаем виртуальную машину, в качестве типа ОС выбирает демократичны "Other" в качестве файла HDD - наш существующий образ *.vmdk, на предложение конвертировать его в новый формат VMware я ответил отказом, на всякий случай. Всё готово )
Теперь идем в каталог с виртуальной машиной, находим там файл типа *.vmx (в нашем примере, допустим MySuperOS.vmx). Он текстовый, в его конец добавляем такие строки
debugStub.listen.guest32 = "TRUE"
debugStub.listen.guest32.remote = "TRUE"
debugStub.hideBreakpoints = "TRUE"
monitor.debugOnStartGuest32 = "TRUE"
debugStub.listen.guest32.remote = "TRUE"
debugStub.hideBreakpoints = "TRUE"
monitor.debugOnStartGuest32 = "TRUE"
что открывает доступ к функции gdb-stub - интерфейс с отладчиком gdb. Кроме этого в настройках самой ВМ включаем полную отладочную информацию
Ещё необходимо включить сетевые службы, для чего в консоли выполняем
$ sudo vmware-networks --start
для запуска сетевого интерфейса с хост-системой.
Теперь запускаем виртуальную машину и видим картину
Это означает, что виртуалка ждет пока мы подключимся к ней из GDB. Запускам отладчик в консоли
$ gdb -q -tui
Ключ указан -q для того чтобы дебаггер не надоедал сообщениями о своей принадлежности к проекту GNU и не загаживал консоль ненужным текстом, а ключ -tui - для доступа к просмотру исходников в окне отладки. И попадаем мы в консоль gdb где вводим команду
(gdb) target remote localhost:8832
Эта команда конектит отладчик с виртуальной машиной, через локальный сетевой интерфейс через порт 8832, используемый vmware для удаленной отладки.
Теперь нам необходимо загрузить в отладчик таблицу символов, чтобы трассировать не дизасемблированный машинный код, а наши родные исходники на языке C.
(gdb) symbol ~/MyOSkernel/src/kernel
Да-да, грузим в отладчик собранное ядро, мы ведь собирали его с ключом -g, если помните, и символьная информация имеется в бинарном файле.
Теперь мы можем поставить точку останова
(gdb) tb main
Отладчик буднично сообщит что установил временную точку останова на функцию main в файле main.c на строку номер 13. Так, теперь вводим команду
(gdb) c
и процесс пошел! И что же мы видим? Отладчик остановился на брейкпоинте, вывалив консоль исходник main.c и приглашает нас отлаживать.
Этого уже вполне сносно хватит для работы. Данная статья - не руководство по GDB, на то есть официальные документы проекта GNU, а для первоначального знакомства с GDB хорошо прочесть эту статью. Наша цель несколько иная, а именно
3. Интергация отладчика с IDE Eclipse
Да, давайте сделаем красиво, будем отлаживать наш проект непосредственно из IDE.
Для этого в Eclipse в меню Run выбираем пункт Debug Configarations, и создаем новую конфигурацию C/C++ Remote Application, как показано на скрине
Тут необходимо кое-то настроить, прежде всего соединение с VMware. Идем на вкладку Debugger, там выбираем вкладку Connection и вбиваем параметры коннекта с отладчиком
Жмем "Apply" и лезем на вкладку Main, с тем чтобы указать путь к бинарнику ядра для загрузки символьной информации в строке C/C++ Application.
Отлично, опять применяем настройки, запускаем виртуальную машину и жмем Debug. И видим мы вот такое чудо
Отладчик подключился к ВМ и передал нам управление в IDE. Теперь можно хоть до посинения ползать по исходникам, ставить точки останова, просматривать переменные, стек вызовов, в общем делать всё то что зовется пошаговой отладкой в IDE.
Заключение
Теперь наши возможности выросли в сотни раз - мы собрали полноценную IDE на основе Eclipse, VMware и GDB и нас ничто не может остановить )
Комментариев нет:
Отправить комментарий