尝试添加print_stack_trace时出现链接错误



在我的嵌入式 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

我可以从上面的数据中注意到,地址 ffec 对应于b6f98eec .我不知道这是什么值导致中止。我对我的 Linux 映像(vmlinux 文件(运行了nmobjdump,无法将其追溯到任何符号地址。现在,我正在尝试从同一处理程序内部调用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
    

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

切勿手动定义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符号时才能设置堆栈跟踪符号。从属符号的值已显示在表达式中。
  6. 没有Prompt:线的符号不能由用户设置,只能自动设置:以特定于拱的方式,或被其他符号选择(Selected by:(。在设置符号STACKTRACE_SUPPORT x86arm也定义了此符号。
  7. 如果任何配置已更改,则需要重建内核。

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

最新更新