Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Apr 2000 19:32:46 +0200 (CEST)
From:      cejkar@dcse.fee.vutbr.cz
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/18099: Bug-fixes to pthread_cond_*() (uthread_cond.c)
Message-ID:  <200004191732.e3JHWko12798@kazi.dcse.fee.vutbr.cz>

next in thread | raw e-mail | index | archive | help

>Number:         18099
>Category:       bin
>Synopsis:       Bug-fixes to pthread_cond_*() (uthread_cond.c)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 19 10:40:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Rudolf Cejka
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
Brno University of Technology, FEE&CS, Czech Republic
>Environment:

5.0-CURRENT and possibly all other branches.

>Description:

Here is small testing program (-pthread):

--
#define _THREAD_SAFE
#include <err.h>
#include <pthread.h>
#include <stdio.h>

pthread_t	tid;

pthread_cond_t	cond = PTHREAD_COND_INITIALIZER;

/* ARGSUSED */
void *test(void *dummy)
{

	if (pthread_cond_broadcast(&cond) != 0)
		warnx("pthread_cond_broadcast()");
	if (pthread_cond_timedwait(&cond, NULL, NULL) != 0)
		warnx("pthread_cond_timedwait()");
	return NULL;
}

int main(void)
{

	if (pthread_create(&tid, NULL, test, NULL) != 0)
		errx(1, "pthread_create()");
	if (pthread_join(tid, NULL) != 0)
		errx(1, "pthread_join()");
	return 0;
}
--

According to standards, pthread_cond_broadcast() should do nothing
without any error. And I think pthread_cond_timedwait() should not
produce a coredump. But if you run it, you get:

--
tst: pthread_cond_broadcast()
Segmentation fault (core dumped)
--

If you apply following patch, you get only:

--
tst: pthread_cond_timedwait()
--

a) pthread_cond_broadcast() will not produce any error: the problem
   occurs only when condition is initialized statically and have not
   been used (= allocated) before - maybe this is artifical example, but
   I had a problem with this in a real situation (on Solaris it works
   fine but on FreeBSD before patch it doesn't)

   (second and third chunk of patch for pthread_cond_signal() and
   pthread_cond_broadcast() functions)

b) pthread_cond_timedwait() will produce error only instead of coredump;
   if you look into sources, it really looks as a copy & paste & insert bug

   (first chunk of patch)

>How-To-Repeat:
>Fix:

--- src/lib/libc_r/uthread/uthread_cond.c.orig	Wed Apr 19 18:52:04 2000
+++ src/lib/libc_r/uthread/uthread_cond.c	Wed Apr 19 18:52:04 2000
@@ -308,19 +308,14 @@
 	
 	if (cond == NULL || abstime == NULL)
 		rval = EINVAL;
-
-	if (abstime->tv_sec < 0 || 
-		abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) {
-		errno = EINVAL;
-		_thread_leave_cancellation_point();
-		return (-1);
-	}
-
+	else if (abstime->tv_sec < 0 || 
+		abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+		rval = EINVAL;
 	/*
 	 * If the condition variable is statically initialized,
 	 * perform the dynamic initialization:
 	 */
-	if (*cond != NULL ||
+	else if (*cond != NULL ||
 	    (rval = pthread_cond_init(cond,NULL)) == 0) {
 
 		_thread_enter_cancellation_point();
@@ -473,9 +468,14 @@
 	int             rval = 0;
 	pthread_t       pthread;
 
-	if (cond == NULL || *cond == NULL)
+	if (cond == NULL)
 		rval = EINVAL;
-	else {
+	/*
+	 * If the condition variable is statically initialized,
+	 * perform the dynamic initialization:
+	 */
+	else if (*cond != NULL ||
+	    (rval = pthread_cond_init(cond, NULL)) == 0) {
 		/*
 		 * Defer signals to protect the scheduling queues
 		 * from access by the signal handler:
@@ -525,9 +525,14 @@
 	int             rval = 0;
 	pthread_t       pthread;
 
-	if (cond == NULL || *cond == NULL)
+	if (cond == NULL)
 		rval = EINVAL;
-	else {
+	/*
+	 * If the condition variable is statically initialized,
+	 * perform the dynamic initialization:
+	 */
+	else if (*cond != NULL ||
+	    (rval = pthread_cond_init(cond,NULL)) == 0) {
 		/*
 		 * Defer signals to protect the scheduling queues
 		 * from access by the signal handler:


>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200004191732.e3JHWko12798>