Linux内核Debug: 相关宏介绍

Linux内核调试相关的宏有很多,下面介绍一些常常用到的

  • CONFIG_DEBUG_KERNEL
  • CONFIG_DEBUG_SLAB(或者 CONFIG_SLUB_DEBUG)
  • CONFIG_DEBUG_PAGEALLOC
  • CONFIG_DEBUG_SPINLOCK
  • CONFIG_DEBUG_SPINLOCK_SLEEP
  • CONFIG_INIT_DEBUG (在2.6.9 ~ 2.6.15版本之间存在过的Feature)
  • CONFIG_DEBUG_INFO
  • CONFIG_MAGIC_SYSRQ
  • CONFIG_DEBUG_STACKOVERFLOW(arm平台不支持,只在powerpc, blackfin, x86等平台支持)
  • CONFIG_DEBUG_STACK_USAGE
  • CONFIG_KALLSYMS
  • CONFIG_IKCONFIG / CONFIG_IKCONFIG_PROC
  • CONFIG_ACPI_DEBUG(ACPI是主要用在PC的电源管理标准)
  • CONFIG_DEBUG_DRIVER
  • CONFIG_SCSI_CONSTANTS
  • CONFIG_INPUT_EVBUG
  • CONFIG_PROFILING

CONFIG_DEBUG_KERNEL

这个宏通常本身没有什么太大用,但其他Debug宏都以来这个宏,所以一般都要打开。

Linux内核Debug: 相关宏介绍_第1张图片

CONFIG_SLUB_DEBUG

CONFIG_SLUB_DEBUG_ON主要的debuggong功能
- SLAB_PANIC
- SLAB_CACHE_DMA
- SLAB_DEBUG_FREE
- SLAB_POISON
- SLAB_RED_ZONE
- SLAB_STORE_USER

Linux内核Debug: 相关宏介绍_第2张图片

  • object padding原来就有的话就不需要再添加 red zone , 最后面的 Pad如果没有的话就增加 4byte pad

test code:

pr_notice("start test: slub_debug.");
buffer = kmalloc(32, GFP_KERNEL);
for(i=0; i<0x32; i++)
    buffer[i] = 0x77;
kfree(buffer);

几十秒之后打印如下:

•••
<5>[  148.333510] start test: slub_debug.
•••
<1>[  174.411704] Unable to handle kernel paging request at virtual address 77777817
<4>[  174.444473] PC is at task_cgroup_from_root+0x80/0xc4
•••

还有

•••
<5>[  338.751992] start test: slub_debug.
<3>[  338.752076] =============================================================================
<3>[  338.758861] BUG kmalloc-32: Redzone overwritten
<3>[  338.763373] -----------------------------------------------------------------------------
<3>[  338.763460]
<3>[  338.773014] INFO: 0xe7844bc0-0xe7844bc3. First byte 0x77 instead of 0xcc
<3>[  338.779709] INFO: Allocated in 0x77777777 age=0 cpu=2004318071 pid=30583
<3>[  338.786403] INFO: Freed in malipmm_irq_bhandler+0xf8/0x260 age=35 cpu=0 pid=13
<3>[  338.793585] INFO: Slab 0xd04f0880 objects=42 used=24 fp=0xe78440c0 flags=0x00c1
<3>[  338.800873] INFO: Object 0xe7844ba0 @offset=2976 fp=0x77777777
<3>[  338.800937]
<3>[  338.808164] Bytes b4 0xe7844b90:  5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
<3>[  338.817103]   Object 0xe7844ba0:  77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwwwwwwwwwww
<3>[  338.826043]   Object 0xe7844bb0:  77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwwwwwwwwwww
<3>[  338.834983]  Redzone 0xe7844bc0:  77 77 77 77                                     wwww
<3>[  338.843924]  Padding 0xe7844be8:  5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
<3>[  338.852865]  Padding 0xe7844bf8:  5a 5a 5a 5a 5a 5a 5a 5a                         ZZZZZZZZ
<4>[  338.861854] [<c01d2338>] (unwind_backtrace+0x0/0x104) from [<c02a3d50>] (check_bytes_and_report+0xd0/0x100)
<4>[  338.861981] [<c02a3d50>] (check_bytes_and_report+0xd0/0x100) from [<c02a3dd8>] (check_object+0x58/0x220)
<4>[  338.862103] [<c02a3dd8>] (check_object+0x58/0x220) from [<c02a4714>] (__slab_free+0x268/0x3ac)
<4>[  338.862213] [<c02a4714>] (__slab_free+0x268/0x3ac) from [<c02a6934>] (kfree+0xd4/0x170)
<4>[  338.862329] [<c02a6934>] (kfree+0xd4/0x170) from [<c049d5bc>] (gpio_keys_report_event+0x100/0x1c0)
<4>[  338.862457] [<c049d5bc>] (gpio_keys_report_event+0x100/0x1c0) from [<c02235a8>] (process_one_work+0x130/0x4c8)
<4>[  338.862591] [<c02235a8>] (process_one_work+0x130/0x4c8) from [<c0223cc0>] (worker_thread+0x17c/0x444)
<4>[  338.862712] [<c0223cc0>] (worker_thread+0x17c/0x444) from [<c0229adc>] (kthread+0x88/0x90)
<4>[  338.862829] [<c0229adc>] (kthread+0x88/0x90) from [<c01cc4b4>] (kernel_thread_exit+0x0/0x8)
<3>[  338.862932] FIX kmalloc-32: Restoring 0xe7844bc0-0xe7844bc3=0xcc•••

