15.5. Отладка ядра в режиме реального времени при помощи удаленного GDB

Эта возможность поддерживается во FreeBSD начиная с версии 2.2, и она на самом деле очень удобна.

В GDB уже давно имеется поддержка удаленной отладки. Это делается при помощи весьма простого протокола по последовательному каналу. В отличие от других методов, описанных выше, для этого вам требуется наличие двух машин. Одна из них является хостом, предоставляющим ресурсы для отладки, включая все исходные тексты и копию ядра со всеми символами в нем, а другая является целевой машиной, на которой запущена та же копия того же ядра (но без отладочной информации).

Вы должны настроить исследуемое ядро при помощи команды config -g, включить DDB в конфигурацию и откомпилировать его обычным образом. Это даст большой объем получаемого бинарного файла из-за отладочной информации. Скопируйте это ядро на целевую машину, усеките отладочную информацию командой strip -x и загрузите это ядро с использованием параметра загрузки -d. Подключите последовательный канал целевой машины, имеющий установленные флаги "flags 080" на соответствующем устройстве sio к любому последовательному каналу отладочного хоста. А теперь на отладочной машине перейдите в каталог компиляции целевого ядра и запустите gdb:

    % gdb -k kernel
    GDB is free software and you are welcome to distribute copies of it
     under certain conditions; type "show copying" to see the conditions.
    There is absolutely no warranty for GDB; type "show warranty" for details.
    GDB 4.16 (i386-unknown-freebsd),
    Copyright 1996 Free Software Foundation, Inc...
    (kgdb)
        

Проинициализируйте сеанс удаленной отладки (предполагается, что используется первый последовательный порт) такой командой:

    (kgdb) target remote /dev/cuaa0
        

Теперь на целевом хосте (тот, который перешел в DDB даже до начала процесса обнаружения устройств) наберите:

    Debugger("Boot flags requested debugger")
    Stopped at Debugger+0x35: movb	$0, edata+0x51bc
    db> gdb
        

DDB ответит следующим:

    Next trap will enter GDB remote protocol mode

Каждый раз, когда вы будете набирать gdb, режим будет меняться между удаленным GDB и локальным DDB. Чтобы немедленно вызвать следующее прерывание, просто наберите s (step). Ваш хостирующий GDB получит управление над целевым ядром:

    Remote debugging using /dev/cuaa0
    Debugger (msg=0xf01b0383 "Boot flags requested debugger")
        at ../../i386/i386/db_interface.c:257
    (kgdb)
        

Вы можете работать в этом сеансе точно также, как и в любом другом сеансе GDB, включая полный доступ к исходным текстам, запуск его в режиме gud-mode внутри окна Emacs (что дает вам автоматический вывод исходного кода в другом окне Emacs) и тому подобное.

Удаленный GDB также может использоваться для отладки модулей LKM. Сначала откомпилируйте LKM с отладочной информацией:

    # cd /usr/src/lkm/linux
    # make clean; make COPTS=-g
        

Затем установите эту версию модуля на целевой машине, загрузите его и воспользуйтесь командой modstat для определения того, куда он был загружен:

    # linux
    # modstat
    Type	 Id Off Loadaddr Size Info     Rev Module Name
    EXEC	  0   4 f5109000 001c f510f010	 1 linux_mod
        

Возьмите адрес загрузки модуля и добавьте к нему 0x20 (для размера заголовка a.out). Получится адрес, куда был перемещен код модуля. Воспользуйтесь командой add-symbol-file в GDB для указания отладчику на модуль:

    (kgdb) add-symbol-file /usr/src/lkm/linux/linux_mod.o 0xf5109020
    add symbol table from file "/usr/src/lkm/linux/linux_mod.o" at
    text_addr = 0xf5109020? (y or n) y
    (kgdb)
        

Теперь вы имеете доступ ко всем символам в LKM.