[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2 2/2] x86/traps: widen condition for logging top-of-stack



Despite -fno-omit-frame-pointer the compiler may omit the frame pointer,
often for relatively simple leaf functions. (To give a specific example,
the case I've run into this with is _pci_hide_device() and gcc 8.
Interestingly the even more simple neighboring iommu_has_feature() does
get a frame pointer set up, around just a single instruction. But this
may be a result of the size-of-asm() effects discussed elsewhere.)

Log the top-of-stack value if it looks valid _or_ if RIP looks invalid.

Also annotate non-frame-pointer-based stack trace entries with a
question mark, to signal clearly that any one of them may not actually
be part of the call stack.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
v2: Re-base over changes to earlier patch.

--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -431,7 +431,7 @@ static void _show_trace(unsigned long sp
     {
         addr = *stack++;
         if ( is_active_kernel_text(addr) )
-            printk("   [<%p>] %pS\n", _p(addr), _p(addr));
+            printk("   [<%p>] ? %pS\n", _p(addr), _p(addr));
     }
 }
 
@@ -504,20 +504,25 @@ static void show_trace(const struct cpu_
     if ( is_active_kernel_text(regs->rip) ||
          !is_active_kernel_text(tos) )
         printk("   [<%p>] %pS\n", _p(regs->rip), _p(regs->rip));
-    else if ( fault )
+
+    if ( fault )
     {
         printk("   [Fault on access]\n");
         return;
     }
+
     /*
-     * Else RIP looks bad but the top of the stack looks good.  Perhaps we
-     * followed a wild function pointer? Lets assume the top of the stack is a
+     * If RIP looks bad or the top of the stack looks good, log the top of
+     * stack as well.  Perhaps we followed a wild function pointer, or we're
+     * in a function without frame pointer, or in a function prologue before
+     * the frame pointer gets set up? Let's assume the top of the stack is a
      * return address; print it and skip past so _show_trace() doesn't print
      * it again.
      */
-    else
+    if ( !is_active_kernel_text(regs->rip) ||
+         is_active_kernel_text(tos) )
     {
-        printk("   [<%p>] %pS\n", _p(tos), _p(tos));
+        printk("   [<%p>] ? %pS\n", _p(tos), _p(tos));
         sp++;
     }
 





_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.