KGDB: Linux Kernel Source Level Debugger
Czym jest KGDB?

  • Jest to narzędzie do zdalnego debugowania jądra oraz ładowalnych modułów linuxa.
  • Instaluje się je jako patch do konkretnej wersji jądra.
  • Potrzebne są dwie maszyny( development machine - z której debugujemy, test machine - którą debugujemy) połączone przez port szeregowy
  • Debugger na poziomie kodu źródłowego
    Zalety:
  • debugujemy jądro w gdb, jak zwyczajny program, widząc i śledząc wykonywany kod w C.
  • - debug modułów - możliwość śledzenia kodu wykonania przy ładowaniu i działaniu modułów. Najbardziej przydatna dla nas funkcjonalność, gdyż swoje programy będziemy pisać jako moduły.
  • - debugowanie startującego systemu - przy specjalnej opcji, maszyna testowa "poczeka" aż podłączymy się do niej z drugiej maszyny przez gdb.
  • - praca zdalna - możliwość modyfikacji jądra bez ryzyka uszkodzenia własnego systemu.
    Wady:
  • trzeba jednak mieć dwie maszyny i port szeregowy ( choć łatwy do emulacji, także w VMwarze)
  • KGDB działa tylko dla pewnych nienajnowszych wersji jądra.
  • Instalacja KGDB

    Omówię instalację KGDB pod Linuxem, gdy maszyna testowana jest wirtualną maszyną w VMwarze. Aby zainstalować KGDB należy na maszynie deweloperskiej przygotować jądro dla maszyny testowej:

    • Ściągamy najnowszą wersję KGDB - na tą chwile 2.4 pod jądro 2.6.15.
    • Ściągamy źródła jądra linuxa na maszynie deweloperskiej- na pewno działa na 2.6.15.6. Po czym je rozpakowujemy. Powiedzmy ze w taki sposob:

      host% tar -xjvf linux-2.6.15.6.tar.bz2

    • Rozpakowujemy w katalogu źrodeł jądra, źrodła KGDB. Po czym aplikujemy patche do jądra:

      host% cd linux-2.6.15.6/
      host% tar -jxvf linux-2.6.15.5-kgdb-2.4.tar.bz2
      host% patch -p1 < linux-2.6.15.5-kgdb-2.4/core-lite.patch
      host% patch -p1 < linux-2.6.15.5-kgdb-2.4/core.patch
      host% patch -p1 < linux-2.6.15.5-kgdb-2.4/i386-lite.patch
      host% patch -p1 < linux-2.6.15.5-kgdb-2.4/i386.patch
      host% patch -p1 < linux-2.6.15.5-kgdb-2.4/8250.patch
      host% patch -p1 < linux-2.6.15.5-kgdb-2.4/module.patch

      (W przypadku innej architektury maszyny testowej niż i386, zamieniamy te patche, na odpowiadającą architekturę)
    • Konfigurujemy jądro, np. poleceniem :

      make menuconfig

    • Wybieramy opcje:


      Kernel hacking ->
      [*] KGDB: kernel debugging with remote gdb ->
      [?] KGDB: Console messages through gdb
      Method for KGDB communication (KGDB: On generic serial port (8250)) --->
         ( ) KGDB: Use only kernel modules for I/O
         (X) KGDB: On generic serial port (8250)
         ( ) KGDB: On ethernet - in kernel
      [*] Simple selection of KGDB serial port
      (115200) Debug serial port baud rate
      (0) Serial port number for KGDB


      Tam, gdzie mieści sie znak zapytania, trzeba wybrać jeden z dwóch sposobów wyświetlania komunikatów jądra: Gdy opcja jest zaznaczona, to wszystkie komunikaty wysyłane przez jądro(np. przy bootowaniu) trafiają na konsole gdb. Jest to przydatne, jak pracujemy na jednym monitorze, a potrzebujemy widzieć na bieżąco każdy komunikat od jądra. W przeciwnym przypadku, komunikaty normalnie trafiaja na swoją konsole.
    • Kompilujemy jądro. Wystarczy skompilować make'iem i zainstalowac moduly, by wszystkie siedzialy w jednym folderze.

      make && make modules_install

    • Teraz przenosimy jądro na maszynę testową,np.:

      host% scp arch/i386/kernel/bzImage [użytkownik]@[adres hosta]:/boot/vmlinuz-2.6.15.6-kgdb
      host% scp System.map [użytkownik]@[adres hosta]:/boot/System.map-2.6.15.6-kgdb
      host% scp /lib/modules/2.6.15.6-kgdb [użytkownik]@[adres hosta]:/lib/modules/

      na maszynie testowej, trzeba zaktualizować boot-loadera, jeśli używamy gruba, jest to:

      update-grub

    • na maszynie deweloperskiej ściągamy i instalujemy jeszcze program socat:(Jest między innymi w repozytoriach SuSE lub Debiana)
      http://www.dest-unreach.org/socat/
    • oraz specjalne, zmodyfikowane gdb, aby łatwiej się debugowało moduły: http://kgdb.linsyssoft.com/downloads/gdbmod-2.4.bz2
    • Gdy chcemy debugować także proces bootowania, to dodajemy do opcji uruchamiania jądra testowego opcję kgdbwait. Dokładniej(zakładając, że używamy gruba) w pliku /boot/grub/menu.lst powinien znajdować się wpis dotyczący naszego nowego jądra(o ile wykonaliśmy update-grub). Dopisujemy do niego opcję kgdbwait. Może wygladać to na przykład tak:

      title Debian GNU/Linux, kernel 2.6.15.6-kgdb
      root (hd0,0)
      kernel /boot/vmlinuz-2.6.15.6-kgdb root=/dev/hda1 ro
      savedefault
      boot

    Uruchamianie KGDB



    Na maszynie deweloperskiej uruchamiamy emulację portu szeregowego za pomocą programu socat. Podajemu mu plik reprezentujący urządzenie szeregowe, do którego mamy się podłaczyć. Gdy robimy to w vmwarze, stworzy on plik o nazwie przez nas podanej. Może to być na przykład "/tmp/com_1" :

    host% socat -d -d /tmp/com_1 PTY:
    socat wyświetli urządzenie, na jakim zainstalował połączenie szeregowe, niech będzie to : "dev/pts/0"
    host% gdb ./vmlinux
    (gdb) target remote /dev/pts/0

    I jesteśmy połączeni.
    Przykład użycia KGDB do debugowania prostego modułu hello_mod w postaci Flash-screencasta: link
    Pomocne linki