Linux内核实时调试,如何完成以及使用哪些工具?

您所在的位置:网站首页 linux内核崩溃调试工具 Linux内核实时调试,如何完成以及使用哪些工具?

Linux内核实时调试,如何完成以及使用哪些工具?

2023-04-24 09:34| 来源: 网络整理| 查看: 265

在Linux内核上进行实时调试的最常用方法和工具为何? 我知道例如Linus。 反对这种针对Linux内核的调试,或者至少是反对这种调试,因此在那些年里,在这种意义上没有做太多事情,但是老实说,自2000年以来已经过去了很多时间,我很想知道关于Linux的观念是否已改变 项目以及当前使用哪些当前方法在Linux内核上进行实时调试(本地或远程)?

欢迎参考有关所提到的技术和工具的演练和教程。

相关讨论 另请参阅lwn.net/Articles/280912(搜索kgdb) 你活着是什么意思? 您当前正在运行的还是? 还是虚拟机中的一个?

另一种选择是使用ICE / JTAG控制器和GDB。这种"硬件"解决方案特别适用于嵌入式系统,

但例如Qemu提供类似的功能:

用侦听'localhost:1234'的gdb'remote'存根启动qemu:qemu -s ...,

然后使用GDB打开用调试信息编译的内核文件vmlinux(您可以查看此邮件列表线程,他们在其中讨论了内核的未优化)。

连接GDB和Qemu:target remote localhost:1234

查看您的实时内核:

123456(gdb) where #0  cpu_v7_do_idle () at arch/arm/mm/proc-v7.S:77 #1  0xc0029728 in arch_idle () atarm/mach-realview/include/mach/system.h:36 #2  default_idle () at arm/kernel/process.c:166 #3  0xc00298a8 in cpu_idle () at arch/arm/kernel/process.c:199 #4  0xc00089c0 in start_kernel () at init/main.c:713

不幸的是,到目前为止,使用GDB无法进行用户空间调试(没有任务列表信息,没有MMU重新编程以查看不同的进程上下文,...),但是如果留在内核空间中,那将非常方便。

info threads将为您提供不同CPU的列表和状态

编辑:

您可以在此PDF中获取有关该过程的更多详细信息:

Debugging Linux systems using GDB and QEMU.

相关讨论 前段时间,我尝试了类似Qemu技术的工具,它非常酷。

在调试Linux内核时,我们可以利用多种工具,例如调试器(KDB,KGDB),崩溃时转储(LKCD),跟踪工具包(LTT,LTTV,LTTng),自定义内核工具(dprobes,kprobes)。在下一节中,我试图总结其中的大部分内容,希望对您有所帮助。

好。

LKCD(Linux内核崩溃转储)工具允许Linux系统在发生崩溃时写入其内存内容。可以进一步分析这些日志以查找崩溃的根本原因。有关LKCD的资源

好。

http://www-01.ibm.com/support/knowledgecenter/linuxonibm/liaax/lkcd.pdf https://www.novell.com/coolsolutions/feature/15284.html https://www.novell.com/support/kb/doc.php?id=3044267

好。

糟糕,当内核检测到问题时,它会打印一条糟糕的消息。这样的消息是由故障处理程序(arch / * / kernel / traps.c)中的printk语句生成的。 printk语句使用的内核中的专用环形缓冲区。 Oops包含以下信息:发生Oops的CPU,CPU寄存器的内容,Oops的数量,描述,堆栈回溯跟踪等。有关内核Oop的资源

好。

https://www.kernel.org/doc/Documentation/oops-tracing.txt http://madwifi-project.org/wiki/DevDocs/KernelOops https://wiki.ubuntu.com/DebuggingKernelOops

好。

Dynamic Probes是IBM开发的流行的Linux调试工具之一。该工具允许在用户和内核空间中的几乎任何位置放置"探针"。该探针由一些代码(用专用的,面向堆栈的语言编写)组成,这些代码在控件到达给定点时执行。下面列出了有关动态探针的资源

好。

http://www-01.ibm.com/support/knowledgecenter/linuxonibm/liaax/dprobesltt.pdf http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.107.6212&rep=rep1&type=pdf

好。

Linux Trace Toolkit是一个内核修补程序和一组相关的实用程序,允许跟踪内核中的事件。跟踪包括时序信息,并且可以创建给定时间段内发生的事情的合理完整的图片。 LTT,LTT Viewer和下一代LTT的资源

好。

http://elinux.org/Linux_Trace_Toolkit http://www.linuxjournal.com/article/3829 http://multivax.blogspot.com/2010/11/introduction-to-linux-tracing-toolkit.html

好。

MEMWATCH是一种开源内存错误检测工具。它通过在gcc语句中定义MEMWATCH并将标题文件添加到我们的代码中来工作。通过这种方式,我们可以跟踪内存泄漏和内存损坏。有关MEMWATCH的资源

好。

http://www.linuxjournal.com/article/6059

好。

ftrace是Linux内核的良好跟踪框架。 ftrace跟踪内核的内部操作。该工具包含在2.6.27的Linux内核中。借助其各种跟踪器插件,ftrace可以针对不同的静态跟踪点,例如调度事件,中断,内存映射的I / O,CPU电源状态转换以及与文件系统和虚拟化相关的操作。此外,还提供对内核函数调用的动态跟踪,可以选择使用glob将其限制为函数的子集,并且可以生成调用图并提供堆栈使用情况。您可以在https://events.linuxfoundation.org/slides/2010/linuxcon_japan/linuxcon_jp2010_rostedt.pdf上找到有关ftrace的很好的教程。

好。

ltrace是Linux中的调试实用程序,用于显示用户空间应用程序对共享库的调用。该工具可用于跟踪任何动态库函数调用。它截获并记录由执行的过程调用的动态库调用以及该过程接收的信号。它还可以拦截并打印程序执行的系统调用。

好。

Getting started with ltrace: how does it do that?

http://developerblog.redhat.com/2014/07/10/ltrace-for-rhel-6-and-7/

好。

KDB是Linux内核的内核内调试器。 KDB遵循简单的shell风格的界面。我们可以使用它来检查内存,寄存器,进程列表,dmesg,甚至设置断点以停止在某个位置。通过KDB,我们可以设置断点并执行一些基本的内核运行控制(尽管KDB不是源级调试器)。有关KDB的一些方便资源

好。

http://www.drdobbs.com/open-source/linux-kernel-debugging/184406318 http://elinux.org/KDB http://dev.man-online.org/man1/kdb/ https://www.kernel.org/pub/linux/kernel/people/jwessel/kdb/usingKDB.html

好。

KGDB旨在用作Linux内核的源代码级调试器。它与gdb一起用于调试Linux内核。使用kgdb需要两台机器。其中一台机器是开发机器,另一台是目标机器。要调试的内核在目标计算机上运行。期望gdb可用于"侵入"内核以检查内存,变量并查看调用堆栈信息,类似于应用程序开发人员使用gdb调试应用程序的方式。可以在内核代码中放置断点并执行一些有限的执行步骤。有关KGDB的一些方便资源

好。

http://landley.net/kdocs/Documentation/DocBook/xhtml-nochunks/kgdb.html

好。

好。

根据Wiki,kgdb在最近几年内已合并到2.6.26的内核中。 kgdb是一个远程调试器,因此您可以在内核中激活它,然后以某种方式将gdb附加到它。我以某种方式说,因为似乎有很多选择-请参见连接gdb。鉴于kgdb现在位于源代码树中,我想说这就是您要使用的东西。

因此,看起来Linus屈服了。但是,我要强调他的观点-您应该知道自己在做什么,并且对系统非常了解。这是核心土地。如果出了什么问题,您就不会得到segfault,从后来的一些晦涩的问题到整个系统崩溃,您都不会得到任何收益。这是龙。继续小心,您已被警告。

相关讨论 我从Mark Shuttleworth(Canonical的创始人)那里偷了一个。 markshuttleworth.com。 在我看来,Linus非常有用。要考虑的另一件事是,某些错误可能会以微妙的方式破坏kgdb-您可以信任它吗:) @mpe我同意。工具也有错误。我认为他的意思是,如果您只能依靠该工具来告诉您错误的时间进行开发,那就是一个问题-您还需要理解该工具,并学会根据自己的知识来解释其输出。对上述工具的盲目信任会导致细微的错误。 如果您要编写内核代码,则确实需要无需调试器就能理解代码。如果可以,那么调试器也许是一个很好的工具,但是它不能替代基本的代码理解能力。 任何工具都无法取代基本的代码理解。那就是我的意思。如果您所做的只是依靠工具告诉您什么时候错了,那是一个问题,因为工具不能总是告诉您正确的事情,有时是因为工具不能告诉您(我想到的是valgrind /微妙的内存错误-他们告诉您有错误,当然,但是它们很难确定在哪里),有时是因为它们本身就有错误-如您所说,内核中的错误可能会影响kgdb输出。它的结构和内存不比您尝试调试的要好。因此,这里是龙。 我不了解Linux社区对内核调试的敌意。我想使用内核调试器来了解系统以及调试问题。如果可以使用printk()进行调试(或获得代码理解),则可以归纳其OK以使用真正的调试器。 printk()只是实现断点和变量监视的效率极低的方法(它只是一种调试技术,需要完整的编译/重新引导周期才能设置新的断点或监视)。

另一个用于"实时"调试的好工具是kprobes /动态探测器。

这使您可以动态地构建一些小的模块,这些模块在执行某些地址时便会运行-有点像断点。

它们的最大优点是:

它们不会影响系统-即当命中某个位置时-它只会执行代码-不会停止整个内核。 您不需要像kgdb那样互连两个不同的系统(目标和调试)

最好执行诸如达到断点,查看数据值或检查事物是否已更改/覆盖等操作。如果要"单步执行代码",则不这样做。

增加-2018年:

另一个非常强大的方法是一个简单地称为" perf"的程序,该程序可以汇总许多工具(例如动态探针),并且可以替换/贬低其他工具(例如oprofile)。

特别是,perf probe命令可用于轻松创建动态探针/向系统添加动态探针,然后perf record可以对系统进行采样并在探针被命中以通过perf report报告时报告信息(和回溯)(或perf script)。如果您在内核中具有良好的调试符号,则即使不关闭内核,也可以从系统中获得出色的信息。进行man perf(在Google或您的系统上)以获取有关此工具的更多信息,或在其上查看以下出色的页面:

http://www.brendangregg.com/perf.html

KGDB + QEMU逐步

KGDB是内核子系统,允许您从主机GDB逐步调试内核本身。

我的QEMU + Buildroot示例是在没有实际硬件的情况下品尝它的好方法:https://github.com/cirosantilli/linux-kernel-module-cheat/tree/1969cd6f8d30dace81d9848c6bacbb8bad9dacd8#kgdb

优缺点与其他方法:

与QEMU的优势: 您通常没有为您的设备提供软件仿真,因为硬件供应商不喜欢为其设备发布准确的软件模型 真正的硬件方式比QEMU更快 与JTAG相比的优势:无需额外的JTAG硬件,易于设置 与QEMU和JTAG相比的缺点:可见性较低,更具侵入性。 KGDB依赖于内核的某些部分才能与主机进行通信。所以例如它崩溃时崩溃了,您无法查看启动顺序。

主要步骤是:

使用以下命令编译内核:

12345678910111213141516CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_INFO=y CONFIG_CONSOLE_POLL=y CONFIG_KDB_CONTINUE_CATASTROPHIC=0 CONFIG_KDB_DEFAULT_ENABLE=0x1 CONFIG_KDB_KEYBOARD=y CONFIG_KGDB=y CONFIG_KGDB_KDB=y CONFIG_KGDB_LOW_LEVEL_TRAP=y CONFIG_KGDB_SERIAL_CONSOLE=y CONFIG_KGDB_TESTS=y CONFIG_KGDB_TESTS_ON_BOOT=n CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 CONFIG_SERIAL_KGDB_NMI=n

其中大多数不是强制性的,但这是我测试过的。

添加到您的QEMU命令:

12-append 'kgdbwait kgdboc=ttyS0,115200' \ -serial tcp::1234,server,nowait

使用以下命令从Linux内核源树的根目录运行GDB:

1gdb -ex 'file vmlinux' -ex 'target remote localhost:1234'

在GDB中:

1(gdb) c

并且启动应该完成。

在QEMU中:

1echo g > /proc/sysrq-trigger

GDB应该崩溃了。

现在我们完成了,您可以照常使用GDB:

12b sys_write c

在Ubuntu 14.04中测试。

KGDB +树莓派

与上面完全相同的设置几乎可以在Raspberry Pi 2,Raspbian Jessie 2016-05-27上运行。

您只需要学习在Pi上执行QEMU步骤即可,这很容易 可谷歌搜索:

按照https://www.raspberrypi.org/documentation/linux/kernel/building.md的说明添加配置选项并重新编译内核。不幸的是,默认内核构建中缺少选项,尤其是没有调试符号,因此重新编译是需要。

编辑引导分区的cmdline.txt并添加:

1kgdbwait kgdboc=ttyAMA0,115200

使用以下命令将gdb连接到串行:

1arm-linux-gnueabihf-gdb -ex 'file vmlinux' -ex 'target remote /dev/ttyUSB0'

如果您不熟悉该序列号,请查看以下内容:https://www.youtube.com/watch?v=da5Q7xL_OTo您只需要一个像这样的便宜适配器即可。在尝试KGDB之前,请确保您可以通过序列获得Shell以确保其正常工作。

做:

1echo g | sudo tee /proc/sysrq-trigger

从SSH会话内部进行,因为串行已由GDB进行。

通过此设置,我能够在sys_write中放置一个断点,暂停程序执行,列出源并继续。

但是,有时当我在sys_write中执行next时,GDB只是挂起并多次打印此错误消息:

1Ignoring packet error, continuing...

因此,我不确定我的设置是否有问题,还是因为某些后台进程在更复杂的Raspbian图像中正在执行操作而导致出现这种情况。

还告诉我尝试使用Linux引导选项禁用多处理,但是我还没有尝试过。

实际上,笑话是Linux自2.2.12起具有一个内核内调试器,即xmon,但仅适用于powerpc体系结构(实际上,当时是ppc)。

它不是源代码级调试器,并且几乎完全没有文档记录,但仍然如此。

http://lxr.linux.no/linux-old+v2.2.12/arch/ppc/xmon/xmon.c#L119

相关讨论 " kdb"与" xmon"的x86等效。

在Ubuntu 16.10主机上测试了QEMU + GDB分步过程

为了快速从头开始,我在以下位置制作了一个最小的全自动QEMU + Buildroot示例:https://github.com/cirosantilli/linux-kernel-module-cheat下面介绍了主要步骤。

首先获取根文件系统rootfs.cpio.gz。如果您需要一个,请考虑:

最小的init唯一可执行映像:https://unix.stackexchange.com/questions/122717/custom-linux-distro-that-runs-just-one-program-nothing-else/238579#238579 一个Busybox交互式系统:https://unix.stackexchange.com/questions/2692/what-is-the-smallest-possible-linux-implementation/203902#203902

然后在Linux内核上:

123456789101112git checkout v4.9 make mrproper make x86_64_defconfig cat "内核黑客"->"编译时检查和编译器选项"->"使用调试信息编译内核" 那不是内核的问题,而是由充分优化的编译器生成的任何程序。没错,没有优化就很难轻松构建Linux内核,但是您可以启用CONFIG_READABLE_ASM。 CONFIG_READABLE_ASM给您带来虚假的希望。因为-O2并且在跟踪时您仍然看到乱码,所以可以进行指令重新排序。我发现的唯一解决方案是在构建系统没有抱怨的任何地方设置-O0,再加上一些黑客手段。然后使用qemu进行调试。我可以看到音调是从哪里来的:) 没有任何-O0确实可以吸收stackoverflow.com/questions/29151235/,但是至少它可以使您了解调用了什么函数。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3