gdb 调试kvm虚拟机_搭建Eclipse+QEMU+GDB调试Linux Kernel环境

0.前言

本文讲述搭建环境的关键环节,相应的工具及版本如下:

JDK:1.6.0_45

Eclipse:eclipse-cpp-kepler-SR2-linux-gtk-x86_64.tar.gz

Qemu:QEMU emulator version 1.5.0 (Debian 1.5.0+dfsg-3ubuntu5.3)

OS:Ubuntu13.10,64bit

其中,JDK 和 Eclipse 工具下载和配置可查阅“参考资料 a”,而在我的 OS 环境里 Eclipse 会有菜单显示问题,可查阅“参考资料 c”。

1.安装 Eclipse 插件 CDT

运行 Eclipse,点击菜单“Help”->“Install New Software...”,在弹出的对话框里点击“Work with:”后面的下拉按钮,选择“Kepler – http://download.eclipse.org/releases/kepler”(不同的 Eclipse 版本选择不一样,与自己下载的版本一致一即可),然后在下面的选择框中将“Programming Languages”的“C/C++ Autotools support”和“C/C++ Visual C++ Support”这两项(对应http://download.eclipse.org/releases/juno 包里的 CDT)以及“C/C++ Development Tools”和“C/C++ Development Tools SDK”选中,接下来点击“Next >”按钮两次和“Finish”一次(共显示 3 个页面),注意其间要选中接收条款,剩下就是自动连网下载安装选中的软件包,安装好后自动重启Eclipse 即可。其中配置 CDT 的界面如下:

配置 CDT 的界面

除了上面与 C/C++相关的工具,还需要安装与 Linux 相关的 GDB,将“Linux Tools”里的“GDB Tracepoint Analysis”和“Mobile and Device Development”里的“C/C++ GDB Hardware Debugging”选中安装上,如下截图:

安装与 Linux 相关的 GDB

注:上面装的工具有些过多,可自行删减,这里是满足更多需求,将相关的全安装上了。

2.安装 QEMU

执行如下命令即可安装下 QEMU 各平台的模拟工具:sudo apt-get install qemu

3.配置联调环境

在上面的工具安装好后,接下来就是要配置联调环境了,首先先把 QEMU 运行起来,执行如

下命令:qemu-system-x86_64 -s -S -kernel ~/linux-3.13.6/arch/x86_64/boot/bzImage -initrd /boot/initrd.img-3.11.0-12-generic

这里我们模拟的是 64 位的 X86,用到的 Kernel 为“参考资料 b”编译好的,而用到的 Ram Disk则是 Ubuntu13.10 里自带的,这里的-s 和-S 在帮助里分别说明如下:-s shorthand for -gdb tcp::1234

-S freeze CPU at startup (use 'c' to start execution)

即-s 为开启 GDB 的调试端口 1234,而-S 则表示运行 QEMU 时冻结住,等待 GDB 执行(c)ontinue 操作。

就这样先执行着,不进行跟QEMU 相关的其他操作,QEMU 一直处于黑屏状态(Pause 状态),等待远程 GDB 的一个 c,接下来配置 Eclipse 环境:a.点击菜单“Window”->“Preferences”,在弹出的对话框中,点击左边的“General”->“Workspace”,将右边的“Build automatically”复选框不选中。再点击对话框左边的“C/C++”->“Indexer”,将右边的“Enable indexer”和“Automatically update the index”两复选框不选中。

b.接下来创建一个工程,点击菜单“File”->“New”->“Project...”,在弹出的对话框中选择“C/C++”->“C Project”,再点击“Next >”按钮,出现的对话框配置如下:

其中,“Project name:”为工程名,可自定义;而“Location:”则为工程文件所在路径,此处设置为 Linux Kernel 源码目录,而“Project type:”则设置为“Makefile project”/“Empty Project”,“Toolchains:”则设置为“Linux GCC”,最后点击“Finish”即可。

c.接下来进行 DEBUG 配置,在“Project Explorer”里右击刚创建的“Linux_Kernel_3.13.6”项目,在右键菜单中点击“Debug As”->“Debug Configurations...”,在弹出的对话框中双击“C/C++ Remote Application”,配置如下截图:

将“C/C++ Application:”栏设置为 Linux Kernel 源码编译出来的 vmlinux 文件所在路径(包含文件名),然后将“Disable auto build”选上,切换到“Debugger”页,修改配置如下截图:

将“Stop on startup at”设置为 start_kernel(Linux Kernel 的入口函数),将“Port number:”设置为之前 QEMU 运行时的默认端口号 1234,“Apply”后再点击上图中的“Debug”按钮开始调试,此时会切换到如下界面:

至此,调试环境也配置好了,接下来是试验下能不能调试了。

