首页 | 邮件资讯 | 技术教程 | 解决方案 | 产品评测 | 邮件人才 | 邮件博客 | 邮件系统论坛 | 软件下载 | 邮件周刊 | 热点专题 | 工具
网络技术 | 操作系统 | 邮件系统 | 客户端 | 电子邮箱 | 反垃圾邮件 | 邮件安全 | 邮件营销 | 移动电邮 | 邮件软件下载 | 电子书下载

操作系统

Windows 9X | Linux&Uinx | Windows Server | 其它操作系统 | Vista | FreeBSD | Windows 7 |
首页 > 操作系统 > Linux&Uinx > 揭开Linux系统内核调试器的神秘面纱 > 正文

揭开Linux系统内核调试器的神秘面纱

出处:赛迪网技术社区 作者:赛迪网技术社区 时间:2007-5-20 23:06:50

KDB 入门指南

调试内核问题时,能够跟踪内核执行情况并查看其内存和数据结构是非常有用的。Linux 中的内置内 核调试器 KDB 提供了这种功能。在本文中您把了解怎么样使用 KDB 所提供的功能,以及怎么样在 Linux 机器上安装和设置 KDB。您还把熟悉 KDB 中可以使用的命令以及设置和显示选项。

Linux 内核调试器(KDB)允许您调试 Linux 内核。这个恰如其名的工具实质上是内核代码的补丁,它允许高手访问内核内存和数据结构。KDB 的主要优点之一就是它不需要用另一台机器进行调试:您可以调试正在运行的内核。

设置一台用于 KDB 的机器需要花费一些工作,因为需要给内核打补丁并进行重新编译。KDB 的用户应当熟悉 Linux 内核的编译(在一定程度上还要熟悉内核内部机理),但是如果您需要编译内核方面的帮助,请参阅本文结尾处的参考资料一节。

在本文中,我们把从有关下载 KDB 补丁、打补丁、(重新)编译内核以及启动 KDB 方面的信息着手。然后我们把了解 KDB 命令并研究一些较常用的命令。最后,我们把研究一下有关设置和显示选项方面的一些详细信息。

入门

KDB 项目是由 Silicon Graphics 维护的(请参阅参考资料以获取链接),您需要从它的 FTP 站点下载与内核版本有关的补丁。(在编写本文时)可用的最新 KDB 版本是 4.2。您把需要下载并应用两个补丁。

一个是“公共的”补丁,包含了对通用内核代码的更改,另一个是特定于体系结构的补丁。补丁可作为 bz2 文件获取。例如,在运行 2.4.20 内核的 x86 机器上,您会需要 kdb-v4.2-2.4.20-common-1.bz2 和 kdb-v4.2-2.4.20-i386-1.bz2。

这里所提供的所有示例都是针对 i386 体系结构和 2.4.20 内核的。您把需要根据您的机器和内核版本进行适当的更改。您还需要拥有 root 许可权以执行这些操作。

把文件复制到 /usr/src/linux 目录中并从用 bzip2 压缩的文件解压缩补丁文件:

#bzip2 -d kdb-v4.2-2.4.20-common-1.bz2

#bzip2 -d kdb-v4.2-2.4.20-i386-1.bz2

您把获得 kdb-v4.2-2.4.20-common-1 和 kdb-v4.2-2.4-i386-1 文件。

现在,应用这些补丁:

#patch -p1

#patch -p1

这些补丁应该干净利落地加以应用。查找任何以 .rej 结尾的文件。这个扩展名表明这些是失败的补丁。如果内核树没问题,那么补丁的应用就不会有任何问题。

接下来,需要构建内核以支持 KDB。第一步是设置 CONFIG_KDB 选项。使用您喜欢的配置机制(xconfig 和 menuconfig 等)来完成这一步。转到结尾处的“Kernel hacking”部分并选择“Built-in Kernel Debugger support”选项。

您还可以根据自己的偏好选择其它两个选项。选择“Compile the kernel with frame pointers”选项(如果有的话)则设置 CONFIG_FRAME_POINTER 标志。这把产生更好的堆栈回溯,因为帧指针寄存器被用作帧指针而不是通用寄存器。

