diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2016-11-15 16:55:59 +0300 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2016-11-15 18:25:39 +0300 |
commit | 24c66dfd569c4744fc43aea638155ad2dc1499d8 (patch) | |
tree | aafbb0d392b4384411c0027773890cbd7ec77cb8 /arch/arm/kernel | |
parent | 6127d124ee4eb9c39983813cc9803f3654ab7e16 (diff) | |
download | linux-24c66dfd569c4744fc43aea638155ad2dc1499d8.tar.xz |
ARM: fix backtrace
Recent kernels have changed their behaviour to be more inconsistent
when handling printk continuations. With todays kernels, the output
looks sane on the console, but dmesg splits individual printk()s which
do not have the KERN_CONT prefix into separate lines.
Since the assembly code is not trivial to add the KERN_CONT, and we
ideally want to avoid using KERN_CONT (as multiple printk()s can race
between different threads), convert the assembly dumping the register
values to C code, and have the C code build the output a line at a
time before dumping to the console.
This avoids the KERN_CONT issue, and also avoids situations where the
output is intermixed with other console activity.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/traps.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index bc698383e822..9688ec0c6ef4 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -74,6 +74,26 @@ void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); } +void dump_backtrace_stm(u32 *stack, u32 instruction) +{ + char str[80], *p; + unsigned int x; + int reg; + + for (reg = 10, x = 0, p = str; reg >= 0; reg--) { + if (instruction & BIT(reg)) { + p += sprintf(p, " r%d:%08x", reg, *stack--); + if (++x == 6) { + x = 0; + p = str; + printk("%s\n", str); + } + } + } + if (p != str) + printk("%s\n", str); +} + #ifndef CONFIG_ARM_UNWIND /* * Stack pointers should always be within the kernels view of |