LINUX.ORG.RU

Отладка модуля ядра Linux


0

0

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

Последнее вроде плучилось - gdb похоже подключился к системе. А вот с ядром не понятно что делать.

До этого я писал только драйвера под винду, так что примерно представляю процесс дебага - надо в начало модуля добавить int 3, чтобы всплыл отладчик, когда модуль начнет грузиться, а там уже бряки и все дела. Будет ли работать такая стратегия с gdb?

Если тебе не нужна отладка соляры :) или тормозной эклипс - загляни в документацию идущую с ядром (DocBook) на предмет kgdb. Лучше наверно все же использовать две машины. Вместе с gdb интересней наверно будет Insight из снапшота. kgdb сейчас есть прямо в исходниках ядра - не надо его патчить. Да - можно цеплять через последовательный порт (можно без аппаратного контроля - достаточно TX,RX) или через изернет.

imhotep
()
Ответ на: комментарий от mv

>Use systemtap.

Умеет он breakpoint устанавливать, чтобы можно было состояние регистров посмотреть или изменение памяти отловить ? Или для этого надо еще изучить его скриптовый язык ?

>kgdb работает очень нестабильно.


в чем измерялась эта очень нестабильность ?

imhotep
()
Ответ на: комментарий от imhotep

> Умеет он breakpoint устанавливать, чтобы можно было состояние регистров посмотреть или изменение памяти отловить ? Или для этого надо еще изучить его скриптовый язык ?

Кошмар! И даже после изучения талмуда всё равно самому всю работу делать надо будет! :)

> в чем измерялась эта очень нестабильность ?

С некоторого момента вдруг переставало работать. Кроме того, kgdb очень сильно влияет на производительность системы в отрицательную сторону, так что круг применения весьма сужается.

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

mv ★★★★★
()
Ответ на: комментарий от mv

>Кроме того, kgdb очень сильно влияет на производительность системы в отрицательную сторону, так что круг применения весьма сужается.

Улыбнуло - для вас важна скорость при отладке модулей ядра ? Причем до такой степени что круг весьма сужается :)

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


Сам не понимаю - как умудряются некотрые на той же целевой платформе как у меня ловить такие глюки что кто-то затирает данные. Причем у меня все работает на ура. А вообще такая самоуверенность что "я пишу отличный код" меня лично всегда настораживает.

imhotep
()
Ответ на: комментарий от imhotep

> Улыбнуло - для вас важна скорость при отладке модулей ядра ? Причем до такой степени что круг весьма сужается :)

Вы говорите о разных сценариях применения отладчика.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Лично я говорю как мне показалось о том что спрашивал топикстартер

>надо в начало модуля добавить int 3, чтобы всплыл отладчик, когда модуль начнет грузиться, а там уже бряки и все дела. Будет ли работать такая стратегия с gdb?

imhotep
()
Ответ на: комментарий от imhotep

Спасибо за ответы! Буду изучать дальше. Многое из предложенного уже читал, хотя пока что все-таки нет мыслей, как все это запустить. Как-то уж слишком много разных отладчиков, не понятно, какой мне подойдет. Пошел читать man.

codergeneration
() автор топика
Ответ на: комментарий от imhotep

> Улыбнуло - для вас важна скорость при отладке модулей ядра ? Причем до такой степени что круг весьма сужается :)

Для меня вообще неважно наличие дебаггера при отладке модуля ядра. Но, допустим, при тормозах поймать какой-нибудь DMA-таймаут или bufer underrun на железке - нефиг делать.

mv ★★★★★
()
Ответ на: комментарий от mv

>Для меня вообще неважно наличие дебаггера при отладке модуля ядра.

Да я верю - таких много.

>при тормозах поймать какой-нибудь DMA-таймаут или bufer underrun на железке - нефиг делать.


А это так важно ставить breakpoint там где устройство ожидает ввод-вывод ?

imhotep
()
Ответ на: комментарий от imhotep

> А это так важно ставить breakpoint там где устройство ожидает ввод-вывод ?

kgdb и без брейкпойнтов тормозит.

mv ★★★★★
()
Ответ на: комментарий от mv

Пытаюсь настроить отладку по статье http://issaris.blogspot.com/2007/12/download-linux-kernel-sourcecode-from.html . Дошел до пункта "And enable the following options: In the "Kernel hacking" menu enable both "Compile the kernel with debug info" and "Compile the kernel with frame pointers" Но в редакторе конфига уже отмечены эти пункты! Значит ли это то, что мое ядро уже собрано с отладочными символами и надо пропустить в статье что-то? Причем тут отмечен пункт про KGDB.