相关的宏有:

config SLUB_DEBUG_ON
    bool "SLUB debugging on by default"
    depends on SLUB && SLUB_DEBUG && !KMEMCHECK
    default n
    help
      Boot with debugging on by default. SLUB boots by default with
      the runtime debug capabilities switched off. Enabling this is
      equivalent to specifying the "slub_debug" parameter on boot.
      There is no support for more fine grained debug control like
      possible with slub_debug=xxx. SLUB debugging may be switched
      off in a kernel built with CONFIG_SLUB_DEBUG_ON by specifying
      "slub_debug=-".

CONFIG_SLUB_DEBUG_PANIC_ON

config SLUB_DEBUG_PANIC_ON
    bool "Enable to Panic on SLUB corruption detection"
    depends on SLUB_DEBUG
    help
      SLUB has a resiliency feature enabled which restores bytes in
      order for production environments to continue to operate. IN
      debug options this may not be desirable as it prevents from
      investigating the root cause which may be rooted within cache
      or memory.

CONFIG_DEBUG_SPINLOCK

这个宏基本的Debug内容(spinlock 和 rw-lock)以及相应的BUG输出的message

  • 没有被初始化的spinlock : “bad magic”
  • 被两次unlock : “already unlocked”
  • 在同一cpu重新lock : “cpu recursion”
  • 错误的process去unlock : “wront owner”
spinlock_types.h文件

typedef struct raw_spinlock {
        arch_spinlock_t raw_lock;
#ifdef CONFIG_DEBUG_SPINLOCK
        unsigned int magic, owner_cpu;
        void *owner;
#endif
} raw_spinlock_t;

//spinlock_debug.c文件

void do_raw_spin_lock(raw_spinlock_t *lock)
{
    debug_spin_lock_before(lock);
...
    debug_spin_lock_after(lock);
}

int do_raw_spin_trylock(raw_spinlock_t *lock)
{
...
    debug_spin_lock_after(lock);
}

void do_raw_spin_unlock(raw_spinlock_t *lock)
{
    debug_spin_unlock(lock);
...
}


//
/lib/Makefile
obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o

CONFIG_DEBUG_SPINLOCK_SLEEP这个宏从3.1开始变成了CONFIG_DEBUG_ATOMIC_SLEEP

这两个宏有如下功能:

  • 在atomic context(spinlock, irq-handler) 检查是否会调用了可以进入睡眠的函数,如果有的话会打印stack trace
  • 如果在抓着spinlock的时候进入睡眠会怎么样??
    (1) 运气好的话会在经过一段时间之后unlock
    (2)运气不好的话会变成daedlock

CONFIG_DEBUG_INFO

这个宏在编译内核的时候包含debug symble,如果没有这个gdb等工具就不能使用

[Nr] Name             
[ 0]                  
[ 1] .note.gnu.build-i
[ 2] .init            
[ 3] .data..percpu    
[ 4] .text            
[ 5] .rodata          
[ 6] .builtin_fw      
[ 7] __ksymtab        
[ 8] __ksymtab_gpl    
[ 9] __kcrctab        
[10] __kcrctab_gpl    
[11] __ksymtab_strings
[12] __param          
[13] .ARM.unwind_idx  
[14] .ARM.unwind_tab  
[15] .data            
[16] .bss             
[17] .comment         
[18] .ARM.attributes  
[19] .debug_line    //这些debug信息如果没有使能CONFIG_DEBUG_INFO就没有 
[20] .debug_info      
[21] .debug_abbrev    
[22] .debug_aranges   
[23] .debug_pubnames  
[24] .debug_str       
[25] .debug_frame     
[26] .debug_loc       
[27] .debug_ranges    
[28] .shstrtab        
[29] .symtab          
[30] .strtab 

这个宏对于最终的kernel binary(arch/arm/boot/Image)的大小没有影响!!!
但vmlinux大小当然会受CONFIG_DEBUG_INFO宏的影响

