Bug 127159

Summary: segfault with large buffer in C program
Product: [Developer tools] valgrind Reporter: Timo Lindfors <timo.lindfors>
Component: generalAssignee: Julian Seward <jseward>
Status: RESOLVED FIXED    
Severity: crash CC: i-bugs-kde-it7zefhsd
Priority: NOR    
Version First Reported In: unspecified   
Target Milestone: ---   
Platform: Debian testing   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:
Attachments: Increase max client stack size from 16mb to 2gb

Description Timo Lindfors 2006-05-11 20:39:51 UTC
Version:            (using KDE KDE 3.5.2)
Installed from:    Debian testing/unstable Packages
OS:                Linux

Steps to reproduce:
1) cat > testcase.c <<EOF
#include <stdio.h>
int main(int argc, char *argv[]) {
    int data[10000000];
    printf("Hello world!");
    return(0);
}
EOF
2) gcc testcase.c -o testcase
3) valgrind ./testcase

Expected results:
3) valgrind should prints its version number information, "Hello World!" and finally more info after "ERROR SUMMARY".

Actual results:
3) valgrind prints its version number but does not print "Hello World!". Finally valgrind segfaults:

==31848== Memcheck, a memory error detector.
==31848== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==31848== Using LibVEX rev 1575, a library for dynamic binary translation.
==31848== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP.
==31848== Using valgrind-3.1.1-Debian, a dynamic binary instrumentation framework.
==31848== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==31848== For more details, rerun with: -v
==31848== 
==31848== Warning: client switching stacks?  SP change: 0xBEFFF378 --> 0xBC9D9960
==31848==          to suppress, use: --max-stackframe=40000024 or greater
==31848== Invalid write of size 4
==31848==    at 0x8048373: main (in /home/lindi/testcase)
==31848==  Address 0xBC9D9960 is on thread 1's stack
==31848== 
==31848== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==31848==  Access not within mapped region at address 0xBC9D9960
==31848==    at 0x8048373: main (in /home/lindi/testcase)
==31848== 
==31848== Process terminating with default action of signal 11 (SIGSEGV)
==31848==  Access not within mapped region at address 0xBC9D995C
==31848==    at 0x4018308: _vgw_freeres (vg_preloaded.c:58)
==31848== 
==31848== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1)
==31848== malloc/free: in use at exit: 0 bytes in 0 blocks.
==31848== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
==31848== For counts of detected errors, rerun with: -v
==31848== All heap blocks were freed -- no leaks are possible.
Segmentation fault

More info:
$ file vgcore.31848 
vgcore.31848: ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from 'testcase'
Comment 1 Tom Hughes 2006-05-18 13:01:57 UTC
This is the normal Unix/Linux behaviour when you run out of stack space - the only reason you're not seeing it normally is because Linux has no limit on the size of the stack by default. I have a 10Mb limit set so it does fail for me even with valgrind.

Unfortunately valgrind needs to reserve space for the stack up front so if there is no stack limit (or the limit is >16Mb) then it uses a 16Mb limit for the stack which is what you are running into.
Comment 2 Thiago Macieira 2006-05-18 19:19:59 UTC
It's also important to note that the "no limit in stack size" is only valid when not using threads. If there is more than one thread running on the program, the stack size per thread is limited.
Comment 3 Raimar Falke 2008-12-10 15:50:13 UTC
Created attachment 29209 [details]
Increase max client stack size from 16mb to 2gb
Comment 4 Raimar Falke 2008-12-10 15:53:31 UTC
We also had this problem. One solution was to increase the stack size 
by patching valgrind. The attached patch increases this 16mb limit to 
2gb.
Comment 5 Julian Seward 2008-12-11 11:20:57 UTC
Did you try the --main-stacksize= flag?  It was created 
specifically to help with this problem.  FWIW, putting
large arrays on the stack is a really bad idea from a
portability perspective; much better to malloc them; and
then also Memcheck can check them better.
Comment 6 Julian Seward 2008-12-11 11:24:43 UTC
Probably (as Tom implies) you need to first get rid of any stack
size ulimit you have, and then use --main-stacksize=.

Comment 7 Raimar Falke 2008-12-11 12:23:13 UTC
Valgrind 3.3.1 doesn't know this option.

I agree that large stack usages are not perfect but we are 
using Ada here and even the normal runtime lib can be quite
demanding on the stack usage.
Comment 8 Julian Seward 2008-12-23 16:47:56 UTC
I believe 3.4.0 will solve this problem by providing the
--main-stacksize= flag.  Therefore closing it.