Линус Торвальдс, главком ядра Linux, является строгим противником использования отладки ядра, т.к. по его мнению (я тоже пожалуй соглашусь) разработчик, который пишет код для kernel space (патчи ядра, модули), должен глубоко разбираться в архитектуре ядра, его внутренних интерфейсах и прочих «кишках», чтобы не прибегать к использованию отладки. Однако, со временем (начиная с версии 2.6.26), поддержка ядерного KGDB отладчика была добавлено в основное дерево.
Мне с KGDB приходилось работать в двух режимах: KDB и KGDOC.
KDB — локальная отладка с использованием клавиатуры PS/2.
KGDBOC (KGDB over serial console) — удаленная отладка с помощью последовательного порта.
Опции ядра для KGDBOC:
- # CONFIG_DEBUG_RODATA is not set
- CONFIG_FRAME_POINTER=y
- CONFIG_KGDB=y
- CONFIG_KGDB_SERIAL_CONSOLE=y
Опции ядра для KDB:
- # CONFIG_DEBUG_RODATA is not set
- CONFIG_FRAME_POINTER=y
- CONFIG_KGDB=y
- CONFIG_KGDB_SERIAL_CONSOLE=y
- CONFIG_KGDB_KDB=y
- CONFIG_KDB_KEYBOARD=y
Для активации отладчика необходимо выполнить на машине с собранным с KGDB ядром:
echo kbd > /sys/module/kgdboc/parameters/kgdboc
или
echo ttyS0,115200 > /sys/module/kgdboc/parameters/kgdboc
Если надо добавить эти опции на всегда, то в загрузчик надо передать соответствующие параметры. В случае загрузчика grub2, в файле /etc/default/grub:
GRUB_CMDLINE_LINUX_DEFAILT=»kgdboc=ttyS0,115200″
или
GRUB_CMDLINE_LINUX_DEFAILT=»kgdboc=kbd»
Далее, после выполнения команды:
echo g > /proc/sysrq-trigger
система принудительно произведет останов (сработает brakeppoint).
Если был указан kbd, то необходимо на этой же машине набрать комбинацию $3#33, которая активирует консоль «kbd>».
Если был указан ttyS0, то необходимо на удаленной машине (сопряженной с целевой нуль модемным кабелем) выполнить команды:
gdb ./vmlinux
set remoutebaud 115200
target remote /dev/ttyS0
Далее продолжаем работать как в обычном отладчике (команда «с» продожает выполнение ядра, «s» — шаг, и т.д.).
Если целевая машина является «виртуалкой» (VirtualBox или VMWare), то перед вызовом «echo g > /proc/sysrq-trigger» необходимо в настройках аппаратных компонентов этой машины добавить устройство последовательного порта (serial port или com) и указать режим его работы, как именованный канал сокет (use socket / named pipe / com / хост-канал). Например, «/tmp/kgdb». (В VMWare также надо добавить «галку» Yield CPU on poll; Направление : From «Server» to «Virtual Machine»).
После старта такой «виртуалки» необходимо запустить ретранслятор socat для двунаправленной передачи данных между «виртуалкой» и хостовой машиной:
socat -d -d /tmp/kgdb PTY
либо
socat -d -d /tmp/kgdb tcp-listen:9999
В случае опции PTY будет создан новый виртуальный порт, например «/dev/pts/6», который будет отображен в листинге socat. Этот виртуальный порт как раз надо будет указать в шеле gdb:
set remotebaud 115200
target remote /dev/pts/6
В случае опции tcp-listen:9999 в команде socat будет создан GDB TCP server на указанном порту (например, 9999), который также будет отображен в листинге socat. Тогда в шеле gdb необходимо выполнить:
target remote 127.0.0.1:9999
Также рекомендую использовать cgdb вместо gdb, т.к. в cgdb экран разделяется на две части: снизу обычный gdb, а свержу окно с исходниками (Vim Styled, переключение между окнами «ESC» и «i»).
Официальная документация: