Re: select() clobbering the timeout

Forever shall I be. (UncleanOne@zerg.com)
Mon, 10 May 1999 15:14:40 -0500


First let me say relying on the value of timeout in any way
can be hazardous to your health; it't extremele non-portable.
With that said, if timeout returns > 0 and it's a linux
system, timeout will contain the time left before the call
would have timed out, otherwise it's pretty much undefined,
so don't expect it to be anything :)

Roger Espel Llima wrote:
>
> I recently came across something strange on one Linux server: select()
> calls that time out suddenly started clobbering the timeout value with
> garbage.
>
> This is a UP P-II running kernel 2.0.35, with an uptime of 254 days.
> It's also a production server, and it's otherwise running fine. The
> weird behavior only started 5 days ago, and we only noticed it because
> it made zsh appear to hang.
>
> Now it's predictable: a test program shows that select() clobbers the
> timeout value everytime the timeout expires, but not when it returns
> early (because of input or a singal). I've single-stepped through the
> disassembly of select() in libc, and it appears clearly that the
> clobbering must happen in the kernel itself. I can't reproduce it on
> any other kernel, but then again, that 2.0.35 took 8 months to start
> doing it.
>
> I'm posting this not to ask for a fix, but just in case someone gets
> inspired to look at it, or can quickly say "that got fixed in 2.0.36" or
> whatever ...
>
> Here's some test code:
>
> #include <stdio.h>
> #include <sys/types.h>
> #include <sys/time.h>
> #include <signal.h>
> #include <unistd.h>
>
> void catchasignal() { }
>
> int main(int argc, char **argv) {
> struct timeval tv;
> fd_set s;
>
> signal(SIGINT, catchasignal);
> tv.tv_sec = atoi(argv[1]);
> tv.tv_usec = atoi(argv[2]);
> FD_ZERO(&s);
> FD_SET(0, &s);
> printf("tv_sec = %ld, tv_usec = %ld\n", (long)tv.tv_sec, (long)tv.tv_usec);
> select(1, &s, NULL, NULL, &tv);
> printf("tv_sec = %ld, tv_usec = %ld\n", (long)tv.tv_sec, (long)tv.tv_usec);
> return 0;
> }
>
> and its output on the misbehaving kernel:
>
> $ ./mintest 0 1000
> tv_sec = 0, tv_usec = 1000
> tv_sec = 20936492, tv_usec = 650000
> $ ./mintest 1 0
> tv_sec = 1, tv_usec = 0
> tv_sec = 20936484, tv_usec = 550000
> $ ./mintest 2 0
> tv_sec = 2, tv_usec = 0
> ^C
> tv_sec = 1, tv_usec = 570000
>
> --
> Roger Espel Llima, espel@llaic.u-clermont1.fr
> http://www.eleves.ens.fr:8080/home/espel/index.html
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.rutgers.edu
> Please read the FAQ at http://www.tux.org/lkml/

-- 
Zinx Verituse
pgp key fingerprint: 9F E5 C9 74 7E B8 FF 32  9B B1 31 99 C4 00 8E 67
gpg key fingerprint: B907 8474 62E3 3432 2EBC  2197 A245 4F19 9314 0EFD
(finger @bliss.penguinpowered.com for keys, when applicable..)

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/