尝试添加print_stack_trace

时间:2016-02-04 07:12:50

标签: linux linux-kernel embedded-linux archlinux-arm

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

详情如下:

  1. 我的目标&上下文:我正在尝试调试"不精确的外部中止"我的内核在A9主板上启动时出现内存故障。 我得到了不精确的中止错误,如下所示:

    [    1.248680] Unhandled fault: imprecise external abort (0x406) at 0xc397ffec
    
  2. 我的目标是尝试收集堆栈的更多细节,并在发生此中止时进行注册。一旦中止发生,我注意到它被定向到一个名为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(),如下所示: 在文件的顶部,我有以下内容: 头文件包含=&gt;

      #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
      
    2. 在函数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
        
      2. 请求您的帮助以解决此问题。如果需要任何信息,请告诉我。

2 个答案:

答案 0 :(得分:2)

永远不要手动定义CONFIG_*

// DO NOT DO THAT!
#define CONFIG_STACKTRACE

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

配置参数可能依赖于目标机器(体系结构)或其他参数,没有这些参数,由给定参数定义的功能将无法正常工作(甚至无法编译,如您的情况)。

如果您需要设置一些配置参数,可以通过.config设置一种方式:

  1. 按键make menuconfig,会出现一个对话框/
  2. 写入配置参数的名称(不区分大小写,不需要Search Configuration Parameter前缀)。例如,输入CONFIG_。按stacktrace
  3. 在搜索输出中找到参数的确切名称:OK
  4. 参数的当前值将在Symbol: STACKTRACE中给出。如果是[][=y],则该符号已在内核中定义。如果是[=m],请检查如何设置给定符号。
  5. 符号可以由用户设置,有[=n]行,用于描述菜单中符号的位置。请注意,仅当Prompt:下的表达式已确定时,该符号才会显示在菜单中。例如,只有在设置STACKTRACE_SUPPORT符号时才能设置STACKTRACE符号。依赖符号的值已经显示在表达式中。
  6. 没有Dependens on:行的符号无法由用户设置,只能自动设置:以特定于拱的方式设置,或由其他符号选择(Prompt:)。在设置Selected by:符号STACKTRACE_SUPPORT时,x86也定义了此符号。
  7. 如果任何配置已更改,则需要重建内核。

答案 1 :(得分:0)

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