Windows 7上のVMware PlayerでLinuxのデバイスドライバをリモートデバッグする方法(3) - 自動化する

Pocket

この記事は、
Windows 7上のVMware Playerにgdbでリモート接続する方法
Windows 7上のVMware PlayerでLinuxのデバイスドライバをリモートデバッグする方法(1) - デバッグするカーネルモジュールを用意する
Windows 7上のVMware PlayerでLinuxのデバイスドライバをリモートデバッグする方法(2) - リモートデバッグする
Windows 7上のVMware PlayerでLinuxのデバイスドライバをリモートデバッグする方法(3) - 自動化する
の1つです。

1. 実際にやってみると

実際にリモートデバッグをしてみると、いちいちセクションの情報を確認して値を設定することが非常に面倒なことがわかると思います。そこで、ゲストOS上でカーネルモジュールをロードする処理と、ホストOS上でgdbを設定する処理をシェルスクリプトで自動化してみます。

基本的にやっていることは、手作業でやっていたことを自動化しただけです。セクション情報をtext.txt、data.txt、bss.txtに保存して、それをゲストOSからホストOSにコピーします。それを使って、gdbの設定を行います。

2. プログラムの説明

load.shは、ゲストOS上でカーネルモジュールをロードするときに使います。

load.sh ---------------------------------------------------

#!/bin/bash

# modnameにカーネルモジュールの.koの名前を入れます。
modname='testmodule'

# devnameは、デバイスファイルの名前です。
devname='/dev/testmodule'

# my_majorにメジャー番号を入れます。
my_major=88

# locationは、VMwareで設定したホストOSにカーネルモジュールやソースをコピーするときの共有フォルダの名前です。
location='/mnt/hgfs/kazu'

# カーネルモジュールが存在すればアンロードします。
if [ -e /sys/module/$modname ]; then
    sudo rmmod $modname
fi

# カーネルモジュールをロードします。
sudo insmod ${modname}.ko

# デバイスファイルがなければ作ります。
if [ ! -e $devname ]; then
    sudo mknod $devname c $my_major 0
    sudo chmod a+rw $devname
fi

# セクション情報を保存します。
sudo cat /sys/module/${modname}/sections/.text >text.txt
sudo cat /sys/module/${modname}/sections/.data >data.txt
sudo cat /sys/module/${modname}/sections/.bss >bss.txt

# セクション情報をコピーします
cp text.txt $location
cp data.txt $location
cp bss.txt $location

# モジュールとソースコードをコピーします。
cp ${modname}.c $location
cp ${modname}.ko $location

--------------------------------------------------

gd.shは、ホストOS上でgdbをリモート接続するときに使います。break_pointに停止させたい関数の名前を設定します。

gd.sh ---------------------------------------------------------

#!/bin/bash
# gdb port number is required
# ./gd.sh number

# モジュールの名前をセットします。
module_name='testmodule'

# ソースの位置をセットします
source_location='/home/kazu/test'

# ブレークポイントを設定します。
break_point='my_ioctl'

# セクション情報を読み込みます。
text=`cat text.txt`
data=`cat data.txt`
bss=`cat bss.txt`

# gdbコマンドを.gdbinitファイルに設定します。
cat <<EOF >.gdbinit
set architecture i386:x86-64
target remote localhost:$1
add-symbol-file ${module_name}.ko $text -s .data $data -s .bss $bss
break $break_point
EOF

# ソースコードを設定した位置にコピーします。
cp ${module_name}.c $source_location

# gdbを実行します。
gdb

----------------------------------------------------

3. 使い方

ゲストOS上に、load.shを置いてください。そこで、

Ubuntu$ chmode +x load.sh

で実行可能にします。これは1度だけやればいいです。

ソースコードを編集した後、makeの後でload.shすることでモジュールのロードと、コピーがされます。

Ubuntu$ make
Ubuntu$ ./load.sh

ホストOSのCygwin上でgd.shを接続するポート番号とともに起動します。

Cygwin$ ./gd.sh 8864

GNU gdb (GDB) 7.6.50.20130728-cvs (cygwin-special)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-pc-cygwin".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".

The target architecture is assumed to be i386:x86-64
0xffffffff8104d386 in ?? ()
add symbol table from file "testmodule.ko" at
        .text_addr = 0xffffffffa03da000
        .data_addr = 0xffffffffa03dc000
        .bss_addr = 0xffffffffa03dc360
Breakpoint 1 at 0xffffffffa03da0f1: file /home/kazu/test/testmodule.c, line 51.
(gdb)

このような表示になって、ゲストOSの実行が止まれば成功です。この状態でcontinueします。

(gdb) continue

その後、ゲストOS上でtestdriverを動かします。

Ubuntu$ ./testdriver

そして、次のようにmy_ioctlで実行が止まれば成功です。

Breakpoint 1, my_ioctl (file=0xffff8800240cdec0, count=32,
    buf=18446612132972596240) at /home/kazu/test/testmodule.c:51
warning: Source file is more recent than executable.
51      {
(gdb)

あとは、手作業で変数の値を見たりできます。面倒な作業が自動化できれば、カーネルモジュールの開発に集中できると思います。

4. 参考にしたサイト

この記事を作るときに、非常に多くのサイトを参考にさせてもらいました。ありがとうございます。もし、何か問題があったら、これらのサイトを参考にしてみてください。

リモートデバッグについて
VMwareのGDB機能を利用する
LinuxでLoadable Moduleをデバッグする
VMware
Qemu and the Kernel
The Kernel Newbie Corner: Kernel and Module Debugging with gdb
Debugging kernel modules
Debug-info for loadable kernel modules
■[Debian] VMwareでLinuxカーネルのデバッグ
Debugging Linux kernels with Workstation 6.0
Debugging Linux Kernel in VMWare with Windows host

カーネルモジュールについて
CS 686: Special Topic: Intel EM64T and VT Extensions (Spring 2007)

gdbの使い方について
gdbコマンド メモ
gdb の使い方・デバッグ方法まとめ

シェルスクリプトについて
UNIX & Linux コマンド・シェルスクリプト リファレンス

Pocket

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください