LinuxOOPS 调试

    技术2022-05-20  48

     

    以前在写驱动的时候 ,遇到比较多的kernel panic oops 问题,然后 问一些 同事 ,比较多的回答都是加 printk,其实用 GDB 的中的一个功能是能很方便地调试这些问题的。 整理了一下,把自己给一家培训学校写的课件 贴上来。 第一章 调试 1.1. 工作环境配置 1 )安装好编译用的 kernel-source :RedHat :kernel-devel-xxx.rpm, •     suse:kernel-source-xxx.rpm, 自己编译的 kernel source 2 GCC 包, gcc,g++,cpp, 3) as,ld,objdump,etc 4) glibc/uclibc 5) make 6) gdb 7 SSH 工具 : SSH secure Shell 用于 windows 系统与 Linux 系统之间的文件传输 8 )串口工具,用于调试拿 log 信息, windos 下用超级终端或者 secureCRT Linux 下用 minicom ,C-Kermit 1.2 printk 在内核中 printk () 的级别定义: #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  */ 通过 /proc/sys/kernel/printk 文件可以调节 printk 的输出级别, 通过如下命令可以使得 Linux 内核的任何 printk 都被输出: #echo 8 > /proc/sys/kernel/printk 同时设置 grub.conf : Kernel  这一行加上 : console=tty0,console=ttyS0,115200 1.3 oops panic 1.3.1 API oops DEBUG 1.3.1.1. 定位 OOPS 示例: apioops.c: #include <stdio.h> #include <stdlib.h> Const char array[]="/x6b/xc0 "; int main(int argc, char *argv[]) {         printf("%p/n", array);         *(int *)0 = 0; } 1. )编译时打开 complie with debug info 选项 (-g) , 选项 [root@localhost ~]# gcc -g -o apioops apioops.c 2 )执行 api_oops: [root@localhost ~]# ./apioops 显示屏输出信息 0x4005e0 Segmentation fault [root@localhost ~]# 串口输出信息: apioops[28910]: segfault at 0000000000000000 rip 00000000004004c0 rsp 00007fff22e15760 error 6 rip 00000000004004c0  表示执行到这个位置是 出错 EIP RIP 值 一般表示代码运行时 ,出错的位置 3 )调试 [root@localhost ~]# gdb apioops GNU gdb Fedora (6.8-27.el5) Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.  Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu"... gdb 1.list 调试 RIP 地址:很明显 出错在第 11 行 ,访问空指针 (gdb) l*0x4004c0 0x4004c0 is in main (apioops.c:11). 6 7       const char array[] = "/x63/x2e"; 8       int main(int argc, char *argv[]) 9       { 10              printf("%p/n", array); 11              *(int *)0 = 0; 12      } (gdb) 2. run apioops ,很明显 11 行 出错 (gdb) r Starting program: /root/apioops 0x4005c8 Program received signal SIGSEGV, Segmentation fault. 0x00000000004004c0 in main (argc=1, argv=0x7fffa7020a28) at oops.c:11 11              *(int *)0 = 0; (gdb) 3) 编译时没打开 complie with debug info 选项 (-g) , 选项的调试,或者只有 error 信息没有 代码的调试 。 1. 运行 run (gdb) r Starting program: /root/apioops (no debugging symbols found) (no debugging symbols found) 0x4005c8 Program received signal SIGSEGV, Segmentation fault. 0x00000000004004c0 in main () (gdb) 2. 反汇编 ( gdb ) disassemble Dump of assembler code for function main: 0x0000000000400498 <main+0>:    push   % rbp 0x0000000000400499 <main+1>:    mov     % rsp,%rbp 0x000000000040049c <main+4>:    sub    $0x10,%rsp 0x00000000004004a0 <main+8>:    mov    

    转载请注明原文地址: https://ibbs.8miu.com/read-2224345.html

    最新回复(0)