Линус Торвальдс, главком ядра 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»).

 

Официальная документация:

  1. KGDB
  2. CGDB