codergeneration
() автор топика
Ответ на: комментарий от codergeneration

Да. Только при сборке дистрибутивного пакета отладочной информации делается strip, чтобы пакет под полгигабайта не весил. В Федоре, например, нужно kernel-debuginfo установить и использовать vmlinux из его состава.

mv ★★★★★
()
Ответ на: комментарий от mv

В общем, поставил компилить ядро, как написано в статье http://linux.xlibs.net/2006/11/20/howto-compile-a-kernel-the-ubuntu-way/ . Уже часа два в процессе. Что делать дальше после того, как оно скомпиляется, чтобы можно было отлаживать загружаемый модуль ядра?

codergeneration
() автор топика
Ответ на: комментарий от mv

похоже. я все-таки сделал что-то не так при сборке ядра или последующей установке. gdb ругается на таймаут подключения.

Делал по статьям: http://linux.xlibs.net/2006/11/20/howto-compile-a-kernel-the-ubuntu-way/ - сборка ядра

http://issaris.blogspot.com/2007/12/download-linux-kernel-sourcecode-from.html - здесь посмотрел пункты, которые надо отменить в kernel hack.

http://kgdb.linsyssoft.com/downloads/kgdb-2/kgdb_docu_full-2.4.pdf.bz2 - настройка подключения kgdb

Делал следующим образом: 1) взял конфиг ядра убунты

/boot/config-2.6.27-11-generic

положил его в папку с исходниками ядра /usr/src/linux-2.6.27.11 под именем .config

2) make menuconfig - загрузил эту конфигурацию, посмотрел на нее, но ничего менять не стал - звездочка напротив kgdb уже стояла. Так же были отмечены пункты из статьи http://issaris.blogspot.com/2007/12/download-linux-kernel-sourcecode-from.html .

3) скомпилил ядро и получил два .deb пакета.

4) Установил ядро из пакета на реальную машину и на машину на vmware

5) на виртуальной машине поправил конфиг загрузки /boot/grub/menu.lst:

kernel /boot/vmlinuz-2.6.27.11-debug root=UUID=много_цифр ro kgdbwait kgdb8250=1б115200

6) на vmware создал виртуальный com порт, смотрящий в файл /dev/serial.

7) ребутнул виртуалку с отредактированного пункта загрузки. Система не стала ждать подключения отладчика, как сказано в доке:( Хотя загрузка шла не в графическом режиме, а с выводом лога.

8) на основной машине дал команду

sudo gdb /boot/initrd.img-2.6.27.11-debug

в ней

(gdb) target remote /dev/serial

и тут получил таймаут.

К сожалению, дока про kgdb немного не подходила к моему случаю, поэтому пришлось по месту модифицировать действия. Боюсь, что сделал что-то не так. Во-первый, в конфиге ядра не было части пунктов, описанных в этой доке, во-вторых, немного модифицировал строку загрузки из menu.lst.

Что-то уже нет мыслей, как что-нибудь поменять. Нужен совет более опытного бубноведа - мой бубен уже не помогает:(

codergeneration
() автор топика
Ответ на: комментарий от codergeneration

Возьми Федору, там ядро уже с поддержкой KGDB:

$ grep -i kgdb /boot/config-`uname -r`
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_TESTS=y
# CONFIG_KGDB_TESTS_ON_BOOT is not set

> 4) Установил ядро из пакета на реальную машину и на машину на vmware

На реальной машине вообще ничего не надо трогать.

> kernel /boot/vmlinuz-2.6.27.11-debug root=UUID=много_цифр ro kgdbwait kgdb8250=1б115200 

8250 - это откуда? Тебе нужно ttyS0 (/dev/serial какой компорт эмулирует?)

> sudo gdb /boot/initrd.img-2.6.27.11-debug 

Неправильно, нужен не рамдиск, а именно само ядро (vmlinux) со всей debug info.

Почитай вот это: http://linux-hacks.blogspot.com/2008/05/setting-up-kgdb-using-kvmqemu.html

mv ★★★★★
()
Ответ на: комментарий от mv

в общем, удалось-таки настроить qemu, поставить на нее систему, поставить собранное ядро. В итоге теперь у меня получается с помощью gdb подключиться к ожидающей операционной системе. Но не совсем понятны следующие моменты: 1) >>Неправильно, нужен не рамдиск, а именно само ядро (vmlinux) со всей debug info.

Где взять этот файл (насколько я понимаю, именно его надо указать в качестве аргумента при запуске gdb)? В предложенной статье он упоминается, но не понятно, откуда берется. 2) после того, как я подключился к виртуалке отладчиком, я, насколько понимаю, должен запустить на выполнение Ось, дождаться загрузки, загрузить модуль с asm( "int $0x03" ) в начале функции загрузки. Но вот я что-то не пойму, как отладчику сказать, где лежат исходники этого модуля?

codergeneration
() автор топика
Ответ на: комментарий от codergeneration

> Где взять этот файл

В Федоре/RHEL:

$ rpm -ql kernel-debuginfo | grep vmlinux
/usr/lib/debug/lib/modules/2.6.29.3-140.fc11.x86_64/vmlinux

Если собирал сам:

$ ll ~/src/git/linux-2.6/vmlinux
-rwxrwxr-x. 1 vitaly vitaly 102825093 2009-05-19 11:00 /home/vitaly/src/git/linux-2.6/vmlinux

> (насколько я понимаю, именно его надо указать в качестве аргумента при запуске gdb)

Да.

> как я подключился к виртуалке отладчиком, я, насколько понимаю, должен запустить на выполнение Ось

Ядро под kgdb при загрузке останавливается и ждёт подключения gdb и команды continue от него.

> Но вот я что-то не пойму, как отладчику сказать, где лежат исходники этого модуля?

add-symbol-file. Вот тут почитай: http://www.linuxjournal.com/article/4525

mv ★★★★★
()
Ответ на: комментарий от mv

спасибо! получилось сгенерить vmlinux.

На этот раз похоже, что я как-то не так скомпилировал ядро. "This GDB was configured as "i486-linux-gnu"... (no debugging symbols found) " Или отладочные символы лежат в каком-то другом файле? Вроде в menuconfig поставил добавление отладочных символов к ядру. Конфиг: http://www.sharemania.ru/0108315

codergeneration
() автор топика
Ответ на: комментарий от mv

file ./vmlinux ./vmlinux: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped Странно. Вроде делал по статье, нигде не отколнялся. Разве что многопоточную сборку ядра включил.

http://linux.xlibs.net/2006/11/20/howto-compile-a-kernel-the-ubuntu-way/

codergeneration
() автор топика
Ответ на: комментарий от codergeneration

Собери ядро так:

make mrproper
make oldconfig
make -j2

mv ★★★★★
()
Ответ на: комментарий от codergeneration

vmlinux и модули с отладочной информацией очень много весят, поэтому пакетные заворачивалки делают strip.

У меня кастом-сборка vmlinux 100мб, модулей ещё на 520.

mv ★★★★★
()
Ответ на: комментарий от mv

Изыскания привели меня к использованию VirtualBox в связи с тем, что он намного шустре qemu. Ядро скомпилировано с kgdb, установлено, образ ядра с отладочными символами лежит. Но установить соединение отладчика и отлаживаемой системы мне так и не удалось.

1) в menu.lst в опциях загрузки указал: console kgdbwait kgdboc=ttyS0,115200 selinux=0

2) создал файл com порта:

sudo mknod -m 666 /tmp/cua0 c 5 64 sudo mknod -m 666 /tmp/ttyS0 c 4 64

3) в настройках com-порта указал com1; хост-устройство; /tmp/ttyS0.

4) Загрузил отлаживаемую систему. Она написала, что ожидает gdb.

5) Запустил gdb:

sudo gdb /usr/src/linux-headers-2.6.29.4-kgdb/vmlinux

6) указал скорость работы порта:

set remotebaud 115200

7) дал команду подключения к отлаживаемой системе:

target remote /tmp/ttyS0

8) получил ошибку:

/tmp/ttyS0: Input/output error.

Аналогичного результата добивался кучей разных других способов:)

Не могу понять, что сделал не так. Есть какие-нибудь мысли по этому поводу?

codergeneration
() автор топика
Ответ на: комментарий от codergeneration

> Изыскания привели меня к использованию VirtualBox в связи с тем, что он намного шустре qemu.

Qemu нужно использовать с kvm. А если процессор аппаратной виртуализации не поддерживает, то хотя бы qemu+kqemu.

> 2) создал файл com порта:


> sudo mknod -m 666 /tmp/cua0 c 5 64 sudo mknod -m 666 /tmp/ttyS0 c 4 64


