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
这样所有级别<,(-)的消息都可以显示在控制台上.
最新文章
- 最新的jQuery插件和JavaScript库
- android 拉伸图片
- 修饰者模式(装饰者模式,Decoration)
- DataTable数据集转换为List非泛型以及泛型方式
- ruby1.8到2.1语法改变
- Codeforces 452D [模拟][贪心]
- 《锋利的jQuery》心得笔记--Four Sections
- python中enumerate的使用
- (java)从零开始之--装饰者设计模式
- oracle系统包——dbms_random用法及order by 小结(转)
- hdu5618 (三维偏序,cdq分治)
- use grep &;amp; awk to get ed2k links in the webpage
- PHP的高并发和大数据处理
- selinux学习
- python celery任务分发
- idea 常用快捷键
- Install Superset from Python3.6
- Java8新特性 并行流与串行流 Fork Join
- LeetCode——150. Evaluate Reverse Polish Notation
- java的环境变量
热门文章
- 【C语言】测试系统各数据类型大小代码
- 构建微服务:Spring boot
- struts中如何将前台的值能在action中获取到
- hadoop 常用配置项
- [Codeforces Round #296 div2 D] Clique Problem 【线段树+DP】
- Ecshop wap
- nginx的autoindex-目录浏览还有其它两个参数
- quartz源码解析--转
- Fixing common issues when hosting a .NET 4.0 WCF service in IIS 7
- [LeetCode#212]Word Search II