Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sun, 31 Mar 2013 14:07:17 -0400
From: Rich Felker <dalias@...ifal.cx>
To: musl@...ts.openwall.com
Subject: Re: pthread_getattr_np

On Sun, Mar 31, 2013 at 07:35:19PM +0200, Szabolcs Nagy wrote:
> pthread_getattr_np is used by some libs (gc, sanitizer) to get the
> beginning of the stack of a thread
> 
> it is a gnu extension but bsds have similar non-portable functions
> (none of them are properly documented)
> 
> glibc: pthread_getattr_np
> freebsd: pthread_attr_get_np
> netbsd: pthread_attr_get_np and pthread_getattr_np
> openbsd: pthread_stackseg_np
> osx: pthread_get_stackaddr_np, pthread_get_stacksize_np
> solaris: thr_stksegment
> hp-ux: _pthread_stack_info_np
> 
> (glibc and freebsd use locks to synchronize the reading of
> thread attributes, may matter for detach state)
> (glibc and openbsd try to get correct info for the main
> stack others don't)
> 
> returning reasonable result for the main stack is not trivial
> (the stack starts at some unspecified address and can grow downward
> until the stack rlimit or some already mmapped region is hit)
> 
> possible ways to get the top of the main thread stack:
> 
> 1) /proc/self/maps (fopen,scanf,.. this is precise, glibc does this)
> 
> 2) save the top address of the stack at libc entry somewhere
> (eg by keeping a pointer to the original environ which is high
> up the stack) this is a good approximation but underestimates
> top by a few pages
> 
> 3) the previous approach can be tweaked: the real top is close
> so the next few pages can be checked if they are mapped (eg with
> madvise) and we declare the address of the first unmapped page
> as the top (usually this gives precise result, but when the pages
> above the stack are mapped it can overestimate top by a few pages)
> 
> then the stack is [top-rlimit,top]
> (the low end should be tweaked when it overlaps with existing
> mappings, the current sp is below it or rlimit is unlimited)

Getting the high address (or "top" as you've called it) is trivial;
your efforts to find the end of the last page that's part of the
"stack mapping" are unnecessary. Any address that's past the address
of any automatic variable in the main thread, but such that all pages
between are valid, is a valid choice for the upper-limit address. The
hard part is getting the lower-limit. The rlimit is not a valid way to
measure this. For example, rlimit could be unlimited, or the stack
might have already grown large before the rlimit was reduced.

In practice, it seems like GC applications only care about the start
(upper limit) of the stack, not the other end; they use the current
stack pointer for the other limit. We could probe the current stack
pointer of the target thread by freezing it (with the synccall magic),
but this seems like it might be excessively costly for no practical
benefit...

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.