d.此时,满心欢喜的等看结果,发现 QEMU 的状态是 Paused,如下截图:

想想肯定是 GDB(我的系统 GDB 版本为 7.6.1)搞鬼,又回到 Eclipse 下查看了, 双击上面Eclipse 调试界面的“Console”标题,让该页最大显示,再点击其右边的“Display Selected Console”按钮(小显示器图标),有如下截图:

原来是有“Remote ‘g’ packet reply is too long:”卡住了,在接下来的“后记”里有说到, 往上跟踪执行的提示,发现有如下内容:637,056 12source .gdbinit

637,056 &"source .gdbinit\n"

637,057 &".gdbinit: No such file or directory.\n"

637,057 12^error,msg=".gdbinit: No such file or directory."

于是想在当前工程根目录下创建一个.gdbinit 文件,然后把“后记”里的那句设置架构的语句放上,但是没效,继续跟踪上面的提示,有如下内容:644,425 17-target-select remote localhost:1234

644,446 =thread-group-started,id="i1",pid="42000"

644,446 =thread-created,id="1",group-id="i1"

发现.gdbinit 是在 remote 连接前先执行,而设置架构是在连接后再设置的,故而也不是办法,只好另找出路了。

从网上找到需要修改 GDB 源码重新编译,故而我们也试试吧。首先,下载 GDB 源码:cd ~/dev_tools

wget http://ftp.gnu.org/gnu/gdb/gdb-7.7.tar.gz

下载完成后进行解压和修改代码:tar xvf gdb-7.7.tar.gz

cd gdb-7.7/

修改 gdb/remote.c 文件,在 process_g_packet 函数里,将如下代码:if (buf_len > 2 * rsa->sizeof_g_packet)

error (_("Remote 'g' packet reply is too long: %s"), rs->buf);

更改为:if (buf_len > 2 * rsa->sizeof_g_packet) {

rsa->sizeof_g_packet = buf_len ;

for (i = 0; i < gdbarch_num_regs (gdbarch); i++) {

if (rsa->regs[i].pnum == -1)

continue;

if (rsa->regs[i].offset >= rsa->sizeof_g_packet)

rsa->regs[i].in_g_packet = 0;

else

rsa->regs[i].in_g_packet = 1;

}

}

更新代码完成后接着配置、编译和安装:./configure –prefix=/home/xinu/dev_tools/mygdb

make

make install

GDB更新好后,接下来重新配置下 Eclipse,点击菜单“Run”->“Debug Configurations...”,在弹出的对话框中,切换到“Debugger”下的“Main”页,修改“GDB debugger:”为刚编译出来的 GDB,而不是默认的 gdb,相应的.gdbinit 也可在该页设置,如下截图:

配置好“Apply”后,再点击“Debug”,此时 QEMU 仍是停在上面的截图位置,但 Eclipse 已停在上图的“start_kernel”处,接下来就可以任我虐了(Step Into、Step Over 等 Step 调试),有如下截图:

从上图可以看到断点位置相关的源码和汇编代码,这样就可以方便我们跟踪阅读 Kernel 的执行流程,学习 Kernel 的精辟设计思想。

4.后记

在使用 gdb 调试时会有如下错误提示:Remote 'g' packet reply is too long: d85f8780ffffffff88......

省略号(......)表示后面还有一长串 16 进制数,解决的方法是在进行 gdb 操作前先在(gdb)后面执行如下语句:set architecture i386:x86-64:intel

请根据实际情况配置,这个问题是 GDB 调试 64 位 Kernel 时才有的。我机器上有如下可选参数:(gdb) set architecture

Requires an argument. Valid arguments are i386, i386:x86-64, i386:x64-32, i8086, i386:intel,i386:x86-64:intel, i386:x64-32:intel, auto.

5.参考资料

a.《Eclispe+qemu+gdb 调试 linux Kernel 全过程 》

http://yyqing.me/blog/2013/03/06/eclisep-plus-qemu-plus-gdbdiao-shi-linux-kernelquan-guo-cheng/

b.《为 Ubuntu 换颗“心”》

c.《Ubuntu13.10 下 eclipse 主菜单下拉菜单无显示》

http://blog.sina.com.cn/s/blog_3e4774e30101r24i.html

d.《【记录】给 Eclipse 安装 CDT 插件》

http://www.crifan.com/install_eclipse_cdt_plugin/

e.《利用 KVM 调试内核》

http://lenky.info/archives/2012/05/12/1624

f.《linux 内核调试:qemu+eclipse 组合》

http://blog.csdn.net/ustc_dylan/article/details/5991490

g.gdb-remote-7.x.patch

https://github.com/xinhaoyuan/ucore-mp64/blob/master/misc/gdb-remote-7.x.patch

你可能感兴趣的:(gdb,调试kvm虚拟机)