]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
arm-linux only: make unwinding by stack scanning (a nasty hack)
authorJulian Seward <jseward@acm.org>
Fri, 18 Oct 2013 13:21:26 +0000 (13:21 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 18 Oct 2013 13:21:26 +0000 (13:21 +0000)
be controllable from the command line.  Fixes (kind of) #289578.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13657

coregrind/m_main.c
coregrind/m_options.c
coregrind/m_stacktrace.c
coregrind/pub_core_options.h
none/tests/cmdline1.stdout.exp
none/tests/cmdline2.stdout.exp

index c2a918c552c5a6a84fb7cb0d7aa6bfeb57e392f3..610d782519fb25cf302bf74c80a776f3e3bab699 100644 (file)
@@ -212,6 +212,11 @@ static void usage_NORETURN ( Bool debug_help )
 "                  in the main exe:  --soname-synonyms=somalloc=NONE\n"
 "                  in libxyzzy.so:   --soname-synonyms=somalloc=libxyzzy.so\n"
 "    --sigill-diagnostics=yes|no  warn about illegal instructions? [yes]\n"
+"    --unw-stack-scan-thresh=<number>   Enable stack-scan unwind if fewer\n"
+"                  than <number> good frames found  [0, meaning \"disabled\"]\n"
+"                  NOTE: stack scanning is only available on arm-linux.\n"
+"    --unw-stack-scan-frames=<number>   Max number of frames that can be\n"
+"                  recovered by stack scanning [5]\n"
 "\n";
 
    const HChar usage2[] = 
@@ -798,6 +803,11 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
       else if VG_XACT_CLO(arg, "--gen-suppressions=all",
                                VG_(clo_gen_suppressions), 2) {}
 
+      else if VG_BINT_CLO(arg, "--unw-stack-scan-thresh",
+                          VG_(clo_unw_stack_scan_thresh), 0, 100) {}
+      else if VG_BINT_CLO(arg, "--unw-stack-scan-frames",
+                          VG_(clo_unw_stack_scan_frames), 0, 32) {}
+
       else if ( ! VG_(needs).command_line_options
              || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
          VG_(fmsg_bad_option)(arg, "");
index b8e3cac583428fcaf95f5788f23a974437cccec6..81225768daf8bbf90a01f557faab3f99d5734bb8 100644 (file)
@@ -125,6 +125,9 @@ VgSmc  VG_(clo_smc_check)      = Vg_SmcStack;
 const HChar* VG_(clo_kernel_variant) = NULL;
 Bool   VG_(clo_dsymutil)       = False;
 Bool   VG_(clo_sigill_diag)    = True;
+UInt   VG_(clo_unw_stack_scan_thresh) = 0; /* disabled by default */
+UInt   VG_(clo_unw_stack_scan_frames) = 5;
+
 
 /*====================================================================*/
 /*=== File expansion                                               ===*/
index 3a1fdff02b807352626dfc28d1e093fb1f54982c..c0523500ffa53156ca39705d61bb4de2001e0538 100644 (file)
@@ -957,6 +957,7 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
    /* Loop unwinding the stack. */
    Bool do_stack_scan = False;
 
+   /* First try the Official Way, using Dwarf CFI. */
    while (True) {
       if (debug) {
          VG_(printf)("i: %d, r15: 0x%lx, r13: 0x%lx\n",
@@ -977,12 +978,17 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
          if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
          continue;
       }
+
       /* No luck.  We have to give up. */
       do_stack_scan = True;
       break;
    }
 
-   if (0/*DISABLED BY DEFAULT*/ && do_stack_scan && i < max_n_ips && i <= 2) {
+   /* Now try Plan B (maybe) -- stack scanning.  This often gives
+      pretty bad results, so this has to be enabled explicitly by the
+      user. */
+   if (do_stack_scan
+       && i < max_n_ips && i < (Int)VG_(clo_unw_stack_scan_thresh)) {
       Int  nByStackScan = 0;
       Addr lr = uregs.r14;
       Addr sp = uregs.r13 & ~3;
@@ -1015,7 +1021,7 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
                if (fps) fps[i] = 0;
                ips[i++] = cand;
                if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
-               if (++nByStackScan >= 5) break;
+               if (++nByStackScan >= VG_(clo_unw_stack_scan_frames)) break;
             }
          }
          sp += 4;
index 0202ab9e27635133a8da7494cd2811730968bfa9..75547220856644e603d41bae65b25a52fe66af83 100644 (file)
@@ -318,6 +318,19 @@ extern Bool VG_(should_we_trace_this_child) ( HChar* child_exe_name,
    depends on verbosity (False if -q). */
 extern Bool VG_(clo_sigill_diag);
 
+/* Unwind using stack scanning (a nasty hack at the best of times)
+   when the normal CFI/FP-chain scan fails.  If the number of
+   "normally" recovered frames is below this number, stack scanning
+   will be used (on platforms on which it is supported, currently only
+   arm-linux).  The default value of zero has the effect of disabling
+   stack scanning.  Default: zero*/
+extern UInt VG_(clo_unw_stack_scan_thresh);
+
+/* If stack scanning is used, this is how many frames it may recover.
+   Since it tends to pick up a lot of junk, this value is set pretty
+   low by default.  Default: 5 */
+extern UInt VG_(clo_unw_stack_scan_frames);
+
 #endif   // __PUB_CORE_OPTIONS_H
 
 /*--------------------------------------------------------------------*/
index 12d7cce91dff8174c9aa7d101e69e0cf09b0c740..26f1e21c81140fa0004bc43a6054dad322db0a26 100644 (file)
@@ -100,6 +100,11 @@ usage: valgrind [options] prog-and-args
                   in the main exe:  --soname-synonyms=somalloc=NONE
                   in libxyzzy.so:   --soname-synonyms=somalloc=libxyzzy.so
     --sigill-diagnostics=yes|no  warn about illegal instructions? [yes]
+    --unw-stack-scan-thresh=<number>   Enable stack-scan unwind if fewer
+                  than <number> good frames found  [0, meaning "disabled"]
+                  NOTE: stack scanning is only available on arm-linux.
+    --unw-stack-scan-frames=<number>   Max number of frames that can be
+                  recovered by stack scanning [5]
 
   user options for Nulgrind:
     (none)
index c3e3d3c97237afc2480d3755b0cf6baeb155433e..f76a25ba08be7d9867491c0e4f4547447cebae68 100644 (file)
@@ -100,6 +100,11 @@ usage: valgrind [options] prog-and-args
                   in the main exe:  --soname-synonyms=somalloc=NONE
                   in libxyzzy.so:   --soname-synonyms=somalloc=libxyzzy.so
     --sigill-diagnostics=yes|no  warn about illegal instructions? [yes]
+    --unw-stack-scan-thresh=<number>   Enable stack-scan unwind if fewer
+                  than <number> good frames found  [0, meaning "disabled"]
+                  NOTE: stack scanning is only available on arm-linux.
+    --unw-stack-scan-frames=<number>   Max number of frames that can be
+                  recovered by stack scanning [5]
 
   user options for Nulgrind:
     (none)