您还可以选择“KDB off by default”选项。这把设置 CONFIG_KDB_OFF 标志,并且在缺省情况下把关闭 KDB。我们把在后面一节中对此进行详细介绍。

保存配置,然后退出。重新编译内核。建议在构建内核之前执行“make clean”。用常用方式安装内核并引导它。

初始化并设置环境变量

您可以定义把在 KDB 初始化期间执行的 KDB 命令。需要在纯文本文件 kdb_cmds 中定义这些命令,该文件位于 Linux 源代码树(当然是在打了补丁之后)的 KDB 目录中。该文件还可以用来定义设置显示和打印选项的环境变量。文件开头的注释提供了编辑文件方面的帮助。使用这个文件的缺点是,在您更改了文件之后需要重新构建并重新安装内核。

激活 KDB

如果编译期间没有选中 CONFIG_KDB_OFF,那么在缺省情况下 KDB 是活动的。否则,您需要显式地激活它 - 通过在引导期间把 kdb=on 标志传递给内核或者通过在挂装了 /proc 之后执行该工作:

#echo "1" >/proc/sys/kernel/kdb

倒过来执行上述步骤则会取消激活 KDB。也就是说,如果缺省情况下 KDB 是打开的,那么把 kdb=off 标志传递给内核或者执行下面这个操作把会取消激活 KDB:

#echo "0" >/proc/sys/kernel/kdb

我们可以看到 rmqueue() 被 __alloc_pages 调用,后者接下来又被 _alloc_pages 调用,以此类推。

每一帧的第一个双字(double word)指向下一帧,这后面紧跟着调用函数的地址。因此,跟踪堆栈就变成一件轻松的工作了。

go 命令可以有选择地以一个地址作为参数。如果您想在某个特定地址处继续执行,则可以提供该地址作为参数。另一个办法是使用 rm 命令修改指令指针寄存器,然后只要输入 go。如果您想跳过似乎会引起问题的某个特定指令或一组指令,这就会很有用。但是,请注意,该指令使用不慎会造成严重的问题,系统可能会严重崩溃。

您可以利用一个名为 defcmd 的有用命令来定义自己的命令集。例如,每当遇到断点时,您可能希望能同时检查某个特殊变量、检查某些寄存器的内容并转储堆栈。通常,您必须要输入一系列命令,以便能同时执行所有这些工作。defcmd 允许您定义自己的命令,该命令可以包含一个或多个预定义的 KDB 命令。然后只需要用一个命令就可以完成所有这三项工作。其语法如下:

[code:1:6ddc15f4ad][0]kdb> defcmd name "usage" "help"

[0]kdb> [defcmd] type the commands here

[0]kdb> [defcmd] endefcmd [/code:1:6ddc15f4ad]

例如,可以定义一个(简单的)新命令 hari,它显示从地址 0xc000000 开始的一行内存、显示寄存器的内容并转储堆栈:

[code:1:6ddc15f4ad][0]kdb> defcmd hari "" "no arguments needed"

[0]kdb> [defcmd] md 0xc000000 1

[0]kdb> [defcmd] rd

[0]kdb> [defcmd] md %ebp 1

[0]kdb> [defcmd] endefcmd [/code:1:6ddc15f4ad]

该命令的输出会是:

[code:1:6ddc15f4ad][0]kdb> hari

[hari]kdb> md 0xc000000 1

0xc000000 00000001 f000e816 f000e2c3 f000e816

[hari]kdb> rd

eax = 0x00000000 ebx = 0xc0105330 ecx = 0xc0466000 edx = 0xc0466000

....

...

[hari]kdb> md %ebp 1

0xc0467fbc c0467fd0 c01053d2 00000002 000a0200

[0]kdb> [/code:1:6ddc15f4ad]

可以使用 bph 和 bpha 命令(假如体系结构支持使用硬件寄存器)来应用读写断点。这意味着每当从某个特定地址读取数据或将数据写入该地址时,我们都可以对此进行控制。当调试数据/内存毁坏问题时这可能会极其方便,在这种情况中您可以用它来识别毁坏的代码/进程。

示例

[code:1:6ddc15f4ad]每当将四个字节写入地址 0xc0204060 时就进入内核调试器:

