kgdb

カーネルをデバッグするためのkgdbについて

本ページの位置:「シリコンリナックス」→「技術情報 CAT wiki」→「kgdb」

対象

  • linux-3.0.4カーネル
  • CAT724

導入

カーネルパッチ

kgdb over ethernet パッチ

drivers/net/filekgdboe.c

  • lib/Kconfig.kgdb
     config KGDB_SERIAL_CONSOLE
             tristate "KGDB: use kgdb over the serial console"
             select CONSOLE_POLL
             select MAGIC_SYSRQ
             default y
             help
               Share a serial console with kgdb. Sysrq-g must be used
               to break in initially.
     
    +config KGDB_OVER_ETHERNET
    +        tristate "KGDB: user kgdb over the ethernet"
    +        select NETPOLL
    +        default y
    +        help
    +         share a ethernet console with kgdb
     
     config KGDB_TESTS
  • drivers/net/Makefile
     obj-$(CONFIG_MLX4_CORE) += mlx4/
     obj-$(CONFIG_ENC28J60) += enc28j60.o
    +obj-$(CONFIG_KGDB_OVER_ETHERNET) += kgdboe.o
     obj-$(CONFIG_ETHOC) += ethoc.o
     obj-$(CONFIG_GRETH) += greth.o

コンフィグ

$ make cat724_defconfig
$ make menuconfig
Kernel hacking  --->
 [*] Magic SysRq key
 [*] Compile the kernel with debug info
 [*] KGDB: kernel debugger  --->
   < >   KGDB: use kgdb over the serial console
   <*>   KGDB: user kgdb over the ethernet (NEW)

カーネル起動パラメータ

ブートローダで
#> setparam console=ttySC0,115200 root=/dev/mtdblock2  (改行しない)
rootfstype=jffs2 ro kgdboe=1234@172.16.1.4/,1234@172.16.0.83/

文法  kgdboe=UDPポート番号@自分のアドレス/ , UDPポート番号@開発PCのアドレス/

これで udp ポート1234 で通信するようになる

カーネルデバッグの実際

デバッガに突入する(breakする)

CAT724にて

# echo g > /proc/sysrq-trigger
SysRq : DEBUG
Entering KGDB

開発PCにて

$ cd カーネルをビルドしたディレクトリ (vmlinuxがある位置)
$ sh4-linux-gnu-gdbtui vmlinux
(gdb) target remote udp:172.16.1.4:1234
960             wmb(); /* Sync point after breakpoint */
(gdb)

デバッグの例

(gdb) p (unsigned long)jiffies             jiffies変数の表示
(gdb) directory drivers/rtc/
(gdb) b rtc_read_time                      rtc_read_time()関数にブレイクを張る
(gdb) c
Continuing.

CAT724にて

# hwclock

rtc_read_time() 関数でブレイクするので

(gdb) s                                    step実行
(gdb) n                                    next実行

ローダブルモジュールのデバッグ

CAT724に /usr/local/bin/print_sections スクリプトを用意しておく

#!/bin/sh

cd /sys/module/$1/sections/

addr=`cat .text`
echo -n "$addr "

for A in .*
do
  if [ "$A" = "." ]; then continue; fi
  if [ "$A" = ".." ]; then continue; fi
  if [ "$A" = ".text" ]; then continue; fi
  addr=`cat $A`
  echo -n "-s $A $addr "
done
echo

timer_warikomi_thread での実験例

CAT724にて

# cd sample_driver/timer_warikomi_thread/
# insmod timer_warikomi.ko
# ls -la /sys/module/timer_warikomi/sections/

とするとモジュールの各セクションのアドレスを示すファイルが見つかる

# cat /sys/module/timer_warikomi/sections/.text
0xc006c000

この例では .text セクションは 0xc006c000 に置かれている。

各セクションを表示するスクリプトを実行する

# print_sections timer_warikomi
0xc006c000 -s .bss 0xc006c32c -s .gnu.linkonce.this_module 0xc006c1f8 -s .note.gnu.build-id 0xc006c148 
-s .rodata.str1.4 0xc006c16c -s .strtab 0xc006e250 -s .symtab 0xc006e000

CAT724にてブレイクする

# echo g > /proc/sysrq-trigger
SysRq : DEBUG
Entering KGDB

開発PCにて gdb に add-symbol-file で各セクションのアドレスを指定する。
上記のprint_sectionsで表示されたアドレスをコピーペーストする。

$ sh4-linux-gnu-gdbtui vmlinux
(gdb) add-symbol-file /どこかの/sample_driver/timer_warikomi_thread/timer_warikomi.ko  (改行しない)
 0xc006c000 -s .bss 0xc006c32c -s .gnu.linkonce.this_module 0xc006c1f8 -s .note.gnu.build-id 0xc006c148 
-s .rodata.str1.4 0xc006c16c -s .strtab 0xc006e250 -s .symtab 0xc006e000
(gdb) directory /どこかの/sample_driver/timer_warikomi_thread
(gdb) target remote udp:172.16.1.4:1234

ブレイクできたら

(gdb) b tmu2handler_bottom                           ドライバのボトムにbreakを置く
(gdb) c                                              コンティニュー

という方法でデバッグできるはずだが SH の場合安定して動作しない。

関連

自動リンク