LINUX 内核调试基础+编程基础
http://blog.chinaunix.net/uid-20564848-id-73208.html
内核文档:
[root@localhost Documentation]# pwd
/usr/src/kernels/linux-2.6./Documentation
[root@localhost Documentation]# ls
-INDEX i2o parport.txt
ABI ia64 PCI
accounting ics932s401 pcmcia
acpi ide pi-futex.txt
aoe infiniband pnp.txt
applying-patches.txt initrd.txt power
arm input powerpc
atomic_ops.txt Intel-IOMMU.txt pps
auxdisplay intel_txt.txt prctl
bad_memory.txt ioctl preempt-locking.txt
basic_profiling.txt io-mapping.txt printk-formats.txt
binfmt_misc.txt IO-mapping.txt prio_tree.txt
blackfin io_ordering.txt rbtree.txt
block iostats.txt RCU
blockdev IPMI.txt rfkill.txt
braille-console.txt IRQ-affinity.txt robust-futex-ABI.txt
bt8xxgpio.txt irqflags-tracing.txt robust-futexes.txt
btmrvl.txt IRQ.txt rtc.txt
BUG-HUNTING isapnp.txt rt-mutex-design.txt
c2port.txt isdn rt-mutex.txt
cachetlb.txt ja_JP s390
cdrom java.txt SAK.txt
cgroups kbuild scheduler
Changes kdump scsi
CodingStyle kernel-doc-nano-HOWTO.txt SecurityBugs
connector kernel-docs.txt SELinux.txt
console kernel-parameters.txt serial
cpu-freq keys-request-key.txt serial-console.txt
cpu-hotplug.txt keys.txt sgi-ioc4.txt
cpuidle kmemcheck.txt sgi-visws.txt
cpu-load.txt kmemleak.txt sh
cputopology.txt kobject.txt slow-work.txt
credentials.txt ko_KR SM501.txt
cris kprobes.txt Smack.txt
crypto kref.txt sound
dcdbas.txt kvm sparc
debugging-modules.txt laptops sparse.txt
debugging-via-ohci1394.txt ldm.txt spi
dell_rbu.txt leds-class.txt spinlocks.txt
development-process leds-lp3944.txt stable_api_nonsense.txt
device-mapper lguest stable_kernel_rules.txt
devices.txt local_ops.txt SubmitChecklist
DMA-API.txt lockdep-design.txt SubmittingDrivers
DMA-attributes.txt lockstat.txt SubmittingPatches
dmaengine.txt logo.gif svga.txt
DMA-ISA-LPC.txt logo.txt sysctl
DMA-mapping.txt m68k sysfs-rules.txt
DocBook magic-number.txt sysrq.txt
dontdiff make telephony
driver-model Makefile thermal
dvb ManagementStyle timers
dynamic-debug-howto.txt mca.txt tomoyo.txt
early-userspace md.txt trace
edac.txt memory-barriers.txt uml
eisa.txt memory-hotplug.txt unaligned-memory-access.txt
email-clients.txt memory.txt unicode.txt
fault-injection mips unshare.txt
fb misc-devices usb
feature-removal-schedule.txt mn10300 vgaarbiter.txt
filesystems mono.txt VGA-softcursor.txt
firmware_class mtd video4linux
flexible-arrays.txt mutex-design.txt video-output.txt
frv namespaces vm
futex-requeue-pi.txt netlabel volatile-considered-harmful.txt
gcov.txt networking voyager.txt
gpio.txt nmi_watchdog.txt w1
highuid.txt nommu-mmap.txt watchdog
HOWTO numastat.txt wimax
hwmon oops-tracing.txt x86
hw_random.txt parisc zh_CN
i2c parport-lowlevel.txt zorro.txt
内核书籍: LDK:LINUX内核设计与实现 ULK:深入理解LINUX内核 LDD:LINUX 设备驱动程序 LVMM:深入理解LINUX 虚拟内存管理 深入理解LINUX网络内幕
内核社区: http://vger.kernel.org/vger-lists.html#linux-kernel http://dir.gmane.org/gmane.linux.usb.general https://www.kernel.org/ http://linux.chinaunix.net/
printk小结 printk 消息级别定义 #define KERN_EMERG "<0>" /*紧急事件,一般是系统崩溃之前的提示消息*/
#define KERN_ALERT "<1>" /*必须立即采取行动*/
#define KERN_CRIT "<2>" /*临界状态,通常涉及严重的硬件或者软件操作失败*/
#define KERN_ERR "<3>" /*用于报告错误状态,设备驱动会经常使用KERN_ERR来报告硬件错误*/
#define KERN_WARNING "<4>" /*对可能出现问题的情况进行警告,这类情况通常不会对系统造成严重问题 */
#define KERN_NOTICE "<5>" /*有必要进行提示的正常情形,许多与安全相关的状况用这个级别进行汇报*/
#define KERN_INFO "<6>" /*内核提示性信息,很多驱动程序在启动的时候以这个级别打印找到的硬件信息*/
#define KERN_DEBUG "<7>" /*用于调试信息*/ 使用方法
printk(KERN_ALERT "XXXXXX",XXXX);
/proc/sys/kernel/printk
该文件可以调节printk的输出等级,文件中有四个数字值。
() 控制台日志级别:优先级高于该值的消息将被打印至控制台。
() 默认的消息日志级别:用该优先级来打印未定义优先级的消息。
() 最低的控制台日志级别:控制台日志界别可被设置的最小值。
() 默认的控制台日志级别:控制台日志级别的默认值。
通过如下命令可以使得Linux内核的任何printk都被输出到控制台
#echo > /proc/sys/kernel/printk 5. cat /proc/kmsg
这个文件用于检索用printk生成的内核消息。任何时刻只能有一个具有超级用户权限的进程可以读取这个文件。也可以用系统调用syslog检索这些消息。
通常使用工具dmesg或守护进程klogd检索这些消息。 printk---------------->log buffer --------------->klogd---------------->syslogd------->文件
printk---------------->log buffer --------------->klogd---------------->文件
printk---------------->log buffer------------------>dmesg 内核模块:
OOPS:LINUX 系统崩溃,LINUX 不能使用 1.EIP
2.CALL TRACE
3.OBJDUMP 反汇编 EIP GDB调试内核:
[root@localhost linux-2.6.32]# pwd
/usr/src/kernels/linux-2.6.32
[root@localhost linux-2.6.32]# gdb vmlinux /proc/kcore
刷新GDB缓存:
(gdb) core-file /proc/kcore
[New process 1]
Core was generated by `ro root=LABEL=/ rhgb quiet'.
#0 0x0000000000000000 in per_cpu.irq_stack_union ()
(gdb) print jiffies
$11 = -109 '\223'
(gdb) core-file /proc/kcore
[New process 1]
Core was generated by `ro root=LABEL=/ rhgb quiet'.
#0 0x0000000000000000 in per_cpu.irq_stack_union ()
(gdb) print jiffies
$12 = 42 '*'
其他内核调试器:
KGDB
http://blog.csdn.net/hejinjing_tom_com/article/details/9932451
KDB
KPROBES
KDUMP
硬件调试器
BDM/JTAG SysRq:
c 内核live reboot,并输出错误信息
d 显示所有排它锁
e 向除 init 外进程发送 SIGTERM 信号,让其自行结束
f 人为触发 OOM Killer (out of memory)
g 当进入内核模式时,以 framebuttter 代替输出
h 输出帮助
i 向除 init 以外所有进程发送 SIGKILL 信号,强制结束进程
k 结束与当前控制台相关的全部进程
m 内存使用信息
n 重置所有进程的 nice(优先级)
o 关机
p 输出cpu 寄存器信息
q Display all active high-resolution timers and clock sources.
r 把键盘设置为 ASCII 模式,使按键可以穿透 x server 捕捉传递给内核
s 同步缓冲区数据到硬盘
t 输出进程列表
u 重新挂载所有文件系统为只读模式
v 输出 Voyager SMP 处理信息
w 输出 block(d状态)进程列表
hello.c 内核模块编绎 #include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h> static int init_hello_4(void)
{
printk(KERN_ALERT "Hello, world 4 ");
return ;
} static void cleanup_hello_4(void)
{
printk(KERN_ALERT "Goodbye, world 4 ");
} module_init(init_hello_4);
module_exit(cleanup_hello_4);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Playmud");
MODULE_DESCRIPTION("Test only!"); 配置Makefile和执行ko编译 [root@server1 ~]# echo "obj-m:=hello.o" > Makefile
[root@server1 ~]# make -C /lib/modules/`uname -r`/build M=`pwd` modules
make: Entering directory `/usr/src/kernels/2.6.32-431.23.3.el6.x86_64'
Building modules, stage 2.
MODPOST 1 modules
make: Leaving directory `/usr/src/kernels/2.6.32-431.23.3.el6.x86_64'
/lib/modules/`uname -r`/build
就是本地机子的module编译配置目录 不是为正在运行的内核编译模块:
make -C M=`pwd`
为正在运行的内核编译模块:
make -C /lib/modules/`uname -r`/build M=`pwd` modules printk没有在console上打印出提示,通过
[root@server1 ~]# dmesg |tail -1
Hello, world
可以查到,具体配置可以查看
vim /etc/syslog.conf
sysrq
常使用的魔术键:
echo >/proc/sys/kernel/sysrq 打开sysrq功能 echo 't' >/proc/sysrq-trigger 打印进程栈,调试时很有用 echo 'c' >/proc/sysrq-trigger 常常用来测试dump模式
printk打印不能显示到终端的问题
【原型】
int printk(const char * fmt,…);
【示例】
与大多数展示printf的功能一样,我们也用一个helloworld的程序来演示printk的输出:
编写一个内核模块:
#include
#include
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include
#endif
MODULE_LICENSE("GPL");
int init_module()
{
printk("hello.word-this is the kernel speaking\n");
return ;
}
void cleanup_module()
{
printk("Short is the life of a kernel module\n");
}
保存为文件hello.c
编写一个Makefile:
CC=gcc
MODCFLAGS:=-O6 -Wall -DMODULE -D__KERNEL__ -DLINUX
hello.o:hello.c /usr/include/linux/version.h
$(CC) $(MODCFLAGS) -c hello.c
echo insmod hello.o to turn it on
保存为文件Makefile
执行make
我们可以看到生成了一个hello.o的内核模块,我们想通过这个模块在插入内核的时候输出
"hello.word-this is the kernel speaking"
这样一条信息。
然后我们开始:
[root@localhost root]# insmod hello.o
[root@localhost root]#
并没有输出任何消息。why?
这也是printf和printk的一个不同的地方
用printk,内核会根据日志级别,可能把消息打印到当前控制台上,这个控制台通常是一个字符模式的终端、一个串口打印机或是一个并口打印机。这些消息正常输出的前提是──日志输出级别小于console_loglevel(在内核中数字越小优先级越高)。
没有指定日志级别的printk语句默认采用的级别是 DEFAULT_ MESSAGE_LOGLEVEL(这个默认级别一般为<>,即与KERN_WARNING在一个级别上),其定义在linux26/kernel/printk.c中可以找到
日志级别一共有8个级别,printk的日志级别定义如下(在include/linux/kernel.h中):
#define KERN_EMERG 0
#define KERN_ALERT 1
#define KERN_CRIT 2
#define KERN_ERR 3
#define KERN_WARNING 4
#define KERN_NOTICE 5
#define KERN_INFO 6
#define KERN_DEBUG 7
现在我们来修改hello.c程序,使printk的输出级别为最高:
printk("<0>""hello.word-this is the kernel speaking\n");
然后重新编译hello.o,并插入内核:
[root@localhost root]# insmod hello.o
[root@localhost root]#
Message from syslogd@localhost at Sat Aug :: ...
localhost kernel: hello.word-this is the kernel speaking
hello,world信息出现了。
其实printk始终是能输出信息的,只不过不一定是到了终端上。我们可以去
/var/log/messages这个文件里面去查看。
如果klogd没有运行,消息不会传递到用户空间,只能查看/proc/kmsg
通过读写/proc/sys/kernel/printk文件可读取和修改控制台的日志级别。查看这个文件的方法如下:
#cat /proc/sys/kernel/printk
上面显示的4个数据分别对应控制台日志级别、默认的消息日志级别、最低的控制台日志级别和默认的控制台日志级别。
可用下面的命令设置当前日志级别:
# echo > /proc/sys/kernel/printk
这样所有级别<,(-)的消息都可以显示在控制台上.
LINUX 内核调试基础+编程基础的更多相关文章
- Linux基础与Linux下C语言编程基础
Linux基础 1 Linux命令 如果使用GUI,Linux和Windows没有什么区别.Linux学习应用的一个特点是通过命令行进行使用. 登录Linux后,我们就可以在#或$符后面去输入命令,有 ...
- LINUX下C语言编程基础
实验二 Linux下C语言编程基础 一.实验目的 1. 熟悉Linux系统下的开发环境 2. 熟悉vi的基本操作 3. 熟悉gcc编译器的基本原理 4. 熟练使用gcc编译器的常用选项 5 .熟练使用 ...
- 【转】Linux基础与Linux下C语言编程基础
原文:https://www.cnblogs.com/huyufeng/p/4841232.html ------------------------------------------------- ...
- linux内核调试指南
linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 ***第一部分:基础知识*** 总纲:内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 ...
- Linux内核调试技术——jprobe使用与实现
前一篇博文介绍了kprobes的原理与kprobe的使用与实现方式,本文介绍kprobes中的另外一种探測技术jprobe.它基于kprobe实现,不能在函数的任何位置插入探測点,仅仅能在函数的入口处 ...
- Linux Kernel - Debug Guide (Linux内核调试指南 )
http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级 ...
- Linux内核调试的方式以及工具集锦【转】
转自:https://blog.csdn.net/gatieme/article/details/68948080 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原 ...
- Linux内核调试的方式以及工具集锦
原文:https://blog.csdn.net/gatieme/article/details/68948080 CSDN GitHubLinux内核调试的方式以及工具集锦 LDD-LinuxDev ...
- Linux内核调试方法总结【转】
转自:http://my.oschina.net/fgq611/blog/113249 内核开发比用户空间开发更难的一个因素就是内核调试艰难.内核错误往往会导致系统宕机,很难保留出错时的现场.调试内核 ...
- 【转】Linux内核调试方法总结
目录[-] 一 调试前的准备 二 内核中的bug 三 内核调试配置选项 1 内核配置 2 调试原子操作 四 引发bug并打印信息 1 BUG()和BUG_ON() 2 dump_sta ...
随机推荐
- CSS2简写代码(优化)
[1]如果CSS属性值为0,那么你不必为其添加单位(如:px/em): 下面是你可能的写法: padding: 10px 5px 0px 0px; 但是你可能这样写: padding: 10px 5p ...
- iOS: plist实例
// // main.m // OSXDemo0601_plist // // Created by yao_yu on 14-6-3. // Copyright (c) 2014年 yao_yu. ...
- 如何设置路由器实现静态IP配置
一.概述 嵌入式开发者,经常面对这样的环境:PC(windows)+虚拟机(linux)+开发板.我们希望三者都能相互通信,而且可以联网. 对于实验室只提供一根网线,而自己没有额外的增加端口数量的设备 ...
- scrollView and tableView
As we all know, tableView is the subclass of scrollView, tableView has every properties that scroll ...
- Quartz1.8.5例子(二)
/* * Copyright 2005 - 2009 Terracotta, Inc. * * Licensed under the Apache License, Version 2.0 (the ...
- css3百叶窗轮播图效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- JSP环境配置
为免以后忘记,记下了. Jdk在C盘,tomcat在D盘. 1.JAVA_HOME C:\Program Files\Java\jdk1.7.0_07 2.CATALINA_HOME D:\apach ...
- Eclipse中Android公共库的正确建立及调用方法
Eclipse中Android公共库的正确建立及调用方法 引言 之前一直头痛于没有办法在多个程序中共享资源,用作公共类库的方法也是使用的导出jar再导入的办法,现在终于初步搞明白了,可算解脱了~,分享 ...
- 用UIKIT的模态对话框要注意的地方
XXX,晚上又搞了三个小时左右,才摸清楚. 多个ID要注意唯一性. 而在DJANGO里,每一个循环的唯一性,也有技巧性. 父循环的编号 {{ forloop.parentloop.counter }} ...
- pfSense软路由防火墙
才刚刚架起来,等着入门呀.. 想作网络的QOS限流这些的...