1

在我的嵌入式 Linux 内核代码中的一个异常处理程序中添加对“print_stack_trace”的调用后,我收到一个看起来像链接问题的错误。

详情如下:

  1. 我的目标和背景:我试图在 A9 板上的内核启动期间调试“不精确的外部中止”内存故障。我收到如下不精确的中止错误:

    [    1.248680] Unhandled fault: imprecise external abort (0x406) at 0xc397ffec
    

我的目标是在发生此中止时尝试收集堆栈和寄存器的更多详细信息。一旦中止发生,我注意到它被定向到一个名为asmlinkage void __exception do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs).

dump_stack()在这个函数内部调用过,它给了我以下堆栈和寄存器数据:

[    1.245755] CPU: 0 PID: 240 Comm: hotplug Not tainted 3.14.26-ts-armv7l #3
[    1.245845] [<c0011fe0>] (unwind_backtrace) from [<c0010934>] (show_stack+0x10/0x14)
[    1.245869] [<c0010934>] (show_stack) from [<c00083c0>] (do_DataAbort+0x40/0x9c)
[    1.245906] [<c00083c0>] (do_DataAbort) from [<c0277f74>] (__dabt_usr+0x34/0x40)
[    1.245919] Exception stack(0xc397ffb0 to 0xc397fff8)
[    1.245935] ffa0:                                     00000000 00000000 00000000 00000000
[    1.245952] ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    1.245969] ffe0: 00000000 be95fe80 00000000 b6f98eec 00000010 ffffffff
[    1.245985] Unhandled fault: imprecise external abort (0x406) at 0xc397ffec

我可以从上面的数据中注意到 fec 对应的地址b6f98eec。我不知道导致中止的值是什么。我针对我的 Linux 映像(vmlinux 文件)运行了一个nmandobjdump并且无法将其跟踪到任何符号地址。现在,我试图从同一个处理程序内部调用save_stack_trace()print_stack_trace(),以获取有关此中止的更多详细信息。

  1. 我所做的更改:我添加save_stack_trace()print_stack_trace()如下内容:在文件顶部,我有以下内容:头文件包含=>

    #include<linux/stacktrace.h>
    #include<asm/stacktrace.h>
    
    #ifdef CONFIG_STACKTRACE
    static unsigned long stack_entries[32];
    
    static struct stack_trace my_trace = {
        .nr_entries = 0,
        .entries = &stack_entries[0],
        .max_entries = 32,
        .skip = 0
    };
    #endif
    

在函数内部do_DataAbort,我添加了以下代码:

#ifdef CONFIG_STACKTRACE
    save_stack_trace(&my_trace);
    printk(KERN_ALERT "calling print_stack \n");
    print_stack_trace(&my_trace, 32);
#endif

在头文件的顶部include/Linux/stacktrace.h,我试图定义CONFIG_STACKTRACE.

#define CONFIG_STACKTRACE
  1. 我的观察和问题:当我编译这段代码时,我收到一个看起来像链接器错误的错误:

    arch/arm/mm/built-in.o: In function 'do_DataAbort':
    :(.exception.text+0x58): undefined reference to 'print_stack_trace'
    make[1]: *** [vmlinux] Error 1
    

请求您的帮助以解决此问题。如果需要任何信息,请告诉我。

4

2 回答 2

2

永远不要手动定义CONFIG_*

// DO NOT DO THAT!
#define CONFIG_STACKTRACE

它们旨在在内核配置(或其他目标)期间设置(或不设置)make menuconfigmake defconfig存储*config.config文件中。

配置参数可能取决于目标机器(架构)或其他参数,如果没有给定参数定义的功能,将无法正常工作(甚至无法编译,就像您的情况一样)。


如果您需要设置一些配置参数,可以通过以下方式进行设置make menuconfig

  1. 按 键,将出现/一个对话框。Search Configuration Parameter
  2. 写入配置参数的名称(不区分大小写,CONFIG_不需要前缀)。例如,输入stacktrace。按OK
  3. 在搜索输出中找到参数的确切名称:Symbol: STACKTRACE
  4. 参数的当前值将在 中给出[]。如果是[=y][=m],则该符号已在内核中定义。如果是[=n],则检查如何设置给定符号。
  5. 可以由用户设置的符号有Prompt:线条,它描述了菜单中符号的位置。请注意,该符号仅在满足下面的表达式时才会显示在菜单Dependens on:中。例如,只有在设置了 STACKTRACE_SUPPORT 符号时才能设置 STACKTRACE 符号。相关符号的值已在表达式中显示。
  6. 没有Prompt:线条的符号不能由用户设置,只能自动设置:以特定于拱门的方式,或被Selected by:其他符号选中 ( )。在x86符号 STACKTRACE_SUPPORT 上设置,arm也定义了这个符号。
  7. 如果任何配置已更改,则需要重新构建内核。
于 2016-02-04T08:17:43.150 回答
0

您不应该只添加#define CONFIG_STACKTRACE。您必须在内核配置中启用此功能。这将确保所需的功能内置到您的内核中。

于 2016-02-04T08:02:05.627 回答