[0]kdb> bph 0xc0204060 dataw 4

在读取从 0xc000000 开始的至少两个字节的数据时进入内核调试器:

[0]kdb> bph 0xc000000 datar 2[/code:1:6ddc15f4ad]

[size=18:6ddc15f4ad]结束语[/size:6ddc15f4ad]

对于执行内核调试,KDB 是一个方便的且功能强大的工具。它提供了各种选项,并且使我们能够分析内存内容和数据结构。最妙的是,它不需要用另一台机器来执行调试。

C 语言作为 Linux 系统上标准的编程语言给予了我们对动态内存分配很大的控制权。然而,这种自由可能会导致严重的内存管理问题,而这些问题可能导致程序崩溃或随时间的推移导致性能降级。

内存泄漏(即 malloc() 内存在对应的 free() 调用执行后永不被释放)和缓冲区溢出(例如对以前分配到某数组的内存进行写操作)是一些常见的问题,它们可能很难检测到。这一部分将讨论几个调试工具,它们极大地简化了检测和找出内存问题的过程。

MEMWATCH 由 Johan Lindh 编写,是一个开放源代码 C 语言内存错误检测工具,您可以自己下载它(请参阅本文后面部分的参考资料)。只要在代码中添加一个头文件并在 gcc 语句中定义了 MEMWATCH 之后,您就可以跟踪程序中的内存泄漏和错误了。MEMWATCH 支持 ANSI C,它提供结果日志纪录,能检测双重释放(double-free)、错误释放(erroneous free)、没有释放的内存(unfreed memory)、溢出和下溢等等。

清单 1. 内存样本(test1.c)

[code:1:ff78191c7b]#include

#include

#include "memwatch.h"

int main(void)

{

char *ptr1;

char *ptr2;

ptr1 = malloc(512);

ptr2 = malloc(512);

ptr2 = ptr1;

free(ptr2);

free(ptr1);

}[/code:1:ff78191c7b]

清单 1 中的代码将分配两个 512 字节的内存块,然后指向第一个内存块的指针被设定为指向第二个内存块。结果,第二个内存块的地址丢失,从而产生了内存泄漏。

现在我们编译清单 1 的 memwatch.c。下面是一个 makefile 示例:

test1

[code:1:ff78191c7b]gcc -DMEMWATCH -DMW_STDIO test1.c memwatch c -o test1[/code:1:ff78191c7b]

当您运行 test1 程序后,它会生成一个关于泄漏的内存的报告。清单 2 展示了示例 memwatch.log 输出文件。

清单 2. test1 memwatch.log 文件

[code:1:ff78191c7b]MEMWATCH 2.67 Copyright (C) 1992-1999 Johan Lindh

...

double-free: <4> test1.c(15), 0x80517b4 was freed from test1.c(14)

...

unfreed: <2> test1.c(11), 512 bytes at 0x80519e4

{FE FE FE FE FE FE FE FE FE FE FE FE ..............}

Memory usage statistics (global):

N)umber of allocations made: 2

L)argest memory usage : 1024

T)otal of all alloc() calls: 1024

U)nfreed bytes totals : 512[/code:1:ff78191c7b]

MEMWATCH 为您显示真正导致问题的行。如果您释放一个已经释放过的指针,它会告诉您。对于没有释放的内存也一样。日志结尾部分显示统计信息,包括泄漏了多少内存,使用了多少内存,以及总共分配了多少内存。

[color=blue:ff78191c7b]YAMD[/color:ff78191c7b]

YAMD 软件包由 Nate Eldredge 编写,可以查找 C 和 C++ 中动态的、与内存分配有关的问题。在撰写本文时,YAMD 的最新版本为 0.32。请下载 yamd-0.32.tar.gz(请参阅参考资料)。执行 make 命令来构建程序;然后执行 make install 命令安装程序并设置工具。

一旦您下载了 YAMD 之后,请在 test1.c 上使用它。请删除 #include memwatch.h 并对 makefile 进行如下小小的修改:

使用 YAMD 的 test1

gcc -g test1.c -o test1

清单 3 展示了来自 test1 上的 YAMD 的输出。

清单 3. 使用 YAMD 的 test1 输出

[code:1:ff78191c7b]YAMD version 0.32

