gdbからgdbserverに接続してリモートデバッグするときに従来のremoteモードに加えて、extended-remoteモードが使用できます。
#従来のremoteモードとextended-remoteモードの比較
remoteモードではgdbserverを起動する段階でどのプロセスをデバッグ対象とするのかを決める必要がありました。(新たにプロセスを起動するか or 実行中のプロセスにアタッチするか)
そして、デバッグが終了してgdbとgdbserverの間の通信が切れた段階でgdbserverのプロセスは終了していました。
extended-remoteモードではデバッグ対象を決めずにgdbserverを起動させておくことができ、gdbと接続した後にデバッグ対象のプロセスを決めてアタッチすることができます。またデタッチした後もgdbserverは生き続けて、再度同じまたは別のプロセスをアタッチすることができます。gdbserverを終了させるには、gdbから "monitor exit" のコマンドを実行します。
要するに、extended-remoteモードではgdbserverを常駐させ続けることができるので、新しくデバッグを始めるたびにgdbserverを起動する必要がなくなるわけです。
#試してみよう
デバッグ対象として、さきほどの記事(組み込みLinuxでクロスデバッグするときのgdbのセットアップ方法)と同じものを使用します。
ソースファイルはこれ。loop.c
.gdbinit は target remote を target extended-remote に修正します。
set sysroot ../buildroot/buildroot-2016.05/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/
#target remote 192.168.129.32:1234
target extended-remote 192.168.129.32:1234
#gdbserverの起動
ARM Linux側でgdbserverを起動します。
デバッグ対象のプロセスを指定する代わりに --multi オプションをつけます。
ARM# gdbserver --multi :1234
Listening on port 1234
#gdbの起動
デバッグホスト側でARM用のgdbを起動します。
$ arm-buildroot-linux-gnueabi-gdb
GNU gdb (GDB) 7.10.1
Copyright (C) 2015 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 "--host=x86_64-unknown-linux-gnu --target=arm-buildroot-linux-gnueabi".
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".
(gdb)
attach する前にデバッグ対象のオブジェクトをfileコマンドで指定しておきます。
(これをせずにattachするとgdbが変な状態になってしまいました。)
それから,attachするためのプロセスIDは、別のttyにログインしてpsコマンドで調べる必要があります。gdbの中からリモートにpsを実行できたらいいのに。
(gdb) file loop
Reading symbols from loop...done.
(gdb) attach 334
Attaching to program: /home/koba/work/at1/gdbtest/loop, process 334
Reading symbols from ../buildroot/buildroot-2016.05/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/lib/libc.so.6...done.
Reading symbols from ../buildroot/buildroot-2016.05/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/lib/ld-linux.so.3...done.
0xb6f01bac in nanosleep ()
from ../buildroot/buildroot-2016.05/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/lib/libc.so.6
(gdb)
現在のバックトレースを確認。
(gdb) bt
#0 0xb6f01bac in nanosleep ()
from ../buildroot/buildroot-2016.05/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/lib/libc.so.6
#1 0xb6f01aa4 in sleep ()
from ../buildroot/buildroot-2016.05/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/lib/libc.so.6
#2 0x0001042c in func2 () at loop.c:16
#3 0x0001045c in func1 () at loop.c:7
#4 0x00010468 in main () at loop.c:23
(gdb)
detach
#4 0x00010468 in main () at loop.c:23
(gdb) detach
Detaching from program: /home/koba/work/at1/gdbtest/loop, process 334
(gdb)
プロセスloop はデバッガが外れたので再度動きだし始めました。
もう一度attach
(gdb) attach 334
Attaching to program: /home/koba/work/at1/gdbtest/loop, process 334
Reading symbols from ../buildroot/buildroot-2016.05/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/lib/libc.so.6...done.
Reading symbols from ../buildroot/buildroot-2016.05/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/lib/ld-linux.so.3...done.
0xb6f01bac in nanosleep ()
from ../buildroot/buildroot-2016.05/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/lib/libc.so.6
(gdb)
detachしてからmonitor exit
(gdb) detach
Detaching from program: /home/koba/work/at1/gdbtest/loop, process 334
(gdb) monitor exit
(gdb)
これで gdbserver のプロセスは終了しました。
attachする前にfileコマンドで(またはgdb起動時の引数で)デバッグ対象のシンボルをロードしておくのがポイントのようです。
さて、このextended-remoteモードはどういう時に便利なのかな?
ひとつ思いついたことがあるので、それは続きの記事で。
続きを書きました。gdbのリモートデバッグのextended-remoteモードを試す(2)
#参考