原理
原理结构图
原理过程
Kgdb是双机在线调试,一端是Host端(linux),运行GDB,另一端是Target端,运行带Kgdb的linux内核。
两边通过串口(KGDBoc)或网络口(KGDBoE)相连接,kgdb实现了远程调试的功能,主要部件有:
stub
stub可卸任是一个运行在target端的代理,它负责与远程的Host端进行沟通,接收Host端发来的指令。
应用场景
如上面原理图所示,常常用于嵌入式开发场景中,开发板作为target端,运行打开Kgdb的内核 ,PC机作为Host端,运行GDB,用来远程调试Target端的内核。
内核配置
在内核2.6.26版本之前,Kgdb是以Patch的方式提供,要使用它需要经过复杂的配置过程,并且容易出错,之后,就集成到了内核中,只需要打开相关配置项即可使用了。
这里,我们以内核 4.4.19为例,KGDB的配置如下:
Kernel hacking --->
[*] KGDB: kernel debugger --->
[ ] KGDB: internal test suite
[*] KGDB: Allow debugging with traps in notifiers
[*] KGDB_KDB: include kdb frontend for kgdb
DEBUG相关配置:
Kernel hacking --->
Compile-time checks and compiler options --->
[*] Compile the kernel with debug info
实例:利用virtualBox(ubuntu14.04) 使用Kgdb进行模拟双机调试
环境:
- Host:deepin 15.2(64Bit)
- Target:virtualbox(Ubuntu14.04_64bit)
- 连接方式:虚拟串口
结构图
准备工作
- 设置虚拟串口
详细参考另一篇博文《Linux主机和VirtualBox之间实现串口通信》
- 在虚拟机中运行开启KGDB的内核
这里,为了方便测试KGDB,直接使用源码中自带的arch/x86/configs/x86_64_defconf
执行
make x86_64_defconf
然后再执行 :
make menuconfig
参考上面开启KGDB和DEBUG相关的内核配置项。
编译带有调试信息的内核
make-kpkg --initrd --revision 001.magc --append-to-version -20160901 kernel_debug kernel_image kernel_headers
注:这里kernel_debug和kernel_image要同时有,因为它们产生的deb有依赖关系。
编译成功后,会看到生成三个deb包,并使用dpkg 命令将它安装上去。
另外,还要将此源码和产物,放到HOST里面一份。
- 修改Guest OS的Grub启动参数
在Guset OS中修改/boot/grub/grub.cfg
找到当前系统使用的内核启动命令行,在后面添加:
kgdboc=ttyS0 115200 kgdbwait
注:
- kgdboc:是指KGDB over console 使用波特率为115200的ttyS0.
- kgdbwait:是让kernel一直等等待直到连上GDB为止。
- 添加此参数后,需要重启系统来激活这些参数。
- 在HOST中使用socat来连接虚拟串口的命名管道文件
# socat -d -d /home/magc/workspace/vmserial PTY
注:
- PTY:是一种pseudo-terminal
- /home/magc/workspace/vmserial:是虚拟串口在HOST上的命名管道文件
- 当运行此命令后,终端进入等待状态,如下图示:
如上所示,得到的pseudo-terminal的设备名是/dev/pts/0 ,这个进程需要在调试过程中一直进行,并且HOST上的GDB会使用这个这设备名
开始双机调试
通过上面几步准备工作,使HOST和虚拟机的虚拟串口连接起来,此时重新启动虚拟机。此时,虚拟机会卡住,等等连接HOST上的GDB.
1. 启动HOST上的GDB:
进入源码编译目录下(此源码目录是从Guest OS中复制过来的),执行下面命令,启动GDB:
# cd linux-4.4.19
# gdb ./vmlinux
(gdb) target remote /dev/pts/0
此时虚拟机仍停止等待,当在GDB中输入下面指令:
continue
此时虚拟机就会继续启动进入系统了。
若想重新回到GDB控制,只需要在Guest OS中执行下面命令:
echo g > /proc/sysrq-trigger
此时,Guest OS就会中止当前会话,回到HOST的GDB控制中。这样就可以增加断点以及调试了。
2. 调试内核模块:
若是调试内核的话,按上面操作方法即可满足需求,若是想调试某个单独的内核模块,那就在Guest OS中安装此模块,并拿到此模块的.text段地址(/sys/module//sections/.text) ,并在HOST的GDB中通过add-symbol-file 参数加载进来进行调试即可。
小结
通过VirtualBox使用KGDB进行双机调试的主要步骤:
1. 在HOST和Guest OS之间建立虚拟串口连接
2. 在Guest OS里编译安装带Debug的内核,并修改Grub启动参数
3. 在Host里启动GDB,并连接到虚拟串口上,开始双机调试
参考:http://opensourceforu.com/2011/03/kgdb-with-virtualbox-debug-live-kernel/