This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] Implement IPv6 support for GDB/gdbserver
On Friday, June 08 2018, Pedro Alves wrote:
> On 06/08/2018 06:47 PM, Sergio Durigan Junior wrote:
>> On Friday, June 08 2018, Pedro Alves wrote:
>
>>>>> Does connecting with "localhost6:port" default to IPv6, BTW?
>>>>> At least fedora includes "localhost6" in /etc/hosts.
>>>>
>>>> Using "localhost6:port" works, but it doesn't default to IPv6. Here's
>>>> what I see on the gdbserver side:
>>>>
>>>> $ ./gdb/gdbserver/gdbserver --once localhost6:1234 a.out
>>>> Process /path/to/a.out created; pid = 7742
>>>> Listening on port 1234
>>>> Remote debugging from host ::ffff:127.0.0.1, port 39196
>>>>
>>>> This means that the connection came using IPv4; it works because IPv6
>>>> sockets also listen for IPv4 connection on Linux (one can change this
>>>> behaviour by setting the "IPV6_V6ONLY" socket option).
>>>>
>>>> This happens because I've made a decision to default to AF_INET (instead
>>>> of AF_UNSPEC) when no prefix has been given. This basically means that,
>>>> at least for now, we assume that an unknown (i.e., not prefixed)
>>>> address/hostname is IPv4. I've made this decision thinking about the
>>>> convenience of the user: when AF_UNSPEC is used (and the user hasn't
>>>> specified any prefix), getaddrinfo will return a linked list of possible
>>>> addresses that we should try to connect to, which usually means an IPv6
>>>> and an IPv4 address, in that order. Usually this is fine, because (as I
>>>> said) IPv6 sockets can also listen for IPv4 connections. However, if
>>>> you start gdbserver with an explicit IPv4 address:
>>>>
>>>> $ ./gdb/gdbserver/gdbserver --once 127.0.0.1:1234 a.out
>>>>
>>>> and try to connect GDB to it using an "ambiguous" hostname:
>>>>
>>>> $ ./gdb/gdb -ex 'target remote localhost:1234' a.out
>>>>
>>>> you will notice that GDB will take a somewhat long time trying to
>>>> connect (to the IPv6 address, because of AF_UNSPEC), and then it will
>>>> error out saying that the connection timed out:
>>>>
>>>> tcp:localhost:1234: Connection timed out.
>>>
>>> How do other tools handle this?
>>
>> Just like GDB.
>
> Well, it sounds like they do the AF_UNSPEC thing, instead of
> defaulting to AF_INET.
Yeah. Sorry, I was comparing with the GDB I currently have here, which
uses AF_UNSPEC because I was doing a few tests and changes.
>>> For example, with ping, I get:
>>>
>>> $ ping localhost
>>> PING localhost.localdomain (127.0.0.1) 56(84) bytes of data.
>>> 64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=1 ttl=64 time=0.048 ms
>>> ^C
>>>
>>> $ ping localhost6
>>> PING localhost6(localhost6.localdomain6 (::1)) 56 data bytes
>>> 64 bytes from localhost6.localdomain6 (::1): icmp_seq=1 ttl=64 time=0.086 ms
>>> ^C
>>
>> And I get:
>>
>> $ ping localhost
>> PING localhost(localhost (::1)) 56 data bytes
>> 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.050 ms
>> ^C
>>
>> $ ping localhost6
>> PING localhost6(localhost (::1)) 56 data bytes
>> 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.089 ms
>> ^C
>>
>> Maybe your /etc/hosts is different than mine:
>>
>> 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
>> ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
>
> Looks like it:
>
> $ cat /etc/hosts
> 127.0.0.1 localhost.localdomain localhost
> ::1 localhost6.localdomain6 localhost6
>
> This is on F27 (upgraded a few times). I don't remember if I ever
> changed this manually.
I've never changed mine either, but this is from a fresh F27 install.
>> We can either adjust it to a lower delay, get rid of
>> it, or leave it as is and assume that unprefixed addresses are IPv4. I
>> fail to see what else we're missing.
>
> The "assume unprefixed addresses are IPv4" seems like the worse
> option to me, as it's a work around. Let's tackle the real issue
> instead.
>
> We could consider for example more verbose progress indication,
> or cycling the whole "getaddrinfo loop" before waiting to retry instead
> of waiting after each individual connection failure.
A more verbose indication would be nice, as well as a way to control how
many retries GDB should perform.
I'm not sure about cycling the whole loop before waiting to retry... I
mean, it works, but I'm not sure it's what the user would expect from a
"retry" mechanism. I would expect GDB to "retry this address X times,
and then go to the next", instead of "retry all the addresses in a
loop". But that can be documented, sure.
On a side note, I have to ask: why not decrease the number of retries
to, say, 5? This would still add a delay, but it'd be much shorter.
>>
>>>>>> + char *orig_name = strdup (name);
>>>>>
>>>>> Do we need a deep copy? And if we do, how about
>>>>> using std::string to avoid having to call free further
>>>>> down?
>>>>
>>>> This is gdbserver/gdbreplay.c, where apparently we don't have access to
>>>> a lot of our regular facilities on GDB. For example, I was trying to
>>>> use std::string, its methods, and other stuff here (even i18n
>>>> functions), but the code won't compile, and as far as I have researched
>>>> this is intentional, because gdbreplay needs to be a very small and
>>>> simple program.
>>>
>>> What did you find that gave you that impression? There's no reason
>>> that gdbreplay needs to be small or simple. Certainly doesn't need
>>> to be smaller than gdbserver.
>>
>> First, the way it is written. It doesn't use any of our facilities
>> (e.g., i18n, strdup instead of xstrdup), and it seems to be treated in a
>> "special" way, because it is a separate program. I found this message:
>>
>> https://sourceware.org/ml/gdb/2008-06/msg00117.html
>>
>> > I've tried to find information in the doc about gdbreplay without luck.
>> > Really quickly, does gdbreplay, as its name suggest, allow to record an
>> > re-run an application session?
>>
>> Yes, exactly -- but with rather stringent limits.
>> In a nutshell, during the replay session, you must give
>> EXACTLY the same sequence of gdb commands as were given
>> during the record session. gdbreplay will prompt you for
>> the next command, but if you do *anything* different,
>> it will throw up its hands and quit.
>>
>> And it seems to imply that gdbreplay is a very limited program.
>
> The "stringent limits" refers to what you can do from gdb
> when connected to gdbreplay, not to gdbreplay's running environment.
Right, I got that. As I said, I think I read too much between the lines
here.
> The tool is useful for support, to e.g., reproduce bugs that only
> trigger against remote stubs / embedded probes that the user has
> access to, other than gdbserver. You ask the user to use "set remotelogfile"
> to record the remote protocol traffic against the user's remote stub, and
> then the user reproduces the bug. The user sends you the resulting
> remote protocol log file, and you load it against gdbreplay. Then, using
> the same gdb version and same program binary the user used, you connect
> to gdbreplay, and use the exact same set of gdb commands the user used.
> Given those constraints, gdb should send the exact same remote protocol
> packets that the user's gdb sent to the users stub. And since gdbreplay
> is replaying the remote protocol traffic the original stub sent, you'll be
> able to reproduce the bug locally. If you use a different set of commands,
> then gdb will send different packets, and the log that gdbreplay is
> replaying of course breaks down.
>
> So gdbreplay runs on the host computer. There's no need to care about
> making it super tiny of anything like that.
We should add this to a wiki or to our official docs. I think it's the
more complete explanation I've read about gdbreplay so far.
Thanks,
--
Sergio
GPG key ID: 237A 54B1 0287 28BF 00EF 31F4 D0EB 7628 65FC 5E36
Please send encrypted e-mail if possible
http://sergiodj.net/