Executable: /usr/src/test/yamd-0.32/test1

...

INFO: Normal allocation of this block

Address 0x40025e00, size 512

...

INFO: Normal allocation of this block

Address 0x40028e00, size 512

...

INFO: Normal deallocation of this block

Address 0x40025e00, size 512

...

ERROR: Multiple freeing At

free of pointer already freed

Address 0x40025e00, size 512

...

WARNING: Memory leak

Address 0x40028e00, size 512

WARNING: Total memory leaks:

1 unfreed allocations totaling 512 bytes

*** Finished at Tue ... 10:07:15 2002

Allocated a grand total of 1024 bytes 2 allocations

Average of 512 bytes per allocation

Max bytes allocated at one time: 1024

24 K alloced internally / 12 K mapped now / 8 K max

Virtual program size is 1416 K

End.[/code:1:ff78191c7b]

YAMD 显示我们已经释放了内存,而且存在内存泄漏。让我们在清单 4 中另一个样本程序上试试 YAMD。

清单 4. 内存代码(test2.c)

[code:1:ff78191c7b]#include

#include

int main(void)

{

char *ptr1;

char *ptr2;

char *chptr;

int i = 1;

ptr1 = malloc(512);

ptr2 = malloc(512);

chptr = (char *)malloc(512);

for (i; i <= 512; i++) {

chptr[i] = 'S';

}

ptr2 = ptr1;

free(ptr2);

free(ptr1);

free(chptr);

}[/code:1:ff78191c7b]

您可以使用下面的命令来启动 YAMD:

[code:1:ff78191c7b]./run-yamd /usr/src/test/test2/test2 [/code:1:ff78191c7b]

清单 5 显示了在样本程序 test2 上使用 YAMD 得到的输出。YAMD 告诉我们在 for 循环中有“越界(out-of-bounds)”的情况。

清单 5. 使用 YAMD 的 test2 输出

[code:1:ff78191c7b]Running /usr/src/test/test2/test2

Temp output to /tmp/yamd-out.1243

*********

./run-yamd: line 101: 1248 Segmentation fault (core dumped)

YAMD version 0.32

Starting run: /usr/src/test/test2/test2

Executable: /usr/src/test/test2/test2

Virtual program size is 1380 K

...

INFO: Normal allocation of this block

Address 0x40025e00, size 512

...

INFO: Normal allocation of this block

Address 0x40028e00, size 512

...

INFO: Normal allocation of this block

Address 0x4002be00, size 512

ERROR: Crash

...

Tried to write address 0x4002c000

Seems to be part of this block:

Address 0x4002be00, size 512

...

Address in question is at offset 512 (out of bounds)

Will dump core after checking heap.

Done.[/code:1:ff78191c7b]

MEMWATCH 和 YAMD 都是很有用的调试工具,它们的使用方法有所不同。对于 MEMWATCH,您需要添加包含文件 memwatch.h 并打开两个编译时间标记。对于链接(link)语句,YAMD 只需要 -g 选项。

[color=blue:ff78191c7b]Electric Fence[/color:ff78191c7b]

