This is the mail archive of the cygwin-developers@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: stack overflow bug in ofstream::operator<<


On Tue, Jun 28, 2005 at 01:39:14PM +0200, Corinna Vinschen wrote:
>On Jun 28 02:39, Scott McPeak wrote:
>> I believe there is a bug in the cygwin DLL that causes a stack overflow
>> segmentation fault when ofstream::operator<< is used to write a string
>> that is longer than 2MB.
>> 
>> Attached is a simple program, writen.cc, that will create an ofstream and
>> write a string of user-specified length to it.  When that length exceeds
>> about 2MB, it fails:
>> 
>>   $ g++ -o writen -Wall -Wno-deprecated writen.cc
>>   $ ./writen 2000000
>>   $ ./writen 3000000
>>   Segmentation fault (core dumped)
>> 
>> The stack dump and gdb backtrace are attached.  It appears to be the case
>> that the string is being copied onto the stack via alloca, so when the
>> string size exceeds the default 2MB stack limit, the program crashes.
>> 
>> I have confirmed that compiling with (e.g.) -Wl,--stack,4000000 causes the
>> failure limit to increase accordingly.  (ulimit -s 4000 does not work
>> because cygwin's ulimit implementation is only partially functional.)
>> 
>> To fix this, I think that cygwin should not make a copy of the string; or,
>> if it must (CR/LF translation?), do the work in smaller chunks.
>
>We're using alloca/memcpy/write in writev so that writev is atomic.
>If we would change that so that write is called multiple times, we'd
>need to make write explicitely thread safe and each single write would
>be slowed down.  We also can't use WriteFileGather here, unfortunately.
>
>So, what we can do without slowing down write, is either to use malloc
>instead of alloca, or use both, dependent on the number of bytes to be
>written in relation to the size of the stack.
>
>Analogous for readv.

We should probably just use malloc.

cgf


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]