Linux 内核中的 dump_stack() 不打印函数的地址

问题描述

我有一个打印 Linux kernel module 的测试 dump_stack()。但它打印了一个不完整的跟踪,因为它没有打印函数地址。我使用带有 Ubuntu 16.04.7 LTS 内核的 4.15.0-142-genericCONfig_DEBUG_INFO=y 设置在 /boot/config-4.15.0-142-generic 中。

我的问题:

(1) 为什么不打印函数地址?我可以使用 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


解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)