[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: pthreads, stack buffers, read and recv on OpenBSD 3.1



On Friday, July 26, 2002, at 11:06  PM, Andy Fripp wrote:

> Hi,
>
> I have a tcp sockets based client server application
> that fails to work on OpenBSD 3.1.  It is using
> posix threads and I suspect that this is where the
> problem lies.  I have created a very cut down version
> of the program to reproduce the problem - it is at the
> foot of this e-mail.
>
> The original program was written on SunOS 5.8 and
> successfully ported to recent versions of IRIX, AIX,
> Linux and HP-UX - it works fine on all of these.
>
> Attached are two programs - a very simple client and
> server and a make file to build them.  The server built
> without using threads "tserv" works fine when "tclient" is run
> but the version built with pthreads returns "Bad address"
> (EFAULT) on recv (or read) when "tclient" is run.
> However, it is sensitive to the stack allocated buffer size.
> If the buffer size is 73000 bytes and read size is 64000
> it fails (EFAULT) but, strangley, it succeeds if the buffer
> size is bigger (100000 bytes) and read size 73000.
>
> Many thanks to anyone who takes a look at this.
>
> Andy Fripp
>

Hi,

You can simplify the test by adding memset(buffer, 0, BIGBUFSIZ); in 
recvTest. This causes an immediate SEGV. Then you would have seen that 
part of your buffer is outside the stack. Apart from that, in a lot of 
cases you do want to clear any old date data may be there.

Why you do not get the error immediately with a bigger buffer size I 
don't know. But you can bet that the moment the kernel socket buffer 
space is increased, so you get more data in recv, you would have gotten 
the error.


The fix is easy:

	pthread_attr_t attrs;
	size_t stack_size;
	pthread_attr_init(&attrs);
	pthread_attr_getstacksize(&attrs, &stack_size);
	pthread_attr_setstacksize(&attrs, stack_size + BIGBUFSIZ);
	printf("new thread %u\n", stack_size);
	pthread_create(&newThreadId,&attrs,recvTest,&cfd);

This code allocates a stack that is probably too big. But for reasonable 
buffer sizes, this doesn't hurt.

Cheers, Otto