Skip site navigation (1)Skip section navigation (2)
Date:      Wed,  3 Nov 1999 07:48:46 -0800 (PST)
From:      xfb52@dial.pipex.com
To:        freebsd-gnats-submit@freebsd.org
Subject:   kern/14685: setjmp/longjmp in threaded app cause subsequent read to run forever
Message-ID:  <19991103154846.E1DA914DBD@hub.freebsd.org>

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

>Number:         14685
>Category:       kern
>Synopsis:       setjmp/longjmp in threaded app cause subsequent read to run forever
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Nov  3 07:50:00 PST 1999
>Closed-Date:
>Last-Modified:
>Originator:     Alex Zbyslaw
>Release:        3.2
>Organization:
>Environment:
FreeBSD stimpy 3.2-RELEASE FreeBSD 3.2-RELEASE #3: Tue Oct 26 19:23:46 BST 1999     alex@stimpy:/usr/src/sys/compile/SHERPA  i386

>Description:
If a program linked against libc_r is looping on a read, the read is
interrupted, and the signal handler uses a longjmp to jump back
to just before the read, the read call will go into an infinite loop.

As far as I have trace it, everything goes wrong somewhere in 
_thread_kern_poll

This is a big problem (for me) as this is exactly how python interacts
libreadline.


>How-To-Repeat:
Compile the following program
e.g. gcc -pthread -o readtest readtest.c

Type a few keys to see that it is working OK, and then press ^C.

I used ktrace/kdump -l to watch what happened when keys were pressed
and when ^C was pressed.  After a keypress the process ends up doing a
gettimeofday() and then a poll() but after a ^C it does the
gettimeofday() but never reaches a poll.  top shows it in a RUN state
chewing up mucho CPU.

#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>
#include <signal.h>
#include <setjmp.h>

extern int errno;
static jmp_buf jbuf;

void
onintr()
{
  printf("\nCAUGHT INT\n");
  longjmp(jbuf, 1);
}

int
main (argc, argv)
     int argc;
     char **argv;
{
  unsigned char c;
  int result;
  int flags;
  struct termios tio;
  struct sigaction act;

  act.sa_handler = onintr;
  act.sa_mask = SIGINT;
  act.sa_flags = 0;

  sigaction(SIGINT, &act, NULL);


  
  tcgetattr(fileno(stdin), &tio);
  tio.c_lflag &= ~(ICANON);

  tcsetattr(fileno(stdin), TCSANOW, &tio);
  

  while (1) {
    if (setjmp(jbuf)) {
      printf("\nIN SETJMP\n");
    }


    result = read(fileno(stdin), &c, sizeof(unsigned char));
    
    if (result == 0 || c == 4) {
      printf ("\nEOF\n");
      exit (0);
    }

    if (result == sizeof(unsigned char)) {
      printf ("\nREAD: %c\n", c);
      continue;
    }

    printf ("\nERROR: %s\n", strerror(errno));
  }
}


>Fix:


>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?19991103154846.E1DA914DBD>