I am getting a error that looks like a linking problem, after adding a call to "print_stack_trace" in one of the exception handlers inside my embedded Linux kernel code.
Details are as below:
My objective & context: I am trying to debug an "imprecise external abort" memory fault during my kernel's boot-up on my A9 board. I am getting the imprecise abort error as below:
[ 1.248680] Unhandled fault: imprecise external abort (0x406) at 0xc397ffec
My objective is to try and gather more details of the stack and registers when this abort is occurring. Once the abort occurs, I noted that it is getting directed to a handler called asmlinkage void __exception do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
.
I have called dump_stack()
inside this function, which gives me the following stack and register data:
[ 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
I can note from the above data that address ffec corresponds to b6f98eec
. I have no idea what value is this that causes the abort. I ran a nm
and objdump
against my Linux image (vmlinux file) and could not trace this to any symbol address.
Now, I am trying to call save_stack_trace()
and print_stack_trace()
from inside the same handler, to obtain more details about this abort.
Changes I have done: I added
save_stack_trace()
andprint_stack_trace()
as follows: At the top of the file, I have the following: Header file inclusions =>#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
Inside the function do_DataAbort
, I have added the following code:
#ifdef CONFIG_STACKTRACE
save_stack_trace(&my_trace);
printk(KERN_ALERT "calling print_stack \n");
print_stack_trace(&my_trace, 32);
#endif
At the top of the header file include/Linux/stacktrace.h
, I have tried to define CONFIG_STACKTRACE
.
#define CONFIG_STACKTRACE
My observation and problem: When I compile this code, I am getting an error that looks like a linker error:
arch/arm/mm/built-in.o: In function 'do_DataAbort': :(.exception.text+0x58): undefined reference to 'print_stack_trace' make[1]: *** [vmlinux] Error 1
Request your help to resolve this. Please let me know if any information is required.
Never define
CONFIG_*
macros manually:They are intended to be set (or not set) during kernel's configuration (
make menuconfig
,make defconfig
or other*config
targets) and to be stored into.config
file.A configuration parameter may depends on target machine(architecture) or other parameters, without which functionality, defined by given parameter, will not work correctly (or even will not compile, like in your case).
If you need some configuration parameter to be set, one way could be set it via
make menuconfig
:/
, a dialogSearch Configuration Parameter
will appear.CONFIG_
prefix is not required). E.g., enterstacktrace
. PressOK
.Symbol: STACKTRACE
.[]
. If it is[=y]
or[=m]
, then the symbol is already defined in the kernel. If it is[=n]
, then check, how to set given symbol.Prompt:
line, which describes location of the symbol in the menu. Note, that symbol is shown in the menu only when expression underDependens on:
is saticfied. E.g., STACKTRACE symbol can be set only when STACKTRACE_SUPPORT symbol is set. Value of dependent symbols is already shown in the expression.Prompt:
line, cannot be set by the user and can only be set automatically: in the arch-specific way, or being selected (Selected by:
) by other symbols. Onx86
symbol STACKTRACE_SUPPORT is set,arm
also defines this symbol.