Зачем? Девайсовую ноду будет обслуживать ядерный драйвер. Для коммуникации между двумя процессами это не годится.

> 8) получил ошибку:


> /tmp/ttyS0: Input/output error.


Закономерно.

> Не могу понять, что сделал не так. Есть какие-нибудь мысли по этому поводу?


По-идее, нужно создавать какой-нибудь юникс-сокет или пайп. Девайс создавать точно не нужно. Но я виртуалбокс в глаза не видел.

Вот тут что-то пишут: http://automatthias.wordpress.com/2008/09/13/serial-port-in-virtualbox/

mv ★★★★★
()
Ответ на: комментарий от mv

Спасибо! заработало!

На моей машине аппаратной виртуализации, к сожалению, нет. По этому kvm пришлось сразу откинуть. Настроил kqemu, это немного ускорило систему, но работа в ней все равно оставалась не комфортная. Мне посоветовали VirtualBox на нем реально все шустрее работает, я не вижу различия по скорости в той же vmware. + удобные штуки в виде дополнений гостевой ОС.

codergeneration
() автор топика
Ответ на: комментарий от codergeneration

Более внимательно углубился в отладку моего модуля. Поскольку время поджимает, решил посмотреть в сторону gui fron-end, чтобы немного сэкономить времени на изучении команд gdb. Пересмотрел несколько программ, но так и не нашел той, что помогла бы мне решить задачу. Большинство так я и не смог заставить подключиться к удаленному отладчику:( Первоначально мне показалось, что kdbg может все, что нужно - эта программа подключалась у удаленной системе, показывала исходник и ядра и все было бы ничего, но я так и не смог объяснить ей, что надо подцепить файл символом моего модуля, поскольку отлаживать я собираюсь именного его. А консоли gdb я не нашел, чтобы вручную заставить gdb подцепить символы. Более продвинутой оболочкой мне показалась DDD, но я так понял, что она не сможет подключится у удаленному kgdb в связи с тем, что ее удаленный режим работы базируется на каком-то другом протоколе. В отличие от kdgb, в DDD есть консоль gdb, но я так понял, что она только логирует ход взаимодействия и я не могу выполнять команды вручную (хотя у меня появилось подозрение, что у меня вообще что-то с клавиатурой в DDD:)).

Пока пытался найди приличный frontend, немного прокачался теорией самого gdb. По этому решил попробовать отладить вручную. И тут обратил внимание на то, что у меня при подключении к системе отладчик почему-то оказывает не то место, что в статье http://linux-hacks.blogspot.com/2008/05/setting-up-kgdb-using-kvmqemu.html . У меня он тормозит на команде 0xc0176884 in kgdb_register_io_module (new_kgdb_io_ops=<value optimized out>) at kernel/kgdb.c:1676. Я предположил, что у меня может различаться версия по сравнению с той, что использовалась в статье, но я нашел фрагмент кода, на котором тормозил их отладчик. На этом я решил проигнорировать этот факт и идти дальше.

Я попробовал подгрузить символы моего модуля module.ko командой symbol-file. При старте системы я подгрузил мой модуль с добавленным в начало его загрузки брейкпоинтом. Модуль остановился, я поставил брейк-поинт на функцию, в которой по моему мнению ошибка. Запустил. Брейкпоинт не сработал. Дальше я еще несколько раз пробовал повторить. Мне показалось, что отладчик каждый раз показывает разные места, где ему передалось управление при срабатывании моего первого брейкпоинта при инициализации модуля. Попробовал воспользоваться командой add-symbol-file. Но для нее надо знать адрес загрузки моего модуля, который не совсем понятно,как я должен узнать. В какой-то статье я прочитал, как его узнают после загрузки модуля, но у меня как раз на загрузке модуля система и ломается, по этому тут я попал в тупик. А теперь вообще не понятно, как жить дальше:)

codergeneration
() автор топика
Ответ на: комментарий от codergeneration

Появилась мысль, что должна быть какая-то структура, описывающая модуль, доступная самому модулю, в которой хранится адрес, по которому загружен модуль, типа PCB процесса. Из этой структурки можно было бы достать этот адрес и вывести с помощью printk. Но вот есть ли такая структура?

codergeneration
() автор топика
Ответ на: комментарий от codergeneration

> Но вот есть ли такая структура?

struct module по адресу THIS_MODULE

> в которой хранится адрес, по которому загружен модуль

поле module_core

rei3er
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.