Author: sewardj
Date: 2007-12-21 01:24:59 +0000 (Fri, 21 Dec 2007)
New Revision: 7304

Log:
Add a new method VG_(record_depth_1_ExeContext), a trivial derivative
of VG_(record_ExeContext), which just records the first stack frame
but does not attempt to unwind the (guest) stack.  This is useful in
situations where we suspect unwinding the stack might cause a
segfault.

Use this in m_signals, when getting a backtrace following a guest
segfault.

Modified:
   trunk/coregrind/m_execontext.c
   trunk/coregrind/m_signals.c
   trunk/include/pub_tool_execontext.h


Modified: trunk/coregrind/m_execontext.c
===================================================================
--- trunk/coregrind/m_execontext.c      2007-12-19 11:01:13 UTC (rev 7303)
+++ trunk/coregrind/m_execontext.c      2007-12-21 01:24:59 UTC (rev 7304)
@@ -30,12 +30,15 @@
 
 #include "pub_core_basics.h"
 #include "pub_core_debuglog.h"
-#include "pub_core_execontext.h"    // self
 #include "pub_core_libcassert.h"
 #include "pub_core_libcprint.h"     // For VG_(message)()
 #include "pub_core_mallocfree.h"
 #include "pub_core_options.h"
 #include "pub_core_stacktrace.h"
+#include "pub_core_machine.h"       // VG_(get_IP)
+#include "pub_core_vki.h"           // To keep pub_core_threadstate.h happy
+#include "pub_core_threadstate.h"   // VG_(is_valid_tid)
+#include "pub_core_execontext.h"    // self
 
 /*------------------------------------------------------------*/
 /*--- Low-level ExeContext storage.                        ---*/
@@ -277,7 +280,8 @@
    ec_htab_size_idx++;
 }
 
-ExeContext* VG_(record_ExeContext) ( ThreadId tid, Word first_ip_delta )
+static ExeContext* record_ExeContext_wrk ( ThreadId tid, Word first_ip_delta,
+                                           Bool first_ip_only )
 {
    Int         i;
    Addr        ips[VG_DEEPEST_BACKTRACE];
@@ -297,8 +301,15 @@
    vg_assert(VG_(clo_backtrace_size) >= 1 &&
              VG_(clo_backtrace_size) <= VG_DEEPEST_BACKTRACE);
 
-   n_ips = VG_(get_StackTrace)( tid, ips, VG_(clo_backtrace_size),
-                                first_ip_delta );
+   if (first_ip_only) {
+      vg_assert(VG_(is_valid_tid)(tid));
+      n_ips = 1;
+      ips[0] = VG_(get_IP)(tid);
+   } else {
+      n_ips = VG_(get_StackTrace)( tid, ips, VG_(clo_backtrace_size),
+                                   first_ip_delta );
+   }
+
    tl_assert(n_ips >= 1 && n_ips <= VG_(clo_backtrace_size));
 
    /* Now figure out if we've seen this one before.  First hash it so
@@ -378,6 +389,17 @@
    return new_ec;
 }
 
+ExeContext* VG_(record_ExeContext)( ThreadId tid, Word first_ip_delta ) {
+   return record_ExeContext_wrk( tid, first_ip_delta,
+                                      False/*!first_ip_only*/ );
+}
+
+ExeContext* VG_(record_depth_1_ExeContext)( ThreadId tid ) {
+   return record_ExeContext_wrk( tid, 0/*first_ip_delta*/,
+                                      True/*first_ip_only*/ );
+}
+
+
 StackTrace VG_(extract_StackTrace) ( ExeContext* e )
 {                                  
    return e->ips;

Modified: trunk/coregrind/m_signals.c
===================================================================
--- trunk/coregrind/m_signals.c 2007-12-19 11:01:13 UTC (rev 7303)
+++ trunk/coregrind/m_signals.c 2007-12-21 01:24:59 UTC (rev 7304)
@@ -1275,7 +1275,7 @@
            case VKI_BUS_OBJERR: event = "Hardware error"; break;
            }
            break;
-        }
+        } /* switch (sigNo) */
 
         if (event != NULL) {
            if (haveaddr)
@@ -1285,11 +1285,17 @@
               VG_(message)(Vg_UserMsg, " %s", event);
         }
       }
-
-      if (tid != VG_INVALID_THREADID) {
-         VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
+      /* Print a stack trace.  Be cautious if the thread's SP is in an
+         obviously stupid place (not mapped readable) that would
+         likely cause a segfault. */
+      if (VG_(is_valid_tid)(tid)) {
+         ExeContext* ec = VG_(am_is_valid_for_client)
+                             (VG_(get_SP)(tid), sizeof(Addr), VKI_PROT_READ)
+                        ? VG_(record_ExeContext)( tid, 0/*first_ip_delta*/ )
+                      : VG_(record_depth_1_ExeContext)( tid );
+         vg_assert(ec);
+         VG_(pp_ExeContext)( ec );
       }
-
       if (sigNo == VKI_SIGSEGV 
           && info && info->si_code > VKI_SI_USER 
           && info->si_code == VKI_SEGV_MAPERR) {

Modified: trunk/include/pub_tool_execontext.h
===================================================================
--- trunk/include/pub_tool_execontext.h 2007-12-19 11:01:13 UTC (rev 7303)
+++ trunk/include/pub_tool_execontext.h 2007-12-21 01:24:59 UTC (rev 7304)
@@ -57,6 +57,15 @@
 extern 
 ExeContext* VG_(record_ExeContext) ( ThreadId tid, Word first_ip_delta );
 
+// Trivial version of VG_(record_ExeContext), which just records the
+// thread's current program counter but does not do any stack
+// unwinding.  This is useful in some rare cases when we suspect the
+// stack might be outside mapped storage, and so unwinding
+// might cause a segfault.  In this case we can at least safely
+// produce a one-element stack trace, which is better than nothing.
+extern
+ExeContext* VG_(record_depth_1_ExeContext)( ThreadId tid );
+
 // Apply a function to every element in the ExeContext.  The parameter 'n'
 // gives the index of the passed ip.  Doesn't go below main() unless
 // --show-below-main=yes is set.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Valgrind-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers

Reply via email to