相关文章 热门文章
  • Linux启动 Sendmail速度慢的解决办法
  • Linux系统下防垃圾邮件基本功能
  • Linux启动sendmail速度慢的解决办法
  • Domino V8 在 UNIX/Linux 平台上的安装及其常见问题
  • IBM Lotus Domino,Linux,虚拟化,可伸缩性:不再是相互排斥的术语
  • 19.11 参 考 资 料
  • 19.10 课 后 练 习
  • 19.9 重 点 回 顾
  • 19.8.3 quota与目录转移
  • 19.8.2 关于备份
  • 19.8.1 问题检查
  • 19.7.8 其他设置技巧
  • linux的基本操作(上)
  • Linux系统下应用知识大荟萃
  • GNU GRUB启动管理器
  • 制作基于软盘的Linux系统
  • 网络配置文件快速解读
  • linux的基本操作(下)
  • 剖析Linux系统启动过程
  • DameWare让局域网管理不再繁琐
  • 在Redhat 9下实现双机热备和集群功能
  • LINUX守护进程介绍
  • Redhat advance server 2.1集群的安装与管理
  • Linux必须学会的60个命令-文件处理
  • 自由广告区
     
    最新软件下载
  • SharePoint Server 2010 部署文档
  • Exchange 2010 RTM升级至SP1 教程
  • Exchange 2010 OWA下RBAC实现的组功能...
  • Lync Server 2010 Standard Edition 标..
  • Lync Server 2010 Enterprise Edition...
  • Forefront Endpoint Protection 2010 ...
  • Lync Server 2010 Edge 服务器部署文档
  • 《Exchange 2003专家指南》
  • Mastering Hyper-V Deployment
  • Windows Server 2008 R2 Hyper-V
  • Microsoft Lync Server 2010 Unleashed
  • Windows Server 2008 R2 Unleashed
  • 今日邮件技术文章
  • 腾讯,在创新中演绎互联网“进化论”
  • 华科人 张小龙 (中国第二代程序员 QQ...
  • 微软推出新功能 提高Hotmail密码安全性
  • 快压技巧分享:秒传邮件超大附件
  • 不容忽视的邮件营销数据分析过程中的算..
  • 国内手机邮箱的现状与未来发展——访尚..
  • 易观数据:2011Q2中国手机邮箱市场收入..
  • 穿越时空的爱恋 QQ邮箱音视频及贺卡邮件
  • Hotmail新功能:“我的朋友可能被黑了”
  • 入侵邻居网络发骚扰邮件 美国男子被重..
  • 网易邮箱莫子睿:《非你莫属》招聘多过..
  • 中国电信推广189邮箱绿色账单
  • 最新专题
  • 鸟哥的Linux私房菜之Mail服务器
  • Exchange Server 2010技术专题
  • Windows 7 技术专题
  • Sendmail 邮件系统配置
  • 组建Exchange 2003邮件系统
  • Windows Server 2008 专题
  • ORF 反垃圾邮件系统
  • Exchange Server 2007 专题
  • ISA Server 2006 教程专题
  • Windows Vista 技术专题
  • “黑莓”(BlackBerry)专题
  • Apache James 专题
  • 分类导航
    邮件新闻资讯:
    IT业界 | 邮件服务器 | 邮件趣闻 | 移动电邮
    电子邮箱 | 反垃圾邮件|邮件客户端|网络安全
    行业数据 | 邮件人物 | 网站公告 | 行业法规
    网络技术:
    邮件原理 | 网络协议 | 网络管理 | 传输介质
    线路接入 | 路由接口 | 邮件存储 | 华为3Com
    CISCO技术 | 网络与服务器硬件
    操作系统:
    Windows 9X | Linux&Uinx | Windows NT
    Windows Vista | FreeBSD | 其它操作系统
    邮件服务器:
    程序与开发 | Exchange | Qmail | Postfix
    Sendmail | MDaemon | Domino | Foxmail
    KerioMail | JavaMail | Winwebmail |James
    Merak&VisNetic | CMailServer | WinMail
    金笛邮件系统 | 其它 |
    反垃圾邮件:
    综述| 客户端反垃圾邮件|服务器端反垃圾邮件
    邮件客户端软件:
    Outlook | Foxmail | DreamMail| KooMail
    The bat | 雷鸟 | Eudora |Becky! |Pegasus
    IncrediMail |其它
    电子邮箱: 个人邮箱 | 企业邮箱 |Gmail
    移动电子邮件:服务器 | 客户端 | 技术前沿
    邮件网络安全:
    软件漏洞 | 安全知识 | 病毒公告 |防火墙
    攻防技术 | 病毒查杀| ISA | 数字签名
    邮件营销:
    Email营销 | 网络营销 | 营销技巧 |营销案例
    邮件人才:招聘 | 职场 | 培训 | 指南 | 职场
    解决方案:
    邮件系统|反垃圾邮件 |安全 |移动电邮 |招标
    产品评测:
    邮件系统 |反垃圾邮件 |邮箱 |安全 |客户端
    广告联系 | 合作联系 | 关于我们 | 联系我们 | 繁體中文
    版权所有:邮件技术资讯网©2003-2010 www.5dmail.net, All Rights Reserved
    www.5Dmail.net Web Team   粤ICP备05009143号