/* Should we show VEX emulation warnings? Default: NO */
extern Bool VG_(clo_show_emwarns);
+/* How much does the stack pointer have to change before tools
+ consider a stack switch to have happened? Default: 2000000 bytes */
+extern Int VG_(clo_max_stackframe);
+
/* Set up the libc freeres wrapper */
extern void VGA_(intercept_libc_freeres_wrapper)(Addr);
Bool VG_(clo_branchpred) = False;
Bool VG_(clo_model_pthreads) = False;
Bool VG_(clo_show_emwarns) = False;
+Int VG_(clo_max_stackframe) = 2000000;
static Bool VG_(clo_wait_for_gdb) = False;
" --db-attach=no|yes start debugger when errors detected? [no]\n"
" --db-command=<command> command to start debugger [gdb -nw %%f %%p]\n"
" --input-fd=<number> file descriptor for input [0=stdin]\n"
+" --max-stackframe=<number> assume stack switch for SP changes larger\n"
+" than <number> bytes [2000000]\n"
"\n";
Char* usage2 =
else VG_BOOL_CLO(arg, "--pointercheck", VG_(clo_pointercheck))
else VG_BOOL_CLO(arg, "--support-elan3", VG_(clo_support_elan3))
else VG_BOOL_CLO(arg, "--show-emwarns", VG_(clo_show_emwarns))
+ else VG_NUM_CLO (arg, "--max-stackframe", VG_(clo_max_stackframe))
else VG_BOOL_CLO(arg, "--profile", VG_(clo_profile))
else VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres))
else VG_BOOL_CLO(arg, "--show-below-main", VG_(clo_show_below_main))
addresses below %esp are not live; those at and above it are.
*/
-/* Kludgey ... how much does %esp have to change before we reckon that
- the application is switching stacks ? */
-#define VG_PLAUSIBLE_STACK_SIZE 8000000
-#define VG_HUGE_DELTA (VG_PLAUSIBLE_STACK_SIZE / 4)
-
/* This function gets called if new_mem_stack and/or die_mem_stack are
tracked by the tool, and one of the specialised cases (eg. new_mem_stack_4)
isn't used in preference */
VGA_REGPARM(2)
void VG_(unknown_SP_update)( Addr old_SP, Addr new_SP )
{
+ static Int moans = 3;
Word delta = (Word)new_SP - (Word)old_SP;
- if (delta < -(VG_HUGE_DELTA) || VG_HUGE_DELTA < delta) {
- /* %esp has changed by more than HUGE_DELTA. We take this to mean
- that the application is switching to a new stack, for whatever
- reason.
+ if (delta < -VG_(clo_max_stackframe) || VG_(clo_max_stackframe) < delta) {
+ /* SP has changed by more than some threshold amount (by
+ default, 2MB). We take this to mean that the application is
+ switching to a new stack, for whatever reason.
JRS 20021001: following discussions with John Regehr, if a stack
switch happens, it seems best not to mess at all with memory
permissions. Seems to work well with Netscape 4.X. Really the
only remaining difficulty is knowing exactly when a stack switch is
happening. */
- if (VG_(clo_verbosity) > 1)
- VG_(message)(Vg_UserMsg, "Warning: client switching stacks? "
- "%%esp: %p --> %p", old_SP, new_SP);
+ if (VG_(clo_verbosity) > 0 && moans > 0) {
+ moans--;
+ VG_(message)(Vg_UserMsg,
+ "Warning: client switching stacks? "
+ "SP change: %p --> %p", old_SP, new_SP);
+ VG_(message)(Vg_UserMsg,
+ " to suppress, use: --max-stackframe=%d or greater",
+ (delta < 0 ? -delta : delta));
+ if (moans == 0)
+ VG_(message)(Vg_UserMsg,
+ " further instances of this message "
+ "will not be shown.");
+ }
} else if (delta < 0) {
VG_TRACK( new_mem_stack, new_SP, -delta );
as the file name or socket details.</para>
</listitem>
+ <listitem>
+ <para><computeroutput>--max-stackframe=<number></computeroutput>
+ [default=2000000]
+ </para>
+ <para>You may need to use this option if your program has large
+ stack-allocated arrays. Valgrind keeps track of your program's
+ stack pointer. If it changes by more than the threshold amount,
+ Valgrind assumes your program is switching to a different stack,
+ and Memcheck behaves differently than it would for a stack pointer
+ change smaller than the threshold. Usually this heuristic works
+ well. However, if your program allocates large structures on the
+ stack, this heuristic will be fooled, and Memcheck will
+ subsequently report large numbers of invalid stack accesses. This
+ option allows you to change the threshold to a different value.
+ </para>
+ <para>
+ You should only consider use of this flag if Valgrind's debug output
+ directs you to do so. In that case it will tell you the new
+ threshold you should specify.
+ </para>
+ <para>
+ In general, allocating large structures on the stack is a bad
+ idea, because (1) you can easily run out of stack space,
+ especially on systems with limited memory or which expect to
+ support large numbers of threads each with a small stack, and (2)
+ because the error checking performed by Memcheck is more effective
+ for heap-allocated data than for stack-allocated data. If you
+ have to use this flag, you may wish to consider rewriting your
+ code to allocate on the heap rather than on the stack.
+ </para>
+ </listitem>
+
<listitem>
<para><computeroutput>--db-attach=no</computeroutput> [default]</para>
<para><computeroutput>--db-attach=yes</computeroutput></para>