Skip to content

Commit 8dbaead

Browse files
author
sewardj
committed
arm-linux only: make unwinding by stack scanning (a nasty hack)
be controllable from the command line. Fixes (kind of) #289578. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13657 a5019735-40e9-0310-863c-91ae7b9d1cf9
1 parent 0e1bad8 commit 8dbaead

File tree

6 files changed

+44
-2
lines changed

6 files changed

+44
-2
lines changed

coregrind/m_main.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ static void usage_NORETURN ( Bool debug_help )
212212
" in the main exe: --soname-synonyms=somalloc=NONE\n"
213213
" in libxyzzy.so: --soname-synonyms=somalloc=libxyzzy.so\n"
214214
" --sigill-diagnostics=yes|no warn about illegal instructions? [yes]\n"
215+
" --unw-stack-scan-thresh=<number> Enable stack-scan unwind if fewer\n"
216+
" than <number> good frames found [0, meaning \"disabled\"]\n"
217+
" NOTE: stack scanning is only available on arm-linux.\n"
218+
" --unw-stack-scan-frames=<number> Max number of frames that can be\n"
219+
" recovered by stack scanning [5]\n"
215220
"\n";
216221

217222
const HChar usage2[] =
@@ -798,6 +803,11 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
798803
else if VG_XACT_CLO(arg, "--gen-suppressions=all",
799804
VG_(clo_gen_suppressions), 2) {}
800805

806+
else if VG_BINT_CLO(arg, "--unw-stack-scan-thresh",
807+
VG_(clo_unw_stack_scan_thresh), 0, 100) {}
808+
else if VG_BINT_CLO(arg, "--unw-stack-scan-frames",
809+
VG_(clo_unw_stack_scan_frames), 0, 32) {}
810+
801811
else if ( ! VG_(needs).command_line_options
802812
|| ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
803813
VG_(fmsg_bad_option)(arg, "");

coregrind/m_options.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ VgSmc VG_(clo_smc_check) = Vg_SmcStack;
125125
const HChar* VG_(clo_kernel_variant) = NULL;
126126
Bool VG_(clo_dsymutil) = False;
127127
Bool VG_(clo_sigill_diag) = True;
128+
UInt VG_(clo_unw_stack_scan_thresh) = 0; /* disabled by default */
129+
UInt VG_(clo_unw_stack_scan_frames) = 5;
130+
128131

129132
/*====================================================================*/
130133
/*=== File expansion ===*/

coregrind/m_stacktrace.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,7 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
957957
/* Loop unwinding the stack. */
958958
Bool do_stack_scan = False;
959959

960+
/* First try the Official Way, using Dwarf CFI. */
960961
while (True) {
961962
if (debug) {
962963
VG_(printf)("i: %d, r15: 0x%lx, r13: 0x%lx\n",
@@ -977,12 +978,17 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
977978
if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
978979
continue;
979980
}
981+
980982
/* No luck. We have to give up. */
981983
do_stack_scan = True;
982984
break;
983985
}
984986

985-
if (0/*DISABLED BY DEFAULT*/ && do_stack_scan && i < max_n_ips && i <= 2) {
987+
/* Now try Plan B (maybe) -- stack scanning. This often gives
988+
pretty bad results, so this has to be enabled explicitly by the
989+
user. */
990+
if (do_stack_scan
991+
&& i < max_n_ips && i < (Int)VG_(clo_unw_stack_scan_thresh)) {
986992
Int nByStackScan = 0;
987993
Addr lr = uregs.r14;
988994
Addr sp = uregs.r13 & ~3;
@@ -1015,7 +1021,7 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
10151021
if (fps) fps[i] = 0;
10161022
ips[i++] = cand;
10171023
if (UNLIKELY(cmrf > 0)) {RECURSIVE_MERGE(cmrf,ips,i);};
1018-
if (++nByStackScan >= 5) break;
1024+
if (++nByStackScan >= VG_(clo_unw_stack_scan_frames)) break;
10191025
}
10201026
}
10211027
sp += 4;

coregrind/pub_core_options.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,19 @@ extern Bool VG_(should_we_trace_this_child) ( HChar* child_exe_name,
318318
depends on verbosity (False if -q). */
319319
extern Bool VG_(clo_sigill_diag);
320320

321+
/* Unwind using stack scanning (a nasty hack at the best of times)
322+
when the normal CFI/FP-chain scan fails. If the number of
323+
"normally" recovered frames is below this number, stack scanning
324+
will be used (on platforms on which it is supported, currently only
325+
arm-linux). The default value of zero has the effect of disabling
326+
stack scanning. Default: zero*/
327+
extern UInt VG_(clo_unw_stack_scan_thresh);
328+
329+
/* If stack scanning is used, this is how many frames it may recover.
330+
Since it tends to pick up a lot of junk, this value is set pretty
331+
low by default. Default: 5 */
332+
extern UInt VG_(clo_unw_stack_scan_frames);
333+
321334
#endif // __PUB_CORE_OPTIONS_H
322335

323336
/*--------------------------------------------------------------------*/

none/tests/cmdline1.stdout.exp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ usage: valgrind [options] prog-and-args
100100
in the main exe: --soname-synonyms=somalloc=NONE
101101
in libxyzzy.so: --soname-synonyms=somalloc=libxyzzy.so
102102
--sigill-diagnostics=yes|no warn about illegal instructions? [yes]
103+
--unw-stack-scan-thresh=<number> Enable stack-scan unwind if fewer
104+
than <number> good frames found [0, meaning "disabled"]
105+
NOTE: stack scanning is only available on arm-linux.
106+
--unw-stack-scan-frames=<number> Max number of frames that can be
107+
recovered by stack scanning [5]
103108

104109
user options for Nulgrind:
105110
(none)

none/tests/cmdline2.stdout.exp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ usage: valgrind [options] prog-and-args
100100
in the main exe: --soname-synonyms=somalloc=NONE
101101
in libxyzzy.so: --soname-synonyms=somalloc=libxyzzy.so
102102
--sigill-diagnostics=yes|no warn about illegal instructions? [yes]
103+
--unw-stack-scan-thresh=<number> Enable stack-scan unwind if fewer
104+
than <number> good frames found [0, meaning "disabled"]
105+
NOTE: stack scanning is only available on arm-linux.
106+
--unw-stack-scan-frames=<number> Max number of frames that can be
107+
recovered by stack scanning [5]
103108

104109
user options for Nulgrind:
105110
(none)

0 commit comments

Comments
 (0)