Roberto Lumbreras <ro...@debian.org> writes:

> timeout is defined as "struct timeval":
>
>        struct timeval {
>            time_t       tv_sec;   /* Seconds */
>            suseconds_t  tv_usec;  /* Microseconds */
>        };
>
> timeout.tv_used is suseconds_t == time_t == int, so I can't understand
> why it's unsigned in your case.

Hi Roberto,

I probably missed the starting 's', suseconds_t is indeed documented as
signed, and is actually a long int here.  So my patch shouldn't work.
What's sure:

# gdb slirp
GNU gdb (Debian 13.1-3) 13.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from slirp...
Reading symbols from 
/usr/lib/debug/.build-id/e1/1ce5371d887d06c3b97a0c6a68463ba1cc8bcf.debug...
(gdb) b main.c:960
Breakpoint 1 at 0x1408b: file ./main.c, line 960.
(gdb) r
Starting program: /usr/bin/slirp 
warning: Error disabling address space randomization: Operation not permitted
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Slirp v1.0.17 (BETA)

Copyright (c) 1995,1996 Danny Gasparovski and others.
All rights reserved.
This program is copyrighted, free software.
Please read the file COPYRIGHT that came with the Slirp
package for the terms and conditions of the copyright.

IP address of Slirp host: 172.17.0.2
IP address of your DNS(s): 10.12.1.5, 10.10.1.10
Your address is 10.0.2.15
(or anything else you want)

Type five zeroes (0) to exit.

[autodetect SLIP/CSLIP, MTU 1500, MRU 1500, 115200 baud]

SLiRP Ready ...

Breakpoint 1, main_loop () at ./main.c:960
warning: Source file is more recent than executable.
960             ret = select(nfds+1, &readfds, &writefds, &xfds, &timeout);
(gdb) p timeout
$1 = {tv_sec = 0, tv_usec = 4294967295}
(gdb) p/x timeout.tv_usec
$2 = 0xffffffff
(gdb) p nfds
$3 = 0
(gdb) n
962             if (ret < 0) {
(gdb) p ret
$4 = -1
(gdb) p errno
$5 = 22
(gdb) n
963                     if (errno == EINTR)
(gdb) 
965                     slirp_exit(1);
(gdb) 
[Inferior 1 (process 4349) exited with code 01]

> If you dig in src/main.c there are more lines with timeout.tv_used
> being compared with negative numbers, your patch may work but I think
> it has to be something else.

Yes, I've got another theory now: timeout.tv_usec is a long int of
8 bytes size, but at main.c:935 it gets assigned a 4-byte unsigned:

if ((timeout.tv_usec < 0) || (tmp_time >= 0 && tmp_time < timeout.tv_usec))
        timeout.tv_usec = (u_int)tmp_time;

This results in the value of 4294967295 above instead of the expected
-1, so timeout does not get reset to {5, 0} and select() gets the
invalid timeout value, immediately breaking the loop.

> Have you tried just compiling the slirp package? Maybe it's a problem
> with libc6 linking, https://tracker.debian.org/pkg/slirp warns that
> slirp "Fails to build during reproducibility testing". I'm looking
> into this.

Reproducibility probably does not factor into this, but I'll do some
more checks as I get to it.
-- 
Regards,
Feri.

Reply via email to