]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
In vg_memory.c, allow the stack-change threshold to be specified by a
authorJulian Seward <jseward@acm.org>
Sat, 2 Apr 2005 23:40:59 +0000 (23:40 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 2 Apr 2005 23:40:59 +0000 (23:40 +0000)
command-line flag (--max-stackframe=number), rather than hardwiring it
to 2000000.  This is helpful for dealing with unruly Fortran programs
which want to allocate large arrays on the stack.

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

coregrind/core.h
coregrind/vg_main.c
coregrind/vg_memory.c
docs/xml/manual-core.xml

index 3204d11460d9c205252a0c2fe5ff1dea21b9e038..fcfd1bf5570e7ed22a591a4a5c7f21ed55523274 100644 (file)
@@ -270,6 +270,10 @@ extern Bool VG_(clo_support_elan3);
 /* 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);
 
index c8e29ad5a7650b137b9f119cdc3e1cdac207d9b7..ba8f21e96b7bdf9bf39862bf837547a910f5196d 100644 (file)
@@ -1446,6 +1446,7 @@ Bool   VG_(clo_support_elan3)  = False;
 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;
 
@@ -1487,6 +1488,8 @@ static void usage ( Bool debug_help )
 "    --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 = 
@@ -1675,6 +1678,7 @@ static void process_cmd_line_options( UInt* client_auxv, const char* toolname )
       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))
index d4d50d4ee0972002bc1c68510646568c2a31ba1a..e32986c450dace024e28946dd4e621bf7963d0ab 100644 (file)
@@ -1063,32 +1063,38 @@ Segment *VG_(find_segment_above_mapped)(Addr a)
    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 );
 
index b9f9587168d40377d8036ece61fdca647264bbe2..3a0e79cbf1adf9f12d1a0e680a0fa86905648174 100644 (file)
@@ -783,6 +783,38 @@ errors, e.g. Memcheck, but not Cachegrind.</para>
     as the file name or socket details.</para>
    </listitem>
 
+   <listitem>
+    <para><computeroutput>--max-stackframe=&lt;number&gt;</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>