stack size vs. thread stack size

56 views
Skip to first unread message

kjacks...@hotmail.com

unread,
May 14, 2002, 9:20:10 PM5/14/02
to
Hi,

I was wondering if someone could explain what the difference is
between the "stack size" you see in ulimit -s and the thread stack
size for pthreads, that you can set using pthread_attr_setstacksize.

For example, on Solaris, when you use ulimit, the default stack size
if 8 MB. On Solaris, I've read that there is a default stack size of
1 MB per thread. Obviously, it can't mean that a process can only
have 8 threads, but I don't know what the relationship between the two
are, if any.

Thanks for any help,

Kev

David Butenhof

unread,
May 15, 2002, 7:50:30 AM5/15/02
to
kjacks...@hotmail.com wrote:

Traditionally, the stack ulimit is the size to which the PROCESS stack is
allowed by the system to grow should nothing else get in the way. (That is,
an mmap() region may be placed "past" the current end of stack and prevent
the stack from actually expanding to the ulimit size.)

There's no practical way to "arbitrarily" extend multiple stacks within the
same address space, so there's no direct way to apply the traditional
meaning except to continue to apply the limit only to the initial thread.
In many cases the memory used for thread stacks isn't "special" to the
kernel anyway, so there's no way to limit it by a stack ulimit. Of course,
it's all covered by vm and swapspace limits just as any other malloc,
valloc, or mmap memory.

On some systems, you may find that the stack ulimit sets an upper limit on
the size of EACH thread stack. For example, on Tru64 UNIX, a special kernel
syscall allocates a "stack VM object" that supports red and yellow zones
and uncommitted stack pages; the stack ulimit applies to these calls.

The standard doesn't really say anything about the relationship between the
ulimit and thread stacks. That is, setrlimit() defines that the stack limit
applies to "the process stack". It doesn't say if, or how, that applies to
additional thread stacks.

/--------------------[ David.B...@hp.com ]--------------------\
| Hewlett-Packard Company Tru64 UNIX & VMS Thread Architect |
| My book: http://www.awl.com/cseng/titles/0-201-63392-2/ |
\-------------[ http://homepage.mac.com/~dbutenhof ]--------------/

Mark Johnson

unread,
May 15, 2002, 9:42:04 AM5/15/02
to
"kjacks...@hotmail.com" wrote:
>
> Hi,
>
> I was wondering if someone could explain what the difference is
> between the "stack size" you see in ulimit -s and the thread stack
> size for pthreads, that you can set using pthread_attr_setstacksize.
>
Unless your system documentation says otherwise - there is no
relationship between these two parameters. The ulimit value is for the
"main program", the thread stack size is for each thread it is applied
to. A typical method of allocating stacks for threads is to use heap
storage (and not eat into the stack space of the main program).

--Mark

Mike Mowbray

unread,
May 15, 2002, 7:27:28 PM5/15/02
to
David Butenhof wrote:


> > [...] on Tru64 UNIX, a special kernel syscall allocates


> > a "stack VM object" that supports red and yellow zones

> > and uncommitted stack pages; [...]

I'm familiar with the concept of a "red" zone in Solaris,
but what exactly are "yellow" zones and "uncommitted
stack pages" ?


TIA,

- MikeM.


David Butenhof

unread,
May 16, 2002, 7:29:40 AM5/16/02
to
Mike Mowbray wrote:

One of the problems with guard pages is that it's hard for an application to
recover. That is, you're notified when you've reached the end of your
stack; but it takes stack to perform the notification and any recovery. So
guard pages (aka "red zone") protect the application from corruption due to
stack overflow, but don't help the application to recover gracefully... or
even to clean up and perform normal notification.

One solution is to have an alternate signal stack for every thread. But
there's no good way to size those stacks, you have to deal with all the
extra memory and management overhead... and of course POSIX and the Open
Group declined to require that alternate signal stacks will even work for
multiple threads (largely because some OS vendors had no interest in
implementing it). Worse, this effectively means that every thread's creator
must be prepared to deal with the situation. (While there would be ways for
a library that doesn't "own" the thread to add one, they're messy and
somewhat unreliable.)

The "yellow zone" is an attempt to improve on all that. It's essentially
another red zone to start with. Except that when the zone is "violated" by
stack incursion, it's changed to "green". This gives an extra page (or two,
or whatever is necessary) for the thread to handle the situation, either by
delivering a signal or raising an exception. Ideally, if the event is
cleanly handled, the yellow page(s) will be automatically "painted red"
again by the OS when the stack is unwound into the green zone. (Tru64 UNIX
works this way; OpenVMS, which also has yellow zone, doesn't convert a used
yellow page back to red.)

Uncommitted stack pages make large stacks practical. When you allocate a
stack with mmap() or valloc(), a kernel normally needs to allocate for you
that many swapfile pages to back dirty pages. Nowadays swap space is often
far more expensive than physical memory pages; and certainly far more
expensive than a page table entry with no physical page. While some threads
might eat a megabyte of stack, most won't; but it's hard to know when you
create a thread and flexibility is really nice. Uncommitted pages don't get
a physical page, or a swapfile page, until they're used; so Sun's 1Mb
stacks and Tru64's 5Mb stacks are essentially "free" except when the
threads really need that much stack... and then the cost is worthwhile.

Mike Mowbray

unread,
May 16, 2002, 7:46:08 PM5/16/02
to
> While explaining yellow and red zones, David Butenhof wrote:

> > The "yellow zone" is an attempt to improve on all that.
> > It's essentially another red zone to start with. Except
> > that when the zone is "violated" by stack incursion, it's

> > changed to "green". This gives an extra page [...] for
> > the thread to handle the situation, [...]. Ideally, if


> > the event is cleanly handled, the yellow page(s) will be
> > automatically "painted red" again by the OS when the stack
> > is unwound into the green zone.

I didn't quite understand that last bit about painting red "again".
The page began its life as yellow, then became temporarily green
when an incursion occurred. If the event is cleanly handled and
the offending thread unwinds its stack I would have thought that
the temporarily-green page should become yellow again, not red.
(?)


- MikeM.


Hillel Y. Sims

unread,
May 16, 2002, 11:06:54 PM5/16/02
to

"David Butenhof" <David.B...@compaq.com> wrote in message
news:EKME8.14$ns3.3...@cacnews.cac.cpqcorp.net...

>
> The "yellow zone" is an attempt to improve on all that. It's essentially
> another red zone to start with. Except that when the zone is "violated" by
> stack incursion, it's changed to "green". This gives an extra page (or
two,
> or whatever is necessary) for the thread to handle the situation, either
by
> delivering a signal or raising an exception. Ideally, if the event is
> cleanly handled, the yellow page(s) will be automatically "painted red"
> again by the OS when the stack is unwound into the green zone. (Tru64 UNIX
> works this way; OpenVMS, which also has yellow zone, doesn't convert a
used
> yellow page back to red.)

What kind of exception is thrown when you hit the yellow/red zone?

thanks,
hys

--
Hillel Y. Sims
hsims AT factset.com


Alexander Terekhov

unread,
May 18, 2002, 1:56:49 PM5/18/02
to
< cross-posted to comp.lang.c++ >

Whatever[1] is thrown, personally, I can't really COMPREHEND
how to deal with it... if it happens to occur invoking/inside
some NOTHROW call, I mean.

Perhaps someone could help me. PLEASE. TIA.

regards,
alexander.

[1]
http://groups.google.com/groups?selm=c29b5e33.0202161451.2ef75f1f%40posting.google.com

"Herb Sutter <hsu...@acm.org> wrote in message
news:<jtas6uggftq6lt2o3...@4ax.com>...
[...]
> Yes, but you can have the nothrow guarantee whether the exception
> specification says so or not. In fact, I usually write declarations
for such
> functions like this: "X f( Y ) // throw()".

And who is protecting your clients from really bad
things (exceptions/faults) along the lines of:


http://www.tru64unix.compaq.com/docs/base_doc/DOCUMENTATION/V51_HTML/ARH9RBTE/DOCU0011.HTM#excep_defs
...."

< NO answer from Mr. Sutter... yet.. here is @ *MICROSOFT* now, BTW >

From the URL above:

"....
pthread_stackovf_e Attempted stack overflow was detected
...."

http://www.tru64unix.compaq.com/docs/base_doc/DOCUMENTATION/V51A_PDF/ARH9RBTE.PDF
("Tru64 UNIX|Guide to the POSIX Threads Library")

"....
A guard area, with its associated overflow warning area,
can help a multithreaded program detect overflow of a
thread's stack. A guard area is a region of no-access
memory that the Threads Library allocates at the overflow
end of the thread's stack, following the thread's overflow
warning area. If the thread attempts to write in the
overflow warning area, a stack overflow exception occurs.
Your program can catch this exception and continue
processing as long as the thread does not attempt to
write in the guard area. When any thread attempts to
access a memory location within the guard area, a memory
addressing violation occurs without the possibility of
recovery.
...."

Well, I'm surely missing something here... but without
C++-like EXCEPTION SPECIFICATIONS "fences" (especially
for NOTHROW calls -- throw(), I mean... and *including/
fencing the parms/args: foo( *...PARMS...* ) throw(),
I guess, BTW), "blind" unwinding on stack overflow fault
is just an invitation for even more troubles, I'm afraid.

Unless it is known for sure that a) stack overflow
exception could indeed be thrown from the point of fault
and b) it's really EXPECTED -- there is some matching
catch handler "waiting" for it... invoking C++ terminate()
handlers instead at "throw" point (for emergency inter-
process cleanup stuff) would seem MUCH more reasonable
to me...

Or am I wrong, folks?

Hillie

unread,
May 23, 2002, 2:43:14 AM5/23/02
to
If you allocate a new stack then do you need to link it somehow to the
process descriptor? I have the problem that after creating a new thread with
its own new stack in heap storage, the functionals like malloc, printf,
open, do not work anymore. These functions require the process context. How
does this work?

Gerald.


"Mark Johnson" <mark_h_...@raytheon.com> wrote in message
news:3CE265AC...@raytheon.com...

Mark Johnson

unread,
May 23, 2002, 10:14:28 AM5/23/02
to
Hillie wrote:
>
> If you allocate a new stack then do you need to link it somehow to the
> process descriptor? I have the problem that after creating a new thread with
> its own new stack in heap storage, the functionals like malloc, printf,
> open, do not work anymore. These functions require the process context. How
> does this work?
>
That should be transparent to the application. What you describe
(functions do not work) is likely caused by
- not linking with the reentrant versions of the run time library OR
- a more general memory corruption problem
To solve the first, you need to build with a switch like -pthread [e.g.,
recent gcc versions] or the appropriate macro and library settings for
your system. An example from an HP system could be...
aCC -D_POSIX_C_SOURCE+199506L prog.c -lpthread -D_REENTRANT
which specifies both compiler options and the thread safe libraries.

To solve the second, you need to review the application carefully for
causes such as inappropriate use of pointers or out of bounds array
references.
--Mark

David Butenhof

unread,
May 29, 2002, 9:23:56 AM5/29/02
to
Mike Mowbray wrote:

A terminology shortcut. I apologize. "Yellow" is, in essense, "red that's
[temporarily] convertable to green". If color refers to page protection (as
I meant in that context), then "yellow" is an abstract designation for a
page that is, in practice, always either red or green. The "yellow" page
starts red, and is made green to deliver a stack protection violation.
Ideally, the system retains the "yellow" designation and eventually
re-protects the page ("painting it red"). OpenVMS does not, and once it's
been "painted green" it becomes an ordinary stack page.

Sorry this reply is a bit late... but, for the record, I do have a good
excuse. From early May 16 through late May 23, I was mostly camped out in
the Dartmouth-Hitchcock Medical Center's pediatric intensive care unit
watching over my 9 year old daughter... and then going through "basic
training" to deal with the previously undiagnosed diabetes that had lead to
her collapse from unprecedentedly severe DKA [diabetic keto-acidosis].
Yesterday was my first day back at work, (and, I'm happy to report, her
first day back at school after a complete recovery)... but I didn't have a
chance to get at news until today.

--

David Butenhof

unread,
May 29, 2002, 9:26:37 AM5/29/02
to
Hillel Y. Sims wrote:

Normally, a simple SIGSEGV signal. In a system with exception support,
though, you might raise an exception. It really doesn't matter; the
important thing is that the application can deal with a stack overflow "in
context" instead of arbitrarily blowing away the process. Perhaps the
latter would really be better since there's probably not much the
application can really do. Still, people love the illusion of being able to
"handle" memory problems, and complain when they're not allowed to fool
themselves. ;-)

--

Reply all
Reply to author
Forward
0 new messages