首页 > 解决方案 > Linux内核中的dump_stack()不打印函数的地址

问题描述

我有一个Linux kernel module打印dump_stack(). 但它会打印不完整的跟踪,因为它没有打印功能地址。我使用Ubuntu 16.04.7 LTS带有4.15.0-142-generic内核并CONFIG_DEBUG_INFO=y设置在/boot/config-4.15.0-142-generic.

我的问题:

(1) 为什么函数的地址没有打印出来?我可以使用 .dump 转储符号表objdump -t

(2) Trace 显示dump_stack()从 调用module_level_init。然而它是module_level_init()->module_level_2()->module_level_3()

以下是dmesg输出:

[ 1347.807370] CPU: 7 PID: 13262 Comm: insmod Tainted: P           OE    4.15.0-142-generic #146~16.04.1-Ubuntu
[ 1347.807371] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[29020.752090] Call Trace:
[29020.752096]  dump_stack+0x6d/0x8b
[29020.752097]  ? 0xffffffffc0730000
[29020.752099]  module_level_init+0x1a/0x1000 [kern]
[29020.752102]  do_one_initcall+0x55/0x1b0
[29020.752103]  ? _cond_resched+0x1a/0x50
[29020.752105]  ? kmem_cache_alloc_trace+0x165/0x1c0
[29020.752106]  do_init_module+0x5f/0x222
[29020.752108]  load_module+0x1894/0x1ea0
[29020.752111]  ? ima_post_read_file+0x83/0xa0
[29020.752112]  SYSC_finit_module+0xe5/0x120
[29020.752113]  ? SYSC_finit_module+0xe5/0x120
[29020.752115]  SyS_finit_module+0xe/0x10
[29020.752116]  do_syscall_64+0x73/0x130

内核模块:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

int module_level_3(void)
{
        dump_stack();
        return 0;
}

int module_level_2(void)
{
        module_level_3();
        return 0;
}

static int __init module_level_init(void)
{
        printk(KERN_INFO "Hello, world\n");
        module_level_2();
        return 0;
}

static void __exit module_level_exit(void)
{
        printk(KERN_INFO "Goodbye, world\n");
}

module_init(module_level_init);
module_exit(module_level_exit);
MODULE_LICENSE("GPL");

生成文件:

obj-m += kern.o

all:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

对象转储


#objdump -Sdlr kern.ko

kern.ko:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <module_level_3>:
module_level_3():
   0:   e8 00 00 00 00          callq  5 <module_level_3+0x5>
                        1: R_X86_64_PC32        __fentry__-0x4
   5:   55                      push   %rbp
   6:   48 89 e5                mov    %rsp,%rbp
   9:   e8 00 00 00 00          callq  e <module_level_3+0xe>
                        a: R_X86_64_PC32        dump_stack-0x4
   e:   31 c0                   xor    %eax,%eax
  10:   5d                      pop    %rbp
  11:   c3                      retq
  12:   0f 1f 40 00             nopl   0x0(%rax)
  16:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  1d:   00 00 00

0000000000000020 <module_level_2>:
module_level_2():
  20:   e8 00 00 00 00          callq  25 <module_level_2+0x5>
                        21: R_X86_64_PC32       __fentry__-0x4
  25:   55                      push   %rbp
  26:   48 89 e5                mov    %rsp,%rbp
  29:   e8 00 00 00 00          callq  2e <module_level_2+0xe>
                        2a: R_X86_64_PC32       dump_stack-0x4
  2e:   31 c0                   xor    %eax,%eax
  30:   5d                      pop    %rbp
  31:   c3                      retq

Disassembly of section .init.text:

0000000000000000 <init_module>:
module_level_init():
   0:   e8 00 00 00 00          callq  5 <init_module+0x5>
                        1: R_X86_64_PC32        __fentry__-0x4
   5:   55                      push   %rbp
   6:   48 c7 c7 00 00 00 00    mov    $0x0,%rdi
                        9: R_X86_64_32S .rodata.str1.1
   d:   48 89 e5                mov    %rsp,%rbp
  10:   e8 00 00 00 00          callq  15 <init_module+0x15>
                        11: R_X86_64_PC32       printk-0x4
  15:   e8 00 00 00 00          callq  1a <init_module+0x1a>
                        16: R_X86_64_PC32       dump_stack-0x4
  1a:   31 c0                   xor    %eax,%eax
  1c:   5d                      pop    %rbp
  1d:   c3                      retq

Disassembly of section .exit.text:

0000000000000000 <cleanup_module>:
module_level_exit():
   0:   55                      push   %rbp
   1:   48 c7 c7 00 00 00 00    mov    $0x0,%rdi
                        4: R_X86_64_32S .rodata.str1.1+0x10
   8:   48 89 e5                mov    %rsp,%rbp
   b:   e8 00 00 00 00          callq  10 <cleanup_module+0x10>
                        c: R_X86_64_PC32        printk-0x4
  10:   5d                      pop    %rbp
  11:   c3                      retq


标签: cdebugginglinux-kernelstack-tracekernel-module

解决方案


推荐阅读