From 8a846ffa5c8ca50a1ee8d9fc70b6a447ab18e198 Mon Sep 17 00:00:00 2001 From: Dave Anderson Date: Tue, 8 May 2018 13:49:57 -0400 Subject: [PATCH] Fix for infrequent failures of the x86 "bt" command to handle cases where a user space task with "resume_userspace" or "entry_INT80_32" at the top of the stack, or which was interrupted by the crash NMI while handling a timer interrupt. Without the patch, the backtrace would be proceeded with the error message "bt: cannot resolve stack trace", and then dump the text symbols found on the stack and all possible exception frames. (anderson@redhat.com) --- lkcd_x86_trace.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lkcd_x86_trace.c b/lkcd_x86_trace.c index b8bc720..3af5806 100644 --- a/lkcd_x86_trace.c +++ b/lkcd_x86_trace.c @@ -1953,13 +1953,24 @@ find_trace( static int kernel_entry_from_user_space(sframe_t *curframe, struct bt_info *bt) { + ulong stack_segment; + if (is_kernel_thread(bt->tc->task)) return FALSE; - if (((curframe->fp + 4 + SIZE(pt_regs)) == GET_STACKTOP(bt->task)) && - !is_kernel_thread(bt->tc->task)) - return TRUE; - else if (userspace_return(curframe->fp+4, bt)) + stack_segment = GET_STACK_ULONG(curframe->fp + 4 + SIZE(pt_regs) - sizeof(kaddr_t)); + + if ((curframe->fp + 4 + SIZE(pt_regs)) == GET_STACKTOP(bt->task)) { + if ((stack_segment == 0x7b) || (stack_segment == 0x2b)) + return TRUE; + } + + if ((curframe->fp + 4 + SIZE(pt_regs) + 8) == GET_STACKTOP(bt->task)) { + if ((stack_segment == 0x7b) || (stack_segment == 0x2b)) + return TRUE; + } + + if (userspace_return(curframe->fp+4, bt)) return TRUE; else return FALSE;