ldd3学习之四:调试技术

╰半橙微兮° 2022-06-18 03:21 257阅读 0赞

内核中的调试支持

内核开发者一般都已经建立了多项用于调试的功能。但是由于这些功能会造成额外的输出,并导致能下降,因此发行版厂商通常会禁止发行版内核中的调试功能。
为了实现内核调试,我在内核配置上增加了几项:
Kernel hacking —->
[*] Magic SysRq key
[*] Kernel debugging
[*] Debug slab memory allocations
[*] Spinlock and rw-lock debugging: basic checks
[*] Spinlock debugging: sleep-inside-spinlock checking
[*] Compile the kernel with debug info
[*] Magic SysRq key
Device Drivers —->
Generic Driver Options —->
[*] Driver Core verbose debug messages
General setup —->
[*] Configure standard kernel features (for small systems) —->
[*] Load all symbols for debugging/ksymoops
书上介绍的还有其他配置。

方法一:printk

① 首先,printk有8个loglevel,定义在中:







#define    KERN_EMERG    “<0>”    / system is unusable           /
#define    KERN_ALERT    “<1>”   / action must be taken immediately/
#define    KERN_CRIT    “<2>”    / critical conditions    /
#define    KERN_ERR    “<3>”    / error conditions            /
#define    KERN_WARNING    “<4>”    / warning conditions   /
#define    KERN_NOTICE    “<5>”    / normal but significant condition /
#define    KERN_INFO    “<6>”    / informational            /
#define    KERN_DEBUG    “<7>”    / debug-level messages   /

未指定优先级的默认级别定义在/kernel/printk.c中:

  1. /* printk’s without a loglevel use this.. */

  2. #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */

当优先级的值小于console_loglevel这个整数变量的值,信息才能显示出来。而console_loglevel的初始值DEFAULT_CONSOLE_LOGLEVEL也定义在/kernel/printk.c中:







#define DEFAULT_CONSOLE_LOGLEVEL 7 / anything MORE serious than KERN_DEBUG /

还可以通过对/proc/sys/kernel/printk的访问来改变console_loglevel的值

24708340_1299485240a0z4.jpg

四个数字的含义:当前的loglevel、默认loglevel、最小允许的loglevel、引导时的默认loglevel。

Linux消息处理方法的一个特点是: 可以在任何地方调用printk,甚至在终端处理函数里也可以调用,而且对数据量的大小没有限制,唯一缺点是可能丢失某些数据。

fdfdf

②为了方便的打开和关闭调试信息,ldd3提供以下源码:

  1. /* Macros to help debugging */

  2. #undef PDEBUG /* undef it, just in case */

  3. #ifdef SCULL_DEBUG

  4. # ifdef __KERNEL__

  5. /* This one if debugging is on, and kernel space */

  6. # define PDEBUG(fmt, args…) printk( KERN_DEBUG “scull: “ fmt, ## args)

  7. # else /* This one for user space */

  8. # define PDEBUG(fmt, args…) fprintf(stderr, fmt, ## args)

  9. # endif

  10. #else

  11. # define PDEBUG(fmt, args…) /* not debugging: nothing */

  12. #endif

  13. #undef PDEBUGG

  14. #define PDEBUGG(fmt, args…) /* nothing: it’s a placeholder */

Makefile中要添加的语句:

  1. # Comment/uncomment the following line to disable/enable debugging

  2. DEBUG = y

  3. # Add your debugging flag (or not) to CFLAGS

  4. ifeq ($(DEBUG),y)

  5. DEBFLAGS = -O -g -DSCULL_DEBUG # “-O” is needed to expand inlines

  6. else

  7. DEBFLAGS = -O2

  8. endif

  9. CFLAGS += $(DEBFLAGS)

这些宏是很有用的,仅有的缺点是每次开启和关闭消息显示时,都要重新编译模块。

③为了避免printk重复输出过快而阻塞系统,内核使用以下函数跳过部分输出

  1. int printk_ratelimit(void);

典型应用:

  1. if (printk_ratelimit( ))

  2. printk(KERN_NOTICE “The printer is still on fire\n”);

可以通过修改/proc/sys/kernel/printk_ratelimit(重开信息前应等待的秒数)和/proc/sys/kernel/printk_ratelimit_burst(在速度限制前可接受的信息数)来定制printk_ratelimit的行为。Linux还提供了打印设备编号的宏(在中定义):

  1. int print_dev_t(char *buffer, dev_t dev);

  2. char *format_dev_t(char *buffer, dev_t dev);

两个函数的唯一区别是:print_dev_t返回打印字符数,format_dev_t返回缓冲区指针。注意缓冲区char *buffer的大小应至少有20B。

方法二:oops

1.Oops是内核级的Segmentation Fault。

应用程序—>访问非法内存或非法指令—>Segment信号—>行为是coredump

kernel—>打印Oops信息

2.分析步骤

①错误提示原因

②调用栈(对照反汇编代码) back tree:

③寄存器。 PC is at fun+0x1c/0x30

  1. PC-->fun函数0x1c偏移处,0x30fun长度

阅读(1218) | 评论(0) | 转发(5) |

0

上一篇:ldd3学习之三: 字符驱动

下一篇:ldd3学习之五:并发与竞态

相关热门文章

  • 欢迎icysky0605在ChinaUnix博…
  • 欢迎xiaoniu02623在ChinaUnix…
  • 欢迎禹诺在ChinaUnix博客安家!…
  • 欢迎lenswolf在ChinaUnix博客…
  • 欢迎qjy133456在ChinaUnix博客…

  • linux 常见服务端口

  • xmanager 2.0 for linux配置
  • 【ROOTFS搭建】busybox的httpd…
  • openwrt中luci学习笔记
  • 什么是shell

  • linux dhcp peizhi roc

  • 关于Unix文件的软链接
  • 求教这个命令什么意思,我是新…
  • sed -e “/grep/d” 是什么意思…
  • 谁能够帮我解决LINUX 2.6 10…

给主人留下些什么吧!~~

评论热议

发表评论

表情:
评论列表 (有 0 条评论,257人围观)

还没有评论,来说两句吧...

相关阅读

    相关 ldd3学习八:内存分配

    Linux内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页(linux只有分页管理)等问题。 1.kmalloc 函数 kmalloc 是一个功能强大

    相关 ldd3学习调试技术

    内核中的调试支持 内核开发者一般都已经建立了多项用于调试的功能。但是由于这些功能会造成额外的输出,并导致能下降,因此发行版厂商通常会禁止发行版内核中的调试功能。 为