pthread stack allocation

I’m writing a net filter to be plugged into io-net. The filter spawns four
worker pthreads that go merrily on their way. One of the threads is crashing
in a function prologue at an x86 push instruction and taking down the entire
io-net process. This seems indicative of a stack overrun. I don’t know much
about QNX’s thread stack allocation. By default it looks like
pthread_attr_setstacklazy() means that the stack allocation is totally
dynamic, and that a stack overrun is impossible.

By experiment, so far I’ve found that neither _POSIX_THREAD_ATTR_STACKSIZE
nor PTHREAD_STACK_MIN are defined. pthread_attr_getstacksize also always
returns a stack size of 0.

How does QNX’s pthread stack allocation actually work?

Thanks,
Shaun

“Shaun Jackman” <sjackman@nospam.vortek.com> wrote in
news:ad3gb9$2j6$1@inn.qnx.com:

I’m writing a net filter to be plugged into io-net. The filter spawns
four worker pthreads that go merrily on their way. One of the threads
is crashing in a function prologue at an x86 push instruction and
taking down the entire io-net process. This seems indicative of a stack
overrun. I don’t know much about QNX’s thread stack allocation. By
default it looks like pthread_attr_setstacklazy() means that the stack
allocation is totally dynamic, and that a stack overrun is impossible.

By experiment, so far I’ve found that neither
_POSIX_THREAD_ATTR_STACKSIZE nor PTHREAD_STACK_MIN are defined.
pthread_attr_getstacksize also always returns a stack size of 0.

How does QNX’s pthread stack allocation actually work?

Frames which are destined for stack allocation are faulted in at access
time.

If you wish, take a look at pthread_attr_setstacklazy() and use non-lazy.

\

Cheers,
Adam

QNX Software Systems Ltd.
[ amallory@qnx.com ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <pschon@baste.magibox.net>

I’ve done some investigation and answered the majority of my questions. I’m
posting my results here in case someone else is curious.

unistd.h:#define _POSIX_THREAD_ATTR_STACKSIZE 1
limits.h:#define PTHREAD_STACK_MIN 64

As far as I know a minimum of one page (4kB) is awlays allocated regardless
of what stack size you ask for. If you set the stack size less than
PTHREAD_STACK_MIN, pthread_create() returns EINVAL.
pthread_attr_getstacksize() will return 0 if pthread_attr_setstacksize()
wasn’t called, otherwise it will return whatever value was passed to
pthread_attr_setstacksize().

The first thread main() gets a default stack limit of 512kB. Every
subsequent thread has a stack limit of 128kB. When writing a net ddk filter,
for some reason the thread you’re running in has a limit of 12kB. These are
hard upper limits on the size of the stack. The stack will fault in pages as
necessary as the stack grows. If it grows higher than this limit the app
will die with a SIGSEGV. Using alloca() to create more memory than the size
of the stack results in undefined behaviour according to POSIX. In QNX the
process gets hit with a SIGSEGV.

Cheers,
Shaun

Shaun Jackman <sjackman@nospam.vortek.com> wrote:

I’ve done some investigation and answered the majority of my questions. I’m
posting my results here in case someone else is curious.

unistd.h:#define _POSIX_THREAD_ATTR_STACKSIZE 1
limits.h:#define PTHREAD_STACK_MIN 64

As far as I know a minimum of one page (4kB) is awlays allocated regardless
of what stack size you ask for.

You can have a smaller stack, if you explicitly allocate the stack
yourself (with say malloc) then point set both the stack address and
stack size.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.