Ubuntu内核调试要点(上)——准备符号和源文件
内核调试是解决复杂软件问题和探索内核世界的最佳手段。因为多方面原因,Linux系统的内核调试设施在很长一段时间里都比较薄弱,特别是与Windows相比,落后较多。不过这种情况正在改变。本文以Ubuntu为例,详细介绍Linux内核调试的现状,着重介绍存在误解和难点的地方。
首先,如果对于从Ubuntu官网下载安装包而安装的系统,不需要重新编译内核。因为,Canonical(开发Ubuntu的公司)在编译时,已经开启了内核调试支持。如果你想确认一下,那么可以查看/boot目录下的编译选项文件,比如对于目前使用较多的16.04 LTS版本:
gedu@gedu-VirtualBox:/boot$ cat config-4.8.0-36-generic | grep -i "GDB"
# CONFIG_CFG80211_INTERNAL_REGDB is not set
CONFIG_SERIAL_KGDB_NMI=y
CONFIG_GDB_SCRIPTS=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
# CONFIG_KGDB_TESTS is not set
CONFIG_KGDB_LOW_LEVEL_TRAP=y
CONFIG_KGDB_KDB=y
可以看到,关于KDB和KGDB的几个选项都是开启的(yes)。
第二个问题是符号文件。
虽然编译选项已经开启了,但是没有符号文件,那么会缺少很多信息,也无法做源代码调试,岂不是还要重新编译?非也。早在2007年,Ubuntu就公开了符号服务器,其网址为http://ddebs.ubuntu.com。其角色和价值与微软的符号服务器是一样的。
那么如何从Ubuntu的符号服务器下载符号呢?基本步骤如下:
1,执行如下命令,产生“符号源列表”文件ddebs.list:
codename=$(lsb_release -c | awk '{print $2}')
sudo tee /etc/apt/sources.list.d/ddebs.list << EOF
deb http://ddebs.ubuntu.com/ ${codename} main restricted universe multiverse
deb http://ddebs.ubuntu.com/ ${codename}-security main restricted universe multiverse
deb http://ddebs.ubuntu.com/ ${codename}-updates main restricted universe multiverse
deb http://ddebs.ubuntu.com/ ${codename}-proposed main restricted universe multiverse
EOF
lsb_release -c命令用来获取当前Ubuntu的开发代号,用于在符号服务器中寻找所需符号包。产生好的ddebs.list应该像下面这样:
ge@gewubox:/etc/apt/sources.list.d$ cat ddebs.list
deb http://ddebs.ubuntu.com/ precise main restricted universe multiverse
deb http://ddebs.ubuntu.com/ precise-security main restricted universe multiverse
deb http://ddebs.ubuntu.com/ precise-updates main restricted universe multiverse
deb http://ddebs.ubuntu.com/ precise-proposed main restricted universe multiverse
其实,对于16.04之前的版本,只需要第一行,为了统一,可以都多加几行。
2,添加访问符号服务器的密钥文件:
wget -O - http://ddebs.ubuntu.com/dbgsym-release-key.asc | sudo apt-key add -
以下是执行过程:
--2018-03-09 22:29:51-- http://ddebs.ubuntu.com/dbgsym-release-key.asc
Resolving ddebs.ubuntu.com (ddebs.ubuntu.com)... 91.189.90.217
Connecting to ddebs.ubuntu.com (ddebs.ubuntu.com)|91.189.90.217|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2471 (2.4K) [text/plain]
Saving to: `STDOUT'
100%[======================================================>]
2,471 --.-K/s in 0s
2018-03-09 22:30:00 (147 MB/s) - written to stdout [2471/2471]
OK
3,执行sudo apt-get update更新
4,执行如下命令开始下载符号包:
sudo apt-get install linux-image-`uname -r`-dbgsym
对于64位的16.04 LTS,安装过程需要占用大约4GB的磁盘空间,也需要下载一会。
安装过程如果顺利结束,那么符号文件会被安装到/usr/lib/debug/目录下,最重要的kernel文件在boot子目录下。
可以使用gdb加载内核文件(相当于把内核当作可执行程序来调试),通过读取其中的变量来确认内核文件的版本,如下图所示。
从vesion字段可以拷打详细的版本信息。从machine字段可以看出内核是64位的。
因为内核调试需要两台机器,所以实际调试时应该在安装有相同版本Ubuntu的调试机器上执行上诉步骤。如果版本不同,那么应该把变量部分(开发代号和版本号)替换成目标机的信息。比如直接执行:
sudo apt-get install linux-image-4.13.0-36-generic-dbgsym
第三个问题是源文件,长话短说,也可以从Ubuntu下载安装,需要3个步骤:
1,打开/etc/apt/sources.list文件,将原本注释掉的deb-src行启用回来,也就是把代表注释的#号去掉。
deb-src http://cn.archive.ubuntu.com/ubuntu/ precise main restricted
2,执行sudo apt-get update。
3,安装源文件:
apt-get source linux-source
准备工作差不多好了,接下来是开始建立会话调试了,web编辑器很不给力,编辑的好费劲,休息一下,我们将在下一篇文章中继续介绍。
[2018/4/3补充]
今日在Ubuntu 16.04(64位)上使用上诉方法下载内核源代码时,出现如下提示:
使用提示中的git命令下载只下载很少的文件后就结束了,后来使用如下命令直接从kernel.ubuntu.com下载可以了
$ git clone git://kernel.ubuntu.com/ubuntu/ubuntu-trusty.git