在添加对" print_stack_trace"的调用之后,我收到一个看起来像链接问题的错误。在我的嵌入式Linux内核代码中的一个异常处理程序中。
详情如下:
我的目标&上下文:我正在尝试调试"不精确的外部中止"我的内核在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文件)运行了nm
和objdump
,无法将其跟踪到任何符号地址。
现在,我试图从同一个处理程序中调用save_stack_trace()
和print_stack_trace()
,以获取有关此中止的更多详细信息。
我所做的更改:我添加了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
在函数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
我的观察和问题: 当我编译此代码时,我收到一个看起来像链接器错误的错误:
arch/arm/mm/built-in.o: In function 'do_DataAbort':
:(.exception.text+0x58): undefined reference to 'print_stack_trace'
make[1]: *** [vmlinux] Error 1
请求您的帮助以解决此问题。如果需要任何信息,请告诉我。
答案 0 :(得分:2)
永远不要手动定义CONFIG_*
宏:
// DO NOT DO THAT!
#define CONFIG_STACKTRACE
它们旨在在内核配置(make menuconfig
,make defconfig
或其他*config
目标)期间设置(或不设置)并存储到{{1文件。
配置参数可能依赖于目标机器(体系结构)或其他参数,没有这些参数,由给定参数定义的功能将无法正常工作(甚至无法编译,如您的情况)。
如果您需要设置一些配置参数,可以通过.config
设置一种方式:
make menuconfig
,会出现一个对话框/
。Search Configuration Parameter
前缀)。例如,输入CONFIG_
。按stacktrace
。OK
。Symbol: STACKTRACE
中给出。如果是[]
或[=y]
,则该符号已在内核中定义。如果是[=m]
,请检查如何设置给定符号。[=n]
行,用于描述菜单中符号的位置。请注意,仅当Prompt:
下的表达式已确定时,该符号才会显示在菜单中。例如,只有在设置STACKTRACE_SUPPORT符号时才能设置STACKTRACE符号。依赖符号的值已经显示在表达式中。Dependens on:
行的符号无法由用户设置,只能自动设置:以特定于拱的方式设置,或由其他符号选择(Prompt:
)。在设置Selected by:
符号STACKTRACE_SUPPORT时,x86
也定义了此符号。答案 1 :(得分:0)
您不应该只添加#define CONFIG_STACKTRACE。您必须在内核配置中启用此功能。这将确保内核中内置所需的功能。