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>
index | next in thread | raw e-mail
>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
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991103154846.E1DA914DBD>