CONFIG_KALLSYMS

决定是否把整个kenrel的symbol信心都编译到vmlinux中。
- symbol信息在做stack backtrace
- 这个宏默认被打开
比如在panic的时候打印如下信息就需要使能上述feature

/init/Kconfig

config KALLSYMS
         bool "Load all symbols for debugging/ksymoops" if EMBEDDED
         default y
         help
           Say Y here to let the kernel print out symbolic crash information and
           symbolic stack backtraces. This increases the size of the kernel
           somewhat, as all symbols have to be loaded into the kernel image.
Stack backtrace

<0>[  313.217680] Kernel panic - not syncing: Crash Key
<4>[  313.220968] [<c0257338>] (unwind_backtrace+0x0/0x104) from [<c07539d8>] (panic+0x6c/0x1a4)
<4>[  313.229199] [<c07539d8>] (panic+0x6c/0x1a4) from [<c026b6fc>] (sec_debug_check_crash_key+0x90/0xdc)
<4>[  313.238223] [<c026b6fc>] (sec_debug_check_crash_key+0x90/0xdc) from [<c051fd54>] (gpio_keys_isr+0x68/0xa0)
<4>[  313.247862] [<c051fd54>] (gpio_keys_isr+0x68/0xa0) from [<c02d7a70>] (handle_IRQ_event+0x7c/0x228)
<4>[  313.256798] [<c02d7a70>] (handle_IRQ_event+0x7c/0x228) from [<c02d9df0>] (handle_edge_irq+0xcc/0x1ac)
<4>[  313.265998] [<c02d9df0>] (handle_edge_irq+0xcc/0x1ac) from [<c0261a50>] (s5pv310_irq_demux_eint16_31+0x98/0x148)
<4>[  313.276155] [<c0261a50>] (s5pv310_irq_demux_eint16_31+0x98/0x148) from [<c024f060>] (asm_do_IRQ+0x60/0xc0)
<4>[  313.285785] [<c024f060>] (asm_do_IRQ+0x60/0xc0) from [<c024fd1c>] (__irq_svc+0x5c/0xf8)

CONFIG_MAGIC_SYSRQ

CONFIG_DEBUG_STACK_USAGE

这个宏检查stack的使用情况
(1) task创建 -> 把8k的stack清零
(2) task exit -> 如果使用了最多的stack的话会输出message
(3) SysRq-T -> show task states

CONFIG_IKCONFIG / CONFIG_IKCONFIG_PROC

kernel configuration信心built-in到kernel里,这个宏打开之后会生成/proc/config.gz文件
打开之后会增大: /arch/arm/boot/Image文件的大小

CONFIG_DEBUG_DRIVER

在调试Driver core的时候很有用的feature,使能之后会输出/driver/base里边pr_debug,dev_dbg等log。

 /drivers/base/Makefile
 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG

/drivers/base/power/Makefile
ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG

打开这个宏之后会在booting和sleep/resume的时候打印很多信心

//booting的时候
•••
<7>[    1.951382] device: 'input3': device_add
<7>[    1.951514] PM: Adding info for No Bus:input3
<6>[    1.951724] input: light_sensor as /devices/virtual/input/input3
<7>[    1.951770] device: 'event3': device_add
<7>[    1.951939] PM: Adding info for No Bus:event3
<7>[    1.952122] device class 'lightsensor': registering
<7>[    1.952303] device: 'switch_cmd': device_add
<7>[    1.952383] PM: Adding info for No Bus:switch_cmd
<6>[    1.952556] bh1721fvc_probe: success!
•••
wakeup的时候
•••
<7>[   63.026451] i2c i2c-0: resume
<7>[   63.026480] at24 0-0050: resume
<7>[   63.026510] at24 0-0052: resume
<7>[   63.026540] i2c i2c-1: resume
<7>[   63.026569] mpu3050 1-0068: resume
<6>[   63.026601] mpu_resume: accel_adapter = f1188c68
<6>[   63.026639] mpu_resume: pid = 2889
<7>[   63.026670] i2c i2c-3: resume
<7>[   63.026699] Atmel MXT768E 3-004c: resume
<7>[   63.026734] i2c i2c-4: resume
<7>[   63.026763] i2c i2c-5: resume
<7>[   63.026792] max8997 5-0066: resume
<6>[   63.026821] wake disabled for irq 331
•••

CONFIG_INPUT_EVBUG

要打印所有的event log的时候使能这个宏

/drivers/input/Makefile

obj-$(CONFIG_INPUT_EVBUG)   += evbug.o

CONFIG_PROFILING

你可能感兴趣的:(Linux内核Debug: 相关宏介绍)