Linux current_stack_region()

Gary Benson gbenson at
Tue Mar 11 02:32:57 PDT 2008

David Holmes wrote:
> Gary Benson said the following on 11/03/08 01:06 AM:
> > The first thing I discovered is that the current linux code is wrong
> > when there are guard pages.  The comment above current_stack_region
> > in os_linux_{i486,amd64,x86}.cpp puts the guard page outside the
> > region reported by pthread_attr_getstack(), which is not the case.
> Reading the POSIX specification I don't see anything that
> explicitly states this, but I would infer that the guard pages are
> not part of the region reported by pthread_attr_getstack from the
> statement:
> "The stack attributes specify the area of storage to be used for
> the created thread's stack."
> i.e. getstack reports the _usable_ stack for the thread. Hence any
> guard region is outside that.

That was how I understood it at first, but this is very definitely not
the case with glibc.  The glibc implementation takes the view that if
a thread asks for X bytes of stack then it will get a region X bytes
in size -- regardless of how that is then parcelled out.

The ia64 case makes it a bit clearer, for me at least.  ia64 has two
stacks, both of which share the same region of memory.  There's a
normal stack which grows downwards, and a register stack which grows
upwards.  Guard pages, when specified, go in the middle.  You can't
really compensate for this without also compensating for the register
stack, so you'd have this extra, unreported region (and threads
silently allocating twice as much memory as you expected them to).
It's awkward whichever way you decide to interpret the spec.

> > I started modifying current_stack_region to do just that, but its
> > comments contain warnings that pthread_getattr_np() returns bogus
> > values for initial threads.  os::Linux::capture_initial_stack()
> > has more such warnings, though neither mentions exactly _what_ was
> > bogus.  Does anyone know?  Without a working pthread_getattr_np()
> > you can't use pthread_attr_getguardsize(), and without that it's
> > not possible to implement current_stack_region() in the form it's
> > currently defined.
> The comment re pthread_getattr_np is about 5 years old and I
> couldn't find anything more specific than the inference that they
> discovered that it returned the wrong values on the initial thread
> on the distributions of the day (whatever they may have
> been). Hotspot is full of this kind of historical baggage with
> workarounds for a range of now defunct linux systems (and old
> Solaris versions too).


> Note also that pthread_attr_setguardsize may internally round-up the
> guardsize to a multiple of page-size; but pthread_attr_getguardsize
> returns the original supplied value not the rounded one. So you
> would have a problem trying to adjust for the true guardsize in a
> portable way.

No, this only matters if the pthread_attr_t you're using is the same.
If you create one using pthread_attr_init() then yes, the value
returned by pthread_attr_getguardsize() will be exactly the value you
set with pthread_attr_setguardsize().  The pthread_attr_t returned by
pthread_getattr_np(), however, is created from the actual properties
of the thread, so it contains the actual guard size in use.



More information about the hotspot-dev mailing list