Linux Kernel Debugging
- 格式:pdf
- 大小:64.61 KB
- 文档页数:19
Linux内核调试⽅法总结之反汇编Linux反汇编调试⽅法Linux内核模块或者应⽤程序经常因为各种各样的原因⽽崩溃,⼀般情况下都会打印函数调⽤栈信息,那么,这种情况下,我们怎么去定位问题呢?本⽂档介绍了⼀种反汇编的⽅法辅助定位此类问题。
代码⽰例如下:#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <execinfo.h>#include <fcntl.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#define PRINT_DEBUG#define MAX_BACKTRACE_LEVEL 10#define BACKTRACE_LOG_NAME "backtrace.log"static void show_reason(int sig, siginfo_t *info, void *secret){void *array[MAX_BACKTRACE_LEVEL];size_t size;#ifdef PRINT_DEBUGchar **strings;size_t i;size = backtrace(array, MAX_BACKTRACE_LEVEL);strings = backtrace_symbols(array, size);printf("Obtain %zd stack frames.\n", size);for(i = 0; i < size; i++)printf("%s\n", strings[i]);free(strings);#elseint fd = open(BACKSTRACE_LOG_NAME, O_CREAT | O_WRONLY);size = backtrace(array, MAX_BACKTRACE_LEVEL);backtrace_symbols_fd(array, size, fd);close(fd);#endifexit(0);}void die() {char *str1;char *str2;char *str3;char *str4 = NULL;strcpy(str4, "ab");}void let_it_die() {die();}int main(int argc, char **argv){struct sigaction act;act.sa_sigaction = show_reason;sigemptyset(&act.sa_mask);act.sa_flags = SA_RESTART | SA_SIGINFO;sigaction(SIGSEGV, &act, NULL);sigaction(SIGUSR1, &act, NULL);sigaction(SIGFPE, &act, NULL);sigaction(SIGILL, &act, NULL);sigaction(SIGBUS, &act, NULL);sigaction(SIGABRT, &act, NULL);sigaction(SIGSYS, &act, NULL);let_it_die();return 0;}在该⽰例中,我们通过⾃定义的信号处理函数,在程序异常时通过调⽤backtrace()和backtrace_symbols()函数获取并打印函数调⽤栈信息。
在 Linux 系统中,内核堆栈(kernel stack)用于执行内核代码。
当发生操作系统内核崩溃、内核出现异常或需要调试时,理解和分析内核堆栈十分重要。
以下是分析 Linux 内核堆栈的常用方法:使用dmesg:当内核发生故障时,错误信息和堆栈追踪通常会输出到内核日志。
你可以使用 dmesg 命令查看内核日志中的堆栈追踪。
dmesg | grep -i stack操作系统崩溃时的系统日志:有时通过分析内核崩溃时的系统日志(如/var/log/syslog 或/var/log/messages、/var/log/kern.log)也可以找到有关堆栈信息。
使用 dump_stack() 函数:在内核代码中,你可以使用 dump_stack() 函数打印当前线程的堆栈信息。
这在调试内核代码时非常有用。
系统核心转储(Core Dump):内核崩溃时,操作系统有时会生成系统核心转储文件。
你可以使用 GNU Debugger(GDB)来分析内核转储文件。
首先,安装 Linux 的调试符号表(debugging symbols),然后使用 gdb 命令加载符号表和内核转储文件,最后使用 bt(backtrace)命令查看堆栈追踪。
gdb path/to/vmlinux path/to/core_dump(gdb) bt请注意,要使内核生成核心转储文件,需要正确配置内核。
具体配置方法取决于你所使用的 Linux 发行版。
内核调试器(如 KGDB 和 KDB):如果你正在研究内核问题,可以使用内核调试器 KGDB 或 KDB。
KGDB 是基于 GDB 的内核调试器,可以在源代码级别进行调试。
KDB 则是一个基于文本的内核调试器。
使用这些工具,你可以从内核级别设置断点、单步执行代码、检查内存内容和调用堆栈等。
通过以上方法可以帮助你分析 Linux 内核堆栈。
如何选择最佳方法取决于你的具体需求和问题。
在进行内核调试之前,请确保熟悉 Linux 操作系统和内核开发的基本知识。
Linux调试⼯具1. 使⽤printf调试#ifdef DEBUGPrintf(“valriable x has value = %d\n”, x)#endif然后在编译选项中加⼊-DDEBUG更复杂的调试应⽤如:#define BASIC_DEBUG 1#define EXTRA_DEBUG 2#define SUPER_DEBUG 4#if (DEBUG &EXTRA_DEBUG)printf …#endif在这种情况下如果设置编译器标志为-DDEBUG=5,将启⽤BASIC_DEBUG和SUPER_DEBUG。
标志-DDEBUG=0将禁⽤所有的调试信息,也可以在程序中添加如下语句:#ifndef DEBUG#define DEBUG 0#endif2.使⽤gdb调试Gcc编译的时候要加上-g选项,让编译器在程序中添加额外的调试信息。
如果正式发布,这些调试信息可以使⽤strip命令删除。
Gdb:Backtrace栈跟踪3. 程序静态分析⼯具splintsplint功能:常识性测试并产⽣⼀些警告信息。
它可以检测未经赋值的变量使⽤,函数的参数未使⽤等异常情况。
4. 程序执⾏性能分析⼯具prof/gprof显⽰执⾏所花费的时间具体都⽤在什么操作上。
5. 内存调试ElectricFence函数库和valgrind可以⽤来检查动态内存分配的⼀些问题,包括内存泄漏。
Linux下的调试⼯具随着XP的流⾏,⼈们越来越注重软件的前期设计、后期的实现,以及贯穿于其中的测试⼯作,经过这个过程出来的⾃然是⾼质量的软件。
甚⾄有⼈声称XP会淘汰调试器!这当然是有⼀定道理的,然⽽就⽬前的现实来看,这还是⼀种理想。
在⽇常⼯作中,调试⼯具还是必不可少的。
在Linux下,调试⼯具并⾮只有gdb,还有很多其它调试⼯具,它们都各有所长,侧重⽅⾯也有所不同。
本⽂介绍⼏种笔者常⽤的调试⼯具:1. mtrace在linux下开发应⽤程序,⽤C/C++语⾔的居多。
序言由于开发环境需要在linux-2.6内核上进行,于是准备对我的虚拟机上的Linux系统升级。
没想到这一弄就花了两天时间(反复装系统,辛苦啊~~),总算把Linux系统从2.4.20-8内核成功升级到了2.6.18内核。
网上虽然有很多介绍Linux内核升级的文章,不过要么过时,下载链接失效;要么表达不清,不知所云;更可气的是很多文章在转载过程中命令行都有错误。
刚开始我就是在这些“攻略”的指点下来升级的,以致于浪费了很多时间。
现在,费尽周折,升级成功,心情很爽,趁性也来写个“升级攻略”吧!于是特意又在虚拟机上重新安装一个Linux系统,再来一次完美的升级,边升级边记录这些步骤,写成一篇Linux内核升级记实录(可不是回忆录啊!),和大家一起分享~~!一、准备工作首先说明,下面带#号的行都是要输入的命令行,且本文提到的所有命令行都在终端里输入。
启动Linux系统,并用根用户登录,进入终端模式下。
1、查看Linux内核版本# uname -a如果屏幕显示的是2.6.x,说明你的已经是2.6的内核,也用不着看下文了,该干什么干什么去吧!~~~如果显示的是2.4.x,那恭喜你,闯关通过,赶快进行下一步。
2、下载2.6内核源码下载地址:/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz23、下载内核升级工具(1)下载module-init-tools-3.2.tar.bz2/pub/linux/utils/kernel/module-init-tools/module-init-tools-3.2.tar.bz2(2)下载mkinitrd-4.1.18-2.i386.rpm/fedora/linux/3/i386/RPMS.core/mkinitrd-4.1.18-2.i386.rpm(3)下载lvm2-2.00.25-1.01.i386.rpm/fedora/linux/3/i386/RPMS.core/lvm2-2.00.25-1.01.i386.rpm(4)下载device-mapper-1.00.19-2.i386.rpm/fedora/linux/3/i386/RPMS.core/device-mapper-1.00.19-2.i386.rpm(2.6.18内核和这4个升级工具我都有备份,如果以上下载地址失效,请到/guestbook留下你的邮箱,我给你发过去)好啦,2.6内核和4个升级工具都下载完了(少一个也不行,如果没有下载齐全,请不要尝试下面的步骤,升级是不会成功的),下面回到Linux系统中开始配置工作吧。
序言由于开发环境需要在linux-2.6内核上进行,于是准备对我的虚拟机上的Linux系统升级。
没想到这一弄就花了两天时间(反复装系统,辛苦啊~~),总算把Linux系统从2.4.20-8内核成功升级到了2.6.18内核。
网上虽然有很多介绍Linux内核升级的文章,不过要么过时,下载链接失效;要么表达不清,不知所云;更可气的是很多文章在转载过程中命令行都有错误。
刚开始我就是在这些“攻略”的指点下来升级的,以致于浪费了很多时间。
现在,费尽周折,升级成功,心情很爽,趁性也来写个“升级攻略”吧!于是特意又在虚拟机上重新安装一个Linux系统,再来一次完美的升级,边升级边记录这些步骤,写成一篇Linux内核升级记实录(可不是回忆录啊!),和大家一起分享~~!一、准备工作首先说明,下面带#号的行都是要输入的命令行,且本文提到的所有命令行都在终端里输入。
启动Linux系统,并用根用户登录,进入终端模式下。
1、查看Linux内核版本# uname -a如果屏幕显示的是2.6.x,说明你的已经是2.6的内核,也用不着看下文了,该干什么干什么去吧!~~~如果显示的是2.4.x,那恭喜你,闯关通过,赶快进行下一步。
2、下载2.6内核源码下载地址:/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz23、下载内核升级工具(1)下载module-init-tools-3.2.tar.bz2/pub/linux/utils/kernel/module-init-tools/module-init-tools-3.2.tar.bz2(2)下载mkinitrd-4.1.18-2.i386.rpm/fedora/linux/3/i386/RPMS.core/mkinitrd-4.1.18-2.i386.rpm(3)下载lvm2-2.00.25-1.01.i386.rpm/fedora/linux/3/i386/RPMS.core/lvm2-2.00.25-1.01.i386.rpm(4)下载device-mapper-1.00.19-2.i386.rpm/fedora/linux/3/i386/RPMS.core/device-mapper-1.00.19-2.i386.rpm(2.6.18内核和这4个升级工具我都有备份,如果以上下载地址失效,请到/guestbook留下你的邮箱,我给你发过去)好啦,2.6内核和4个升级工具都下载完了(少一个也不行,如果没有下载齐全,请不要尝试下面的步骤,升级是不会成功的),下面回到Linux系统中开始配置工作吧。
linux内核启用参数Linux内核启用参数是指在Linux系统启动时,可以通过设置参数来改变内核的行为和配置。
这些参数可以通过修改启动脚本或者在引导时通过命令行参数传递给内核。
我们来介绍一些常用的Linux内核启用参数。
1. root:指定根文件系统所在的设备或分区。
在启动时,内核会将根文件系统挂载到这个设备上,成为系统的根目录。
可以使用设备名称(如/dev/sda1)或者UUID(Universally Unique Identifier)来指定。
2. init:指定系统初始化进程的路径。
这个进程是系统启动后的第一个用户空间进程,负责初始化系统环境、启动其他进程等。
一般情况下,它的路径是/bin/init。
3. quiet:禁用内核启动时的冗长输出信息。
默认情况下,内核会将启动过程中的详细信息输出到控制台上,使用quiet参数可以减少这些输出,使启动过程更加简洁。
4. vga:指定启动时的图形模式。
可以通过设置不同的参数值来改变显示分辨率和颜色深度。
例如,vga=791表示使用1024x768分辨率,颜色深度为16位。
5. acpi:启用或禁用ACPI(Advanced Configuration and PowerInterface)功能。
ACPI是一种能够管理电源、温度、风扇等硬件的标准,通过设置acpi参数,可以控制是否启用ACPI功能。
6. noapic:禁用APIC(Advanced Programmable Interrupt Controller)功能。
APIC是用于处理系统中断的硬件设备,通过设置noapic参数,可以禁用APIC功能,解决一些不兼容的硬件问题。
7. nomodeset:禁用内核对图形模式的自动设置。
有些显卡驱动在启动时可能会导致系统冻结或无法启动,通过设置nomodeset参数,可以强制内核使用基本的VGA模式运行。
8. mem:指定系统可用的物理内存大小。
Uncompressing Linux...done, booting the kernel解决办法u-boot是好的,是刚移植成功的,用其他的内核跑过没问题。
所以皇莡-boot传参有问题,问题就是出在我移植的内核上面。
我用的是mini2440的配置,linux2.6.35的内核。
网上找了很多资料试了都没有,开了CONFIG_DEBUG_LL(这个选项是在Kernel hacking里面,需要你打开Kernel low-level debugging functions & Kernel Low-level debugging message via S3C UART)本来想看下出错信息的,加了之后连Uncompressing Linux...done, booting the kernel都没有了。
悲剧。
后来没办法,只能设死循环调试。
后来发现在bl__lookup_machine_type 这条语句(在arch/arm/kernel/head.S中) 执行之后返回的r5寄存器一直是0. 由此可以推测我的MACHINE_TYPE肯定出问题了。
去arch/arm/mach-s3c2440/mach-mini2440.c 查看下面这个结构体:MACHINE_START(MINI2440, "MINI2440")/* Maintainer: Michel Pollet <buserror@> */ .phys_io = S3C2410_PA_UART,.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,.boot_params = S3C2410_SDRAM_PA + 0x100,.map_io = mini2440_map_io,.init_machine = mini2440_init,.init_irq = s3c24xx_init_irq,.timer = &s3c24xx_timer,MACHINE_END问题就是出在第一行的MINI2440,因为这个宏定义扩展之后的machine type 就成了MACHINE_TYPE_MINI2440, 而我在u-boot定义的是MACHINE_TYPE_S3C2440,因此不匹配导致内核不识别死在这里了。
kernel debug级别(实用版)目录1.Kernel Debug 级别的含义2.Kernel Debug 级别的作用3.如何设置 Kernel Debug 级别4.Kernel Debug 级别的应用实例正文【1.Kernel Debug 级别的含义】Kernel Debug 级别是指 Linux 内核中的一种调试级别,用于控制内核在运行时输出调试信息的详细程度。
这个级别可以设置为 0-5 共 6 个等级,其中 0 级表示不输出任何调试信息,5 级表示输出最详细的调试信息。
【2.Kernel Debug 级别的作用】Kernel Debug 级别的主要作用是方便开发者和系统管理员调试内核,找出系统中可能存在的问题。
通过调整 Kernel Debug 级别,可以控制输出的调试信息的详细程度,从而在解决问题时提供不同程度的帮助。
【3.如何设置 Kernel Debug 级别】要设置 Kernel Debug 级别,可以使用以下命令:```echo <debug_level> > /proc/sys/kernel/debug```其中,`<debug_level>`表示要设置的调试级别,取值范围为 0-5。
例如,要将 Kernel Debug 级别设置为 3,可以使用以下命令:```echo 3 > /proc/sys/kernel/debug```【4.Kernel Debug 级别的应用实例】Kernel Debug 级别在实际应用中可以帮助我们排查系统问题。
例如,当系统出现频繁卡顿的现象时,我们可以通过将 Kernel Debug 级别设置为较高级别,以便查看内核的运行状态,找出可能的性能瓶颈。
在找到问题后,可以将 Kernel Debug 级别调回较低级别,以提高系统性能。
总之,Kernel Debug 级别是 Linux 内核中的一种调试工具,可以帮助我们更好地了解系统的运行状态,找出并解决问题。
kernel debug级别摘要:1.介绍kernel debug 级别的概念和作用2.kernel debug 级别的设置方法和技巧3.kernel debug 级别的使用案例和注意事项4.kernel debug 级别的优缺点分析正文:1.介绍kernel debug 级别的概念和作用在Linux 系统中,kernel debug 级别是一种用于控制内核调试信息输出的机制。
通过调整kernel debug 级别,可以控制内核打印哪些调试信息,从而帮助开发者调试内核代码和驱动程序。
kernel debug 级别分为以下几个级别:- KERN_DEBUG:输出内核调试信息。
- KERN_INFO:输出内核信息。
- KERN_WARNING:输出内核警告信息。
- KERN_ERROR:输出内核错误信息。
- KERN_CRIT:输出内核严重错误信息。
2.kernel debug 级别的设置方法和技巧要设置kernel debug 级别,可以使用以下方法:- 在内核配置文件(通常位于/usr/src/linux/.config)中修改相应的选项。
例如,要开启KERN_DEBUG级别,需要将CONFIG_KERNEL_DEBUG设置为Y。
- 在编译内核时,使用make 命令添加debug 选项。
例如,要开启KERN_DEBUG 级别,可以使用make KERN_DEBUG=y 命令。
- 在运行时,通过echo 命令修改/proc/sys/kernel/debug 字符串。
例如,要开启KERN_DEBUG 级别,可以使用echo "KERN_DEBUG" >/proc/sys/kernel/debug命令。
3.kernel debug 级别的使用案例和注意事项在使用kernel debug 级别时,需要注意以下几点:- 合理选择debug 级别。
过高的debug 级别可能导致系统性能下降,而过低的debug 级别可能无法提供足够的调试信息。