Bug 5329 - pthread_cond_timedwait returns EINTR in multithreaded processes when gdb is attached to them
Summary: pthread_cond_timedwait returns EINTR in multithreaded processes when gdb is a...
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: glibc
Version: 6.0
Hardware: i386
OS: Linux
high
high
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 1999-09-23 15:42 UTC by greg
Modified: 2008-05-01 15:37 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2003-01-24 18:25:06 UTC
Embargoed:


Attachments (Terms of Use)

Description greg 1999-09-23 15:42:24 UTC
this silly little test program demonstrates a bug in the
interaction between
GNU gdb 4.17.0.11 with Linux support as shipped with Red
Hat Linux 6.0 and
LinuxThreads-0.8 as built into glibc 2.1.1-6 as shipped
with Red Hat Linux
6.0.  when this test program is run outside of the
debugger, it performs
as expected.  when it is run from within gdb (even with no
breakpoints set),
the call to pthread_cond_timedwait returns immediately with
EINTR.  this
seems to be a result of nanosleep(2) returning as the
result of a
non-blocked signal being sent to the thread.  from nanosleep
(2):

      EINTR   The  pause  has  been interrupted by a non-
blocked
              signal that was  delivered  to  the
process.  The
              remaining sleep time has been written into
*rem so
              that the process can easily call  nanosleep
again
              and continue with the pause.

i could throw out a guess that linuxthreads and gdb talk to
each other using
signals, and this is causing nanosleep to return.  this,
however, is just a
guess.

greg thompson <greg>

Comment 1 greg 1999-09-23 15:54:59 UTC
forgot to put in the test prog...

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1999-09-23 11:34 EDT by <greg>.
# Source directory was `/home/greg/testcond'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#    198 -rw-r--r-- Makefile
#   3019 -rw-r--r-- testcond.c
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File
Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh22314; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= Makefile ==============
if test -f 'Makefile' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'Makefile' '(file already exists)'
else
  $echo 'x -' extracting 'Makefile' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
# Makefile for testcond
X
CC = gcc
CFLAGS = -Wall -ggdb
CPPFLAGS = -D_REENTRANT
X
X.PHONY : all clean
X
all : testcond
X
clean :
X	rm testcond.o testcond
X
testcond : testcond.o
X	$(CC) $^ -o $@ -lpthread
SHAR_EOF
  $shar_touch -am 0923113299 'Makefile' &&
  chmod 0644 'Makefile' ||
  $echo 'restore of' 'Makefile' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null;
then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'Makefile:' 'MD5 check failed'
44277dee9de52b323807a8f210f5f8eb  Makefile
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`"
    test 198 -eq "$shar_count" ||
    $echo 'Makefile:' 'original size' '198,' 'current
size' "$shar_count!"
  fi
fi
# ============= testcond.c ==============
if test -f 'testcond.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'testcond.c' '(file already exists)'
else
  $echo 'x -' extracting 'testcond.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'testcond.c' &&
/*
X * testcond.c
X *
X * this silly little test program demonstrates a bug in the
interaction between
X * GNU gdb 4.17.0.11 with Linux support as shipped with Red Hat
Linux 6.0 and
X * LinuxThreads-0.8 as built into glibc 2.1.1-6 as shipped with Red
Hat Linux
X * 6.0.  when this test program is run outside of the debugger, it
performs
X * as expected.  when it is run from within gdb (even with no
breakpoints set),
X * the call to pthread_cond_timedwait returns immediately with
EINTR.  this
X * seems to be a result of nanosleep(2) returning as the result of a
X * non-blocked signal being sent to the thread.  from nanosleep(2):
X *
X *       EINTR   The  pause  has  been interrupted by a non-blocked
X *               signal that was  delivered  to  the  process.  The
X *               remaining sleep time has been written into *rem so
X *               that the process can easily call  nanosleep  again
X *               and continue with the pause.
X *
X * i could throw out a guess that linuxthreads and gdb talk to each
other using
X * signals, and this is causing nanosleep to return.  this, however,
is just a
X * guess.
X *
X * greg thompson <greg>
X * 1999-09-22
X */
X
#include <stdio.h>
#include <sys/time.h>
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
X
#define DUMMIES 1
X
X
static void *dummyMain(
X    void			*arg
X    )
{
X    sem_wait((sem_t *) arg);
X
X    return NULL;
}
X
X
int main(
X    int				 argc,
X    char			*argv[]
X    )
{
X    struct timeval		 v1, v2;
X    struct timespec		 t;
X    sem_t			 sem;
X    pthread_t			 threads[DUMMIES];
X    int				 i;
X    pthread_mutex_t		 m;
X    pthread_cond_t		 c;
X    int				 e;
X
X    /*
X     * first, create a semaphore for the dummy threads, then spawn
off the
X     * dummies
X     */
X
X    sem_init(&sem, 0, 0);
X
X    for (i = 0; i < DUMMIES; ++i)
X	pthread_create(&threads[i], NULL, dummyMain, &sem);
X
X    /*
X     * next, setup a mutex and a condition variable and sleep for
five seconds
X     * by waiting on the condition variable.
X     */
X
X    pthread_mutex_init(&m, NULL);
X
X    pthread_cond_init(&c, NULL);
X
X    pthread_mutex_lock(&m);
X
X    gettimeofday(&v1, NULL);
X
X    TIMEVAL_TO_TIMESPEC(&v1, &t);
X
X    t.tv_sec += 5;
X
X    e = pthread_cond_timedwait(&c, &m, &t);
X
X    /*
X     * display the amount of time that has past since we went to
sleep
X     */
X
X    gettimeofday(&v2, NULL);
X
X    printf("%s : slept for %ld.%ld seconds\n",
X	   (e == ETIMEDOUT ? "cv timed out" :
X	    (e == 0 ? "cv signalled" :
X	     (e == EINTR ? "thread interrupted" : "unknown reason"))),
X	   v2.tv_sec - v1.tv_sec, v2.tv_usec - v1.tv_usec);
X
X    /*
X     * cleanup the mutex and condition variable
X     */
X
X    pthread_mutex_unlock(&m);
X
X    pthread_cond_destroy(&c);
X
X    pthread_mutex_destroy(&m);
X
X    /*
X     * bring the dummy threads back in and cleanup the semaphore
X     */
X
X    for (i = 0; i < DUMMIES; ++i)
X	sem_post(&sem);
X
X    for (i = DUMMIES - 1; i >= 0; --i)
X	pthread_join(threads[i], NULL);
X
X    sem_destroy(&sem);
X
X    /*
X     * get out.
X     */
X
X    return 0;
}
SHAR_EOF
  $shar_touch -am 0923113099 'testcond.c' &&
  chmod 0644 'testcond.c' ||
  $echo 'restore of' 'testcond.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null;
then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'testcond.c:' 'MD5 check failed'
f7f249f4cf281eef2a4d4522775ed7f8  testcond.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'testcond.c'`"
    test 3019 -eq "$shar_count" ||
    $echo 'testcond.c:' 'original size' '3019,' 'current
size' "$shar_count!"
  fi
fi
rm -fr _sh22314
exit 0

Comment 2 Cristian Gafton 2000-05-22 14:53:59 UTC
assign to jakub

Comment 3 Stephen John Smoogen 2003-01-24 18:25:06 UTC
Bug 5329 has been closed due to the fact that most of the problem products are
no longer supported by Red Hat. If the problem can be shown to occur in the
8.0.93 Phoebe release, it would be better to open a new ticket against that
release as the NPTL threading code uses different syntax and would get faster
looking at.


Note You need to log in before you can comment on or make changes to this bug.