binutils-gdb/gdb/ser-tcp.c

514 lines
12 KiB
C
Raw Normal View History

/* Serial interface for raw TCP connections on Un*x like systems.
Copyright (C) 1992-2019 Free Software Foundation, Inc.
1999-07-07 22:19:36 +02:00
This file is part of GDB.
1999-07-07 22:19:36 +02:00
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
1999-07-07 22:19:36 +02:00
(at your option) any later version.
1999-07-07 22:19:36 +02:00
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
1999-07-07 22:19:36 +02:00
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "serial.h"
* Makefile.in (SFILES): Add ser-base.c. (ser_base_h): New variable. (ser-base.o): New target. (ser-pipe.o): Depend on $(ser_base_h). (ser-tcp.o): Likewise. (ser-unix.o): Likewise. Do not depend on $(event_loop_h). * configure.ac (SER_HARDWIRE): Include ser-base.o where appropriate. * ser-base.c: New file. (push_event): Move from ser-unix.c. (fd_event): Likewise. (reschedule): Likewise. (ser_unix_write): Likewise. (ser_unix_nop_flush_output): Likewise. (ser_unix_flush_input): Likewise. (ser_unix_nop_send_break): Likewise. (ser_unix_nop_drain_output): Likewise. (ser_unix_nop_raw): Likewise. (ser_unix_nop_get_tty_state): Likewise. (ser_unix_nop_set_tty_state): Likewise. (ser_unix_nop_noflush_set_tty_state): Likewise. (ser_unix_nop_print_tty_state): Likewise. (ser_unix_nop_setbaudrate): Likewise. (ser_unix_nop_setstopbits): Likewise. (ser_unix_async): Likewise. * ser-base.h: New file. * ser-pipe.c (ser-base.h): Include it. * ser-tcp.c (ser-base.h): Likewise. * ser-unix.h (ser_unix_nop_flush_output): Remove. (ser_unix_flush_input): Likewise. (ser_unix_nop_send_break): Likewise. (ser_unix_nop_raw): Likewise. (ser_unix_nop_get_tty_state): Likewise. (ser_unix_nop_set_tty_state): Likewise. (ser_unix_nop_print_tty_state): Likewise. (ser_unix_nop_noflush_set_tty_state): Likewise. (ser_unix_nop_setbaudrate): Likewise. (ser_unix_nop_setstopbits): Likewise. (ser_unix_nop_drain_output): Likewise. (ser_unix_wait_for): Likewise. (ser_unix_write): Likewise. (ser_unix_async): Likewise. * ser-unix.c (event-loop.h): Do not include it. (push_event): Move to ser-base.c. (fd_event): Likewise. (reschedule): Likewise. (ser_unix_write): Likewise. (ser_unix_nop_flush_output): Likewise. (ser_unix_flush_input): Likewise. (ser_unix_nop_send_break): Likewise. (ser_unix_nop_drain_output): Likewise. (ser_unix_nop_raw): Likewise. (ser_unix_nop_get_tty_state): Likewise. (ser_unix_nop_set_tty_state): Likewise. (ser_unix_nop_noflush_set_tty_state): Likewise. (ser_unix_nop_print_tty_state): Likewise. (ser_unix_nop_setbaudrate): Likewise. (ser_unix_nop_setstopbits): Likewise. (ser_unix_async): Likewise. (ser_unix_wait_for): Make it static. * configure: Regenerated.
2005-03-25 20:47:23 +01:00
#include "ser-base.h"
* NEWS: Mention native Windows support. * Makefile.in (gdb_select_h, ser_tcp_h): New. (ALLDEPFILES): Add ser-mingw.c. (event-loop.o, inflow.o, mingw-hdep.o, posix-hdep.o, ser-base.o) (ser-tcp.o, ser-unix.o): Update. (ser-mingw.o): New rule. * configure: Regenerated. * configure.ac: Add ser-mingw.o for mingw32. * ser-mingw.c: New file. * event-loop.c: Include "gdb_select.h". (gdb_select): Remove, moved to mingw-hdep.c and posix-hdep.c. * ser-base.c: Include "gdb_select.h". (ser_base_wait_for): Use gdb_select. * serial.c (serial_for_fd): New function. (serial_fdopen): Try "terminal" before "hardwire". Initialize the allocated struct serial. (serial_wait_handle): New function. * serial.h (serial_for_fd, serial_wait_handle): New prototypes. (struct serial_ops) [USE_WIN32API]: Add wait_handle. * gdb_select.h: New file. * ser-tcp.c: Include "ser-tcp.h". Remove unused "ser-unix.h" include. (net_close, net_read_prim, net_write_prim): Make global. (net_open): Likewise. Pass an exception set to select. Whitespace fix. Document why we can not use gdb_select. (_initialize_ser_tcp) [USE_WIN32API]: Do not register TCP support here. * ser-tcp.h: New file. * inflow.c (gdb_has_a_terminal): Don't initialize stdin_serial here. (handle_sigio): Use gdb_select. (initialize_stdin_serial): New function. * terminal.h (initialize_stdin_serial): New prototype. * top.c (gdb_init): Call initialize_stdin_serial. * mingw-hdep.c (gdb_select): New function, moved from gdb_select in event-loop.c. Add exception condition support. Use serial_for_fd and serial_wait_handle. Fix timeout handling. * posix-hdep.c: Include "gdb_select.h". (gdb_select): New function. * remote-st.c (connect_command): Use gdb_select. * ser-unix.c: Include "gdb_select.h". (hardwire_send_break, wait_for): Use gdb_select.
2006-02-10 23:01:43 +01:00
#include "ser-tcp.h"
#include "gdbcmd.h"
#include "cli/cli-decode.h"
#include "cli/cli-setshow.h"
Normalize includes to use common/ This changes all includes to use the form "common/filename.h" rather than just "filename.h". This was written by a script. gdb/ChangeLog 2019-01-25 Tom Tromey <tom@tromey.com> * xtensa-linux-nat.c: Fix common/ includes. * xml-support.h: Fix common/ includes. * xml-support.c: Fix common/ includes. * x86-linux-nat.c: Fix common/ includes. * windows-nat.c: Fix common/ includes. * varobj.h: Fix common/ includes. * varobj.c: Fix common/ includes. * value.c: Fix common/ includes. * valops.c: Fix common/ includes. * utils.c: Fix common/ includes. * unittests/xml-utils-selftests.c: Fix common/ includes. * unittests/utils-selftests.c: Fix common/ includes. * unittests/unpack-selftests.c: Fix common/ includes. * unittests/tracepoint-selftests.c: Fix common/ includes. * unittests/style-selftests.c: Fix common/ includes. * unittests/string_view-selftests.c: Fix common/ includes. * unittests/scoped_restore-selftests.c: Fix common/ includes. * unittests/scoped_mmap-selftests.c: Fix common/ includes. * unittests/scoped_fd-selftests.c: Fix common/ includes. * unittests/rsp-low-selftests.c: Fix common/ includes. * unittests/parse-connection-spec-selftests.c: Fix common/ includes. * unittests/optional-selftests.c: Fix common/ includes. * unittests/offset-type-selftests.c: Fix common/ includes. * unittests/observable-selftests.c: Fix common/ includes. * unittests/mkdir-recursive-selftests.c: Fix common/ includes. * unittests/memrange-selftests.c: Fix common/ includes. * unittests/memory-map-selftests.c: Fix common/ includes. * unittests/lookup_name_info-selftests.c: Fix common/ includes. * unittests/function-view-selftests.c: Fix common/ includes. * unittests/environ-selftests.c: Fix common/ includes. * unittests/copy_bitwise-selftests.c: Fix common/ includes. * unittests/common-utils-selftests.c: Fix common/ includes. * unittests/cli-utils-selftests.c: Fix common/ includes. * unittests/array-view-selftests.c: Fix common/ includes. * ui-file.c: Fix common/ includes. * tui/tui-io.c: Fix common/ includes. * tracepoint.h: Fix common/ includes. * tracepoint.c: Fix common/ includes. * tracefile-tfile.c: Fix common/ includes. * top.h: Fix common/ includes. * top.c: Fix common/ includes. * thread.c: Fix common/ includes. * target/waitstatus.h: Fix common/ includes. * target/waitstatus.c: Fix common/ includes. * target.h: Fix common/ includes. * target.c: Fix common/ includes. * target-memory.c: Fix common/ includes. * target-descriptions.c: Fix common/ includes. * symtab.h: Fix common/ includes. * symfile.c: Fix common/ includes. * stap-probe.c: Fix common/ includes. * spu-linux-nat.c: Fix common/ includes. * sparc-nat.c: Fix common/ includes. * source.c: Fix common/ includes. * solib.c: Fix common/ includes. * solib-target.c: Fix common/ includes. * ser-unix.c: Fix common/ includes. * ser-tcp.c: Fix common/ includes. * ser-pipe.c: Fix common/ includes. * ser-base.c: Fix common/ includes. * selftest-arch.c: Fix common/ includes. * s12z-tdep.c: Fix common/ includes. * rust-exp.y: Fix common/ includes. * rs6000-aix-tdep.c: Fix common/ includes. * riscv-tdep.c: Fix common/ includes. * remote.c: Fix common/ includes. * remote-notif.h: Fix common/ includes. * remote-fileio.h: Fix common/ includes. * remote-fileio.c: Fix common/ includes. * regcache.h: Fix common/ includes. * regcache.c: Fix common/ includes. * record-btrace.c: Fix common/ includes. * python/python.c: Fix common/ includes. * python/py-type.c: Fix common/ includes. * python/py-inferior.c: Fix common/ includes. * progspace.h: Fix common/ includes. * producer.c: Fix common/ includes. * procfs.c: Fix common/ includes. * proc-api.c: Fix common/ includes. * printcmd.c: Fix common/ includes. * ppc-linux-nat.c: Fix common/ includes. * parser-defs.h: Fix common/ includes. * osdata.c: Fix common/ includes. * obsd-nat.c: Fix common/ includes. * nat/x86-linux.c: Fix common/ includes. * nat/x86-linux-dregs.c: Fix common/ includes. * nat/x86-dregs.h: Fix common/ includes. * nat/x86-dregs.c: Fix common/ includes. * nat/ppc-linux.c: Fix common/ includes. * nat/mips-linux-watch.h: Fix common/ includes. * nat/mips-linux-watch.c: Fix common/ includes. * nat/linux-waitpid.c: Fix common/ includes. * nat/linux-ptrace.h: Fix common/ includes. * nat/linux-ptrace.c: Fix common/ includes. * nat/linux-procfs.c: Fix common/ includes. * nat/linux-personality.c: Fix common/ includes. * nat/linux-osdata.c: Fix common/ includes. * nat/linux-namespaces.c: Fix common/ includes. * nat/linux-btrace.h: Fix common/ includes. * nat/linux-btrace.c: Fix common/ includes. * nat/fork-inferior.c: Fix common/ includes. * nat/amd64-linux-siginfo.c: Fix common/ includes. * nat/aarch64-sve-linux-ptrace.c: Fix common/ includes. * nat/aarch64-linux.c: Fix common/ includes. * nat/aarch64-linux-hw-point.h: Fix common/ includes. * nat/aarch64-linux-hw-point.c: Fix common/ includes. * namespace.h: Fix common/ includes. * mips-linux-tdep.c: Fix common/ includes. * minsyms.c: Fix common/ includes. * mi/mi-parse.h: Fix common/ includes. * mi/mi-main.c: Fix common/ includes. * mi/mi-cmd-env.c: Fix common/ includes. * memrange.h: Fix common/ includes. * memattr.c: Fix common/ includes. * maint.h: Fix common/ includes. * maint.c: Fix common/ includes. * main.c: Fix common/ includes. * machoread.c: Fix common/ includes. * location.c: Fix common/ includes. * linux-thread-db.c: Fix common/ includes. * linux-nat.c: Fix common/ includes. * linux-fork.c: Fix common/ includes. * inline-frame.c: Fix common/ includes. * infrun.c: Fix common/ includes. * inflow.c: Fix common/ includes. * inferior.h: Fix common/ includes. * inferior.c: Fix common/ includes. * infcmd.c: Fix common/ includes. * inf-ptrace.c: Fix common/ includes. * inf-child.c: Fix common/ includes. * ia64-linux-nat.c: Fix common/ includes. * i387-tdep.c: Fix common/ includes. * i386-tdep.c: Fix common/ includes. * i386-linux-tdep.c: Fix common/ includes. * i386-linux-nat.c: Fix common/ includes. * i386-go32-tdep.c: Fix common/ includes. * i386-fbsd-tdep.c: Fix common/ includes. * i386-fbsd-nat.c: Fix common/ includes. * guile/scm-type.c: Fix common/ includes. * guile/guile.c: Fix common/ includes. * go32-nat.c: Fix common/ includes. * gnu-nat.c: Fix common/ includes. * gdbthread.h: Fix common/ includes. * gdbarch-selftests.c: Fix common/ includes. * gdb_usleep.c: Fix common/ includes. * gdb_select.h: Fix common/ includes. * gdb_bfd.c: Fix common/ includes. * gcore.c: Fix common/ includes. * fork-child.c: Fix common/ includes. * findvar.c: Fix common/ includes. * fbsd-nat.c: Fix common/ includes. * event-top.c: Fix common/ includes. * event-loop.c: Fix common/ includes. * dwarf2read.c: Fix common/ includes. * dwarf2loc.c: Fix common/ includes. * dwarf2-frame.c: Fix common/ includes. * dwarf-index-cache.c: Fix common/ includes. * dtrace-probe.c: Fix common/ includes. * disasm-selftests.c: Fix common/ includes. * defs.h: Fix common/ includes. * csky-tdep.c: Fix common/ includes. * cp-valprint.c: Fix common/ includes. * cp-support.h: Fix common/ includes. * cp-support.c: Fix common/ includes. * corelow.c: Fix common/ includes. * completer.h: Fix common/ includes. * completer.c: Fix common/ includes. * compile/compile.c: Fix common/ includes. * compile/compile-loc2c.c: Fix common/ includes. * compile/compile-cplus-types.c: Fix common/ includes. * compile/compile-cplus-symbols.c: Fix common/ includes. * command.h: Fix common/ includes. * cli/cli-dump.c: Fix common/ includes. * cli/cli-cmds.c: Fix common/ includes. * charset.c: Fix common/ includes. * build-id.c: Fix common/ includes. * btrace.h: Fix common/ includes. * btrace.c: Fix common/ includes. * breakpoint.h: Fix common/ includes. * breakpoint.c: Fix common/ includes. * ax.h: (enum agent_op): Fix common/ includes. * ax-general.c (struct aop_map): Fix common/ includes. * ax-gdb.c: Fix common/ includes. * auxv.c: Fix common/ includes. * auto-load.c: Fix common/ includes. * arm-tdep.c: Fix common/ includes. * arch/riscv.c: Fix common/ includes. * arch/ppc-linux-common.c: Fix common/ includes. * arch/i386.c: Fix common/ includes. * arch/arm.c: Fix common/ includes. * arch/arm-linux.c: Fix common/ includes. * arch/arm-get-next-pcs.c: Fix common/ includes. * arch/amd64.c: Fix common/ includes. * arch/aarch64.c: Fix common/ includes. * arch/aarch64-insn.c: Fix common/ includes. * arch-utils.c: Fix common/ includes. * amd64-windows-tdep.c: Fix common/ includes. * amd64-tdep.c: Fix common/ includes. * amd64-sol2-tdep.c: Fix common/ includes. * amd64-obsd-tdep.c: Fix common/ includes. * amd64-nbsd-tdep.c: Fix common/ includes. * amd64-linux-tdep.c: Fix common/ includes. * amd64-linux-nat.c: Fix common/ includes. * amd64-fbsd-tdep.c: Fix common/ includes. * amd64-fbsd-nat.c: Fix common/ includes. * amd64-dicos-tdep.c: Fix common/ includes. * amd64-darwin-tdep.c: Fix common/ includes. * agent.c: Fix common/ includes. * ada-lang.h: Fix common/ includes. * ada-lang.c: Fix common/ includes. * aarch64-tdep.c: Fix common/ includes. gdb/gdbserver/ChangeLog 2019-01-25 Tom Tromey <tom@tromey.com> * win32-low.c: Fix common/ includes. * win32-i386-low.c: Fix common/ includes. * tracepoint.c: Fix common/ includes. * thread-db.c: Fix common/ includes. * target.h: Fix common/ includes. * symbol.c: Fix common/ includes. * spu-low.c: Fix common/ includes. * server.h: Fix common/ includes. * server.c: Fix common/ includes. * remote-utils.c: Fix common/ includes. * regcache.h: Fix common/ includes. * regcache.c: Fix common/ includes. * nto-x86-low.c: Fix common/ includes. * notif.h: Fix common/ includes. * mem-break.h: Fix common/ includes. * lynx-low.c: Fix common/ includes. * lynx-i386-low.c: Fix common/ includes. * linux-x86-tdesc-selftest.c: Fix common/ includes. * linux-x86-low.c: Fix common/ includes. * linux-low.c: Fix common/ includes. * inferiors.h: Fix common/ includes. * i387-fp.c: Fix common/ includes. * hostio.c: Fix common/ includes. * hostio-errno.c: Fix common/ includes. * gdbthread.h: Fix common/ includes. * gdbreplay.c: Fix common/ includes. * fork-child.c: Fix common/ includes. * event-loop.c: Fix common/ includes. * ax.c: (enum gdb_agent_op): Fix common/ includes.
2019-01-23 18:21:39 +01:00
#include "common/filestuff.h"
#include "common/netstuff.h"
1999-09-22 05:28:34 +02:00
#include <sys/types.h>
#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h> /* For FIONBIO. */
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> /* For FIONBIO. */
#endif
Normalize includes to use common/ This changes all includes to use the form "common/filename.h" rather than just "filename.h". This was written by a script. gdb/ChangeLog 2019-01-25 Tom Tromey <tom@tromey.com> * xtensa-linux-nat.c: Fix common/ includes. * xml-support.h: Fix common/ includes. * xml-support.c: Fix common/ includes. * x86-linux-nat.c: Fix common/ includes. * windows-nat.c: Fix common/ includes. * varobj.h: Fix common/ includes. * varobj.c: Fix common/ includes. * value.c: Fix common/ includes. * valops.c: Fix common/ includes. * utils.c: Fix common/ includes. * unittests/xml-utils-selftests.c: Fix common/ includes. * unittests/utils-selftests.c: Fix common/ includes. * unittests/unpack-selftests.c: Fix common/ includes. * unittests/tracepoint-selftests.c: Fix common/ includes. * unittests/style-selftests.c: Fix common/ includes. * unittests/string_view-selftests.c: Fix common/ includes. * unittests/scoped_restore-selftests.c: Fix common/ includes. * unittests/scoped_mmap-selftests.c: Fix common/ includes. * unittests/scoped_fd-selftests.c: Fix common/ includes. * unittests/rsp-low-selftests.c: Fix common/ includes. * unittests/parse-connection-spec-selftests.c: Fix common/ includes. * unittests/optional-selftests.c: Fix common/ includes. * unittests/offset-type-selftests.c: Fix common/ includes. * unittests/observable-selftests.c: Fix common/ includes. * unittests/mkdir-recursive-selftests.c: Fix common/ includes. * unittests/memrange-selftests.c: Fix common/ includes. * unittests/memory-map-selftests.c: Fix common/ includes. * unittests/lookup_name_info-selftests.c: Fix common/ includes. * unittests/function-view-selftests.c: Fix common/ includes. * unittests/environ-selftests.c: Fix common/ includes. * unittests/copy_bitwise-selftests.c: Fix common/ includes. * unittests/common-utils-selftests.c: Fix common/ includes. * unittests/cli-utils-selftests.c: Fix common/ includes. * unittests/array-view-selftests.c: Fix common/ includes. * ui-file.c: Fix common/ includes. * tui/tui-io.c: Fix common/ includes. * tracepoint.h: Fix common/ includes. * tracepoint.c: Fix common/ includes. * tracefile-tfile.c: Fix common/ includes. * top.h: Fix common/ includes. * top.c: Fix common/ includes. * thread.c: Fix common/ includes. * target/waitstatus.h: Fix common/ includes. * target/waitstatus.c: Fix common/ includes. * target.h: Fix common/ includes. * target.c: Fix common/ includes. * target-memory.c: Fix common/ includes. * target-descriptions.c: Fix common/ includes. * symtab.h: Fix common/ includes. * symfile.c: Fix common/ includes. * stap-probe.c: Fix common/ includes. * spu-linux-nat.c: Fix common/ includes. * sparc-nat.c: Fix common/ includes. * source.c: Fix common/ includes. * solib.c: Fix common/ includes. * solib-target.c: Fix common/ includes. * ser-unix.c: Fix common/ includes. * ser-tcp.c: Fix common/ includes. * ser-pipe.c: Fix common/ includes. * ser-base.c: Fix common/ includes. * selftest-arch.c: Fix common/ includes. * s12z-tdep.c: Fix common/ includes. * rust-exp.y: Fix common/ includes. * rs6000-aix-tdep.c: Fix common/ includes. * riscv-tdep.c: Fix common/ includes. * remote.c: Fix common/ includes. * remote-notif.h: Fix common/ includes. * remote-fileio.h: Fix common/ includes. * remote-fileio.c: Fix common/ includes. * regcache.h: Fix common/ includes. * regcache.c: Fix common/ includes. * record-btrace.c: Fix common/ includes. * python/python.c: Fix common/ includes. * python/py-type.c: Fix common/ includes. * python/py-inferior.c: Fix common/ includes. * progspace.h: Fix common/ includes. * producer.c: Fix common/ includes. * procfs.c: Fix common/ includes. * proc-api.c: Fix common/ includes. * printcmd.c: Fix common/ includes. * ppc-linux-nat.c: Fix common/ includes. * parser-defs.h: Fix common/ includes. * osdata.c: Fix common/ includes. * obsd-nat.c: Fix common/ includes. * nat/x86-linux.c: Fix common/ includes. * nat/x86-linux-dregs.c: Fix common/ includes. * nat/x86-dregs.h: Fix common/ includes. * nat/x86-dregs.c: Fix common/ includes. * nat/ppc-linux.c: Fix common/ includes. * nat/mips-linux-watch.h: Fix common/ includes. * nat/mips-linux-watch.c: Fix common/ includes. * nat/linux-waitpid.c: Fix common/ includes. * nat/linux-ptrace.h: Fix common/ includes. * nat/linux-ptrace.c: Fix common/ includes. * nat/linux-procfs.c: Fix common/ includes. * nat/linux-personality.c: Fix common/ includes. * nat/linux-osdata.c: Fix common/ includes. * nat/linux-namespaces.c: Fix common/ includes. * nat/linux-btrace.h: Fix common/ includes. * nat/linux-btrace.c: Fix common/ includes. * nat/fork-inferior.c: Fix common/ includes. * nat/amd64-linux-siginfo.c: Fix common/ includes. * nat/aarch64-sve-linux-ptrace.c: Fix common/ includes. * nat/aarch64-linux.c: Fix common/ includes. * nat/aarch64-linux-hw-point.h: Fix common/ includes. * nat/aarch64-linux-hw-point.c: Fix common/ includes. * namespace.h: Fix common/ includes. * mips-linux-tdep.c: Fix common/ includes. * minsyms.c: Fix common/ includes. * mi/mi-parse.h: Fix common/ includes. * mi/mi-main.c: Fix common/ includes. * mi/mi-cmd-env.c: Fix common/ includes. * memrange.h: Fix common/ includes. * memattr.c: Fix common/ includes. * maint.h: Fix common/ includes. * maint.c: Fix common/ includes. * main.c: Fix common/ includes. * machoread.c: Fix common/ includes. * location.c: Fix common/ includes. * linux-thread-db.c: Fix common/ includes. * linux-nat.c: Fix common/ includes. * linux-fork.c: Fix common/ includes. * inline-frame.c: Fix common/ includes. * infrun.c: Fix common/ includes. * inflow.c: Fix common/ includes. * inferior.h: Fix common/ includes. * inferior.c: Fix common/ includes. * infcmd.c: Fix common/ includes. * inf-ptrace.c: Fix common/ includes. * inf-child.c: Fix common/ includes. * ia64-linux-nat.c: Fix common/ includes. * i387-tdep.c: Fix common/ includes. * i386-tdep.c: Fix common/ includes. * i386-linux-tdep.c: Fix common/ includes. * i386-linux-nat.c: Fix common/ includes. * i386-go32-tdep.c: Fix common/ includes. * i386-fbsd-tdep.c: Fix common/ includes. * i386-fbsd-nat.c: Fix common/ includes. * guile/scm-type.c: Fix common/ includes. * guile/guile.c: Fix common/ includes. * go32-nat.c: Fix common/ includes. * gnu-nat.c: Fix common/ includes. * gdbthread.h: Fix common/ includes. * gdbarch-selftests.c: Fix common/ includes. * gdb_usleep.c: Fix common/ includes. * gdb_select.h: Fix common/ includes. * gdb_bfd.c: Fix common/ includes. * gcore.c: Fix common/ includes. * fork-child.c: Fix common/ includes. * findvar.c: Fix common/ includes. * fbsd-nat.c: Fix common/ includes. * event-top.c: Fix common/ includes. * event-loop.c: Fix common/ includes. * dwarf2read.c: Fix common/ includes. * dwarf2loc.c: Fix common/ includes. * dwarf2-frame.c: Fix common/ includes. * dwarf-index-cache.c: Fix common/ includes. * dtrace-probe.c: Fix common/ includes. * disasm-selftests.c: Fix common/ includes. * defs.h: Fix common/ includes. * csky-tdep.c: Fix common/ includes. * cp-valprint.c: Fix common/ includes. * cp-support.h: Fix common/ includes. * cp-support.c: Fix common/ includes. * corelow.c: Fix common/ includes. * completer.h: Fix common/ includes. * completer.c: Fix common/ includes. * compile/compile.c: Fix common/ includes. * compile/compile-loc2c.c: Fix common/ includes. * compile/compile-cplus-types.c: Fix common/ includes. * compile/compile-cplus-symbols.c: Fix common/ includes. * command.h: Fix common/ includes. * cli/cli-dump.c: Fix common/ includes. * cli/cli-cmds.c: Fix common/ includes. * charset.c: Fix common/ includes. * build-id.c: Fix common/ includes. * btrace.h: Fix common/ includes. * btrace.c: Fix common/ includes. * breakpoint.h: Fix common/ includes. * breakpoint.c: Fix common/ includes. * ax.h: (enum agent_op): Fix common/ includes. * ax-general.c (struct aop_map): Fix common/ includes. * ax-gdb.c: Fix common/ includes. * auxv.c: Fix common/ includes. * auto-load.c: Fix common/ includes. * arm-tdep.c: Fix common/ includes. * arch/riscv.c: Fix common/ includes. * arch/ppc-linux-common.c: Fix common/ includes. * arch/i386.c: Fix common/ includes. * arch/arm.c: Fix common/ includes. * arch/arm-linux.c: Fix common/ includes. * arch/arm-get-next-pcs.c: Fix common/ includes. * arch/amd64.c: Fix common/ includes. * arch/aarch64.c: Fix common/ includes. * arch/aarch64-insn.c: Fix common/ includes. * arch-utils.c: Fix common/ includes. * amd64-windows-tdep.c: Fix common/ includes. * amd64-tdep.c: Fix common/ includes. * amd64-sol2-tdep.c: Fix common/ includes. * amd64-obsd-tdep.c: Fix common/ includes. * amd64-nbsd-tdep.c: Fix common/ includes. * amd64-linux-tdep.c: Fix common/ includes. * amd64-linux-nat.c: Fix common/ includes. * amd64-fbsd-tdep.c: Fix common/ includes. * amd64-fbsd-nat.c: Fix common/ includes. * amd64-dicos-tdep.c: Fix common/ includes. * amd64-darwin-tdep.c: Fix common/ includes. * agent.c: Fix common/ includes. * ada-lang.h: Fix common/ includes. * ada-lang.c: Fix common/ includes. * aarch64-tdep.c: Fix common/ includes. gdb/gdbserver/ChangeLog 2019-01-25 Tom Tromey <tom@tromey.com> * win32-low.c: Fix common/ includes. * win32-i386-low.c: Fix common/ includes. * tracepoint.c: Fix common/ includes. * thread-db.c: Fix common/ includes. * target.h: Fix common/ includes. * symbol.c: Fix common/ includes. * spu-low.c: Fix common/ includes. * server.h: Fix common/ includes. * server.c: Fix common/ includes. * remote-utils.c: Fix common/ includes. * regcache.h: Fix common/ includes. * regcache.c: Fix common/ includes. * nto-x86-low.c: Fix common/ includes. * notif.h: Fix common/ includes. * mem-break.h: Fix common/ includes. * lynx-low.c: Fix common/ includes. * lynx-i386-low.c: Fix common/ includes. * linux-x86-tdesc-selftest.c: Fix common/ includes. * linux-x86-low.c: Fix common/ includes. * linux-low.c: Fix common/ includes. * inferiors.h: Fix common/ includes. * i387-fp.c: Fix common/ includes. * hostio.c: Fix common/ includes. * hostio-errno.c: Fix common/ includes. * gdbthread.h: Fix common/ includes. * gdbreplay.c: Fix common/ includes. * fork-child.c: Fix common/ includes. * event-loop.c: Fix common/ includes. * ax.c: (enum gdb_agent_op): Fix common/ includes.
2019-01-23 18:21:39 +01:00
#include "common/gdb_sys_time.h"
#ifdef USE_WIN32API
#if _WIN32_WINNT < 0x0501
# undef _WIN32_WINNT
# define _WIN32_WINNT 0x0501
#endif
#include <ws2tcpip.h>
#ifndef ETIMEDOUT
#define ETIMEDOUT WSAETIMEDOUT
#endif
Import "glob" and "getcwd" modules from gnulib These two modules are necessary because of the rework that will be done in the "change directory" logic on GDB/gdbserver in the next commits. First, we will get rid of the "gdb_dirbuf" global variable and instead rely on the fact that "getcwd (NULL, 0)", which is a GNU extension, returns a heap-allocated string with the necessary bytes to hold the full path. This is a good practice not only because globals are not ideal but also because there is no good way to know beforehand the size of the full pathname allowed in the filesystem ("PATH_MAX" is not portable and does not reflect all the possible filesystems out there). We will also have a way to "cd" to a directory also on gdbserver, but in order to do that uniformly, there must be a way to do tilde expansion on directories provided by the user. Currently, GDB uses "tilde_expand" from readline to do that, but gdbserver doesn't link against readline and therefore cannot use this function. The solution is to use "glob" instead, which can perform tilde expansion as a GNU extension. Therefore, we need gnulib's version of "glob". A special note is necessary for gdb/ser-tcp.c. It defines "close" as "closesocket" on Win32 targets. If we leave the code as is, this would conflict with gnulib's definition of "close". Therefore, in order to keep the same code path from before this import, I decided to "#undef close" first, and then let the original (re)definition of it take place. gdb/ChangeLog: 2017-09-22 Sergio Durigan Junior <sergiodj@redhat.com> * gnulib/aclocal.m4: Regenerate. * gnulib/config.in: Regenerate. * gnulib/configure: Regenerate. * gnulib/import/Makefile.am: Regenerate. * gnulib/import/Makefile.in: Regenerate. * gnulib/import/assure.h: New file. * gnulib/import/at-func.c: Likewise * gnulib/import/chdir-long.c: New file. * gnulib/import/chdir-long.h: New file. * gnulib/import/cloexec.c: New file. * gnulib/import/cloexec.h: New file. * gnulib/import/close.c: New file. * gnulib/import/closedir.c: New file. * gnulib/import/dirent-private.h: New file. * gnulib/import/dup-safer.c: New file. * gnulib/import/dup.c: New file. * gnulib/import/dup2.c: New file. * gnulib/import/error.c: New file. * gnulib/import/error.h: New file. * gnulib/import/exitfail.c: New file. * gnulib/import/exitfail.h: New file. * gnulib/import/fchdir.c: New file. * gnulib/import/fcntl.c: New file. * gnulib/import/fcntl.in.h: New file. * gnulib/import/fd-hook.c: New file. * gnulib/import/fd-hook.h: New file. * gnulib/import/fd-safer.c: New file. * gnulib/import/fdopendir.c: New file. * gnulib/import/filename.h: New file. * gnulib/import/filenamecat-lgpl.c: New file. * gnulib/import/filenamecat.h: New file. * gnulib/import/fstat.c: New file. * gnulib/import/fstatat.c: New file. * gnulib/import/getcwd-lgpl.c: New file. * gnulib/import/getcwd.c: New file. * gnulib/import/getdtablesize.c: New file. * gnulib/import/getlogin_r.c: New file. * gnulib/import/getprogname.c: New file. * gnulib/import/getprogname.h: New file. * gnulib/import/gettext.h: New file. * gnulib/import/glob-libc.h: New file. * gnulib/import/glob.c: New file. * gnulib/import/glob.in.h: New file. * gnulib/import/intprops.h: New file. * gnulib/import/m4/chdir-long.m4: New file. * gnulib/import/m4/close.m4: New file. * gnulib/import/m4/closedir.m4: New file. * gnulib/import/m4/d-ino.m4: New file. * gnulib/import/m4/d-type.m4: New file. * gnulib/import/m4/dup.m4: New file. * gnulib/import/m4/dup2.m4: New file. * gnulib/import/m4/error.m4: New file. * gnulib/import/m4/fchdir.m4: New file. * gnulib/import/m4/fcntl.m4: New file. * gnulib/import/m4/fcntl_h.m4: New file. * gnulib/import/m4/fdopendir.m4: New file. * gnulib/import/m4/filenamecat.m4: New file. * gnulib/import/m4/fstat.m4: New file. * gnulib/import/m4/fstatat.m4: New file. * gnulib/import/m4/getcwd-abort-bug.m4: New file. * gnulib/import/m4/getcwd-path-max.m4: New file. * gnulib/import/m4/getcwd.m4: New file. * gnulib/import/m4/getdtablesize.m4: New file. * gnulib/import/m4/getlogin_r.m4: New file. * gnulib/import/m4/getprogname.m4: New file. * gnulib/import/m4/glob.m4: New file. * gnulib/import/m4/gnulib-cache.m4: Regenerate. * gnulib/import/m4/gnulib-comp.m4: Regenerate. * gnulib/import/m4/mempcpy.m4: New file. * gnulib/import/m4/memrchr.m4: New file. * gnulib/import/m4/mode_t.m4: New file. * gnulib/import/m4/msvc-inval.m4: New file. * gnulib/import/m4/msvc-nothrow.m4: New file. * gnulib/import/m4/open.m4: New file. * gnulib/import/m4/openat.m4: New file. * gnulib/import/m4/opendir.m4: New file. * gnulib/import/m4/readdir.m4: New file. * gnulib/import/m4/realloc.m4: New file. * gnulib/import/m4/rewinddir.m4: New file. * gnulib/import/m4/save-cwd.m4: New file. * gnulib/import/m4/strdup.m4: New file. * gnulib/import/m4/strerror.m4: New file. * gnulib/import/m4/unistd-safer.m4: New file. * gnulib/import/mempcpy.c: New file. * gnulib/import/memrchr.c: New file. * gnulib/import/msvc-inval.c: New file. * gnulib/import/msvc-inval.h: New file. * gnulib/import/msvc-nothrow.c: New file. * gnulib/import/msvc-nothrow.h: New file. * gnulib/import/open.c: New file. * gnulib/import/openat-die.c: New file. * gnulib/import/openat-priv.h: New file. * gnulib/import/openat-proc.c: New file. * gnulib/import/openat.c: New file. * gnulib/import/openat.h: New file. * gnulib/import/opendir.c: New file. * gnulib/import/pipe-safer.c: New file. * gnulib/import/readdir.c: New file. * gnulib/import/realloc.c: New file. * gnulib/import/rewinddir.c: New file. * gnulib/import/save-cwd.c: New file. * gnulib/import/save-cwd.h: New file. * gnulib/import/strdup.c: New file. * gnulib/import/strerror-override.c: New file. * gnulib/import/strerror-override.h: New file. * gnulib/import/strerror.c: New file. * gnulib/import/unistd--.h: New file. * gnulib/import/unistd-safer.h: New file. * gnulib/update-gnulib.sh (IMPORTED_GNULIB_MODULES): Add "getcwd" and "glob". * ser-tcp.c: Undefine "close" before redefining it.
2017-09-09 02:09:12 +02:00
/* Gnulib defines close too, but gnulib's replacement
doesn't call closesocket unless we import the
socketlib module. */
#undef close
#define close(fd) closesocket (fd)
#define ioctl ioctlsocket
#else
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#endif
#include <signal.h>
#include "gdb_select.h"
gdb: Use std::min and std::max throughout Otherwise including <string> or some other C++ header is broken. E.g.: In file included from /opt/gcc/include/c++/7.0.0/bits/char_traits.h:39:0, from /opt/gcc/include/c++/7.0.0/string:40, from /home/pedro/gdb/mygit/cxx-convertion/src/gdb/infrun.c:68: /opt/gcc/include/c++/7.0.0/bits/stl_algobase.h:243:56: error: macro "min" passed 3 arguments, but takes just 2 min(const _Tp& __a, const _Tp& __b, _Compare __comp) ^ /opt/gcc/include/c++/7.0.0/bits/stl_algobase.h:265:56: error: macro "max" passed 3 arguments, but takes just 2 max(const _Tp& __a, const _Tp& __b, _Compare __comp) ^ In file included from .../src/gdb/infrun.c:21:0: To the best of my grepping abilities, I believe I adjusted all min/max calls. gdb/ChangeLog: 2016-09-16 Pedro Alves <palves@redhat.com> * defs.h (min, max): Delete. * aarch64-tdep.c: Include <algorithm> and use std::min and std::max throughout. * aarch64-tdep.c: Likewise. * alpha-tdep.c: Likewise. * amd64-tdep.c: Likewise. * amd64-windows-tdep.c: Likewise. * arm-tdep.c: Likewise. * avr-tdep.c: Likewise. * breakpoint.c: Likewise. * btrace.c: Likewise. * ctf.c: Likewise. * disasm.c: Likewise. * doublest.c: Likewise. * dwarf2loc.c: Likewise. * dwarf2read.c: Likewise. * environ.c: Likewise. * exec.c: Likewise. * f-exp.y: Likewise. * findcmd.c: Likewise. * ft32-tdep.c: Likewise. * gcore.c: Likewise. * hppa-tdep.c: Likewise. * i386-darwin-tdep.c: Likewise. * i386-tdep.c: Likewise. * linux-thread-db.c: Likewise. * lm32-tdep.c: Likewise. * m32r-tdep.c: Likewise. * m88k-tdep.c: Likewise. * memrange.c: Likewise. * minidebug.c: Likewise. * mips-tdep.c: Likewise. * moxie-tdep.c: Likewise. * nds32-tdep.c: Likewise. * nios2-tdep.c: Likewise. * nto-procfs.c: Likewise. * parse.c: Likewise. * ppc-sysv-tdep.c: Likewise. * probe.c: Likewise. * record-btrace.c: Likewise. * remote.c: Likewise. * rs6000-tdep.c: Likewise. * rx-tdep.c: Likewise. * s390-linux-nat.c: Likewise. * s390-linux-tdep.c: Likewise. * ser-tcp.c: Likewise. * sh-tdep.c: Likewise. * sh64-tdep.c: Likewise. * source.c: Likewise. * sparc-tdep.c: Likewise. * symfile.c: Likewise. * target-memory.c: Likewise. * target.c: Likewise. * tic6x-tdep.c: Likewise. * tilegx-tdep.c: Likewise. * tracefile-tfile.c: Likewise. * tracepoint.c: Likewise. * valprint.c: Likewise. * value.c: Likewise. * xtensa-tdep.c: Likewise. * cli/cli-cmds.c: Likewise. * compile/compile-object-load.c: Likewise.
2016-09-16 20:55:17 +02:00
#include <algorithm>
#ifndef HAVE_SOCKLEN_T
typedef int socklen_t;
#endif
/* For "set tcp" and "show tcp". */
static struct cmd_list_element *tcp_set_cmdlist;
static struct cmd_list_element *tcp_show_cmdlist;
/* Whether to auto-retry refused connections. */
static int tcp_auto_retry = 1;
/* Timeout period for connections, in seconds. */
static unsigned int tcp_retry_limit = 15;
/* How many times per second to poll deprecated_ui_loop_hook. */
#define POLL_INTERVAL 5
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
/* Helper function to wait a while. If SOCK is not -1, wait on its
file descriptor. Otherwise just wait on a timeout, updating
*POLLS. Returns -1 on timeout or interrupt, otherwise the value of
select. */
static int
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
wait_for_connect (int sock, unsigned int *polls)
{
struct timeval t;
int n;
/* While we wait for the connect to complete,
poll the UI so it can update or the user can
interrupt. */
if (deprecated_ui_loop_hook && deprecated_ui_loop_hook (0))
{
errno = EINTR;
return -1;
}
/* Check for timeout. */
if (*polls > tcp_retry_limit * POLL_INTERVAL)
{
errno = ETIMEDOUT;
return -1;
}
/* Back off to polling once per second after the first POLL_INTERVAL
polls. */
if (*polls < POLL_INTERVAL)
{
t.tv_sec = 0;
t.tv_usec = 1000000 / POLL_INTERVAL;
}
else
{
t.tv_sec = 1;
t.tv_usec = 0;
}
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
if (sock >= 0)
{
fd_set rset, wset, eset;
FD_ZERO (&rset);
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
FD_SET (sock, &rset);
wset = rset;
eset = rset;
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
/* POSIX systems return connection success or failure by signalling
wset. Windows systems return success in wset and failure in
eset.
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
We must call select here, rather than gdb_select, because
the serial structure has not yet been initialized - the
MinGW select wrapper will not know that this FD refers
to a socket. */
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
n = select (sock + 1, &rset, &wset, &eset, &t);
}
else
/* Use gdb_select here, since we have no file descriptors, and on
Windows, plain select doesn't work in that case. */
n = gdb_select (0, NULL, NULL, NULL, &t);
/* If we didn't time out, only count it as one poll. */
if (n > 0 || *polls < POLL_INTERVAL)
(*polls)++;
else
(*polls) += POLL_INTERVAL;
return n;
}
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
/* Try to connect to the host represented by AINFO. If the connection
succeeds, return its socket. Otherwise, return -1 and set ERRNO
accordingly. POLLS is used when 'connect' returns EINPROGRESS, and
we need to invoke 'wait_for_connect' to obtain the status. */
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
static int
try_connect (const struct addrinfo *ainfo, unsigned int *polls)
{
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
int sock = gdb_socket_cloexec (ainfo->ai_family, ainfo->ai_socktype,
ainfo->ai_protocol);
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
if (sock < 0)
return -1;
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
/* Set socket nonblocking. */
#ifdef USE_WIN32API
u_long ioarg = 1;
#else
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
int ioarg = 1;
#endif
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
ioctl (sock, FIONBIO, &ioarg);
2011-01-05 Michael Snyder <msnyder@vmware.com> * addrmap.c: Shorten lines of >= 80 columns. * arch-utils.c: Ditto. * arch-utils.h: Ditto. * ax-gdb.c: Ditto. * ax-general.c: Ditto. * bcache.c: Ditto. * blockframe.c: Ditto. * breakpoint.c: Ditto. * buildsym.c: Ditto. * c-lang.c: Ditto. * c-typeprint.c: Ditto. * charset.c: Ditto. * coffread.c: Ditto. * command.h: Ditto. * corelow.c: Ditto. * cp-abi.c: Ditto. * cp-namespace.c: Ditto. * cp-support.c: Ditto. * dbug-rom.c: Ditto. * dbxread.c: Ditto. * defs.h: Ditto. * dfp.c: Ditto. * dfp.h: Ditto. * dictionary.c: Ditto. * disasm.c: Ditto. * doublest.c: Ditto. * dwarf2-frame.c: Ditto. * dwarf2expr.c: Ditto. * dwarf2loc.c: Ditto. * dwarf2read.c: Ditto. * elfread.c: Ditto. * eval.c: Ditto. * event-loop.c: Ditto. * event-loop.h: Ditto. * exceptions.h: Ditto. * exec.c: Ditto. * expprint.c: Ditto. * expression.h: Ditto. * f-lang.c: Ditto. * f-valprint.c: Ditto. * findcmd.c: Ditto. * frame-base.c: Ditto. * frame-unwind.c: Ditto. * frame-unwind.h: Ditto. * frame.c: Ditto. * frame.h: Ditto. * gcore.c: Ditto. * gdb-stabs.h: Ditto. * gdb_assert.h: Ditto. * gdb_dirent.h: Ditto. * gdb_obstack.h: Ditto. * gdbcore.h: Ditto. * gdbtypes.c: Ditto. * gdbtypes.h: Ditto. * inf-ttrace.c: Ditto. * infcall.c: Ditto. * infcmd.c: Ditto. * inflow.c: Ditto. * infrun.c: Ditto. * inline-frame.h: Ditto. * language.c: Ditto. * language.h: Ditto. * libunwind-frame.c: Ditto. * libunwind-frame.h: Ditto. * linespec.c: Ditto. * linux-nat.c: Ditto. * linux-nat.h: Ditto. * linux-thread-db.c: Ditto. * machoread.c: Ditto. * macroexp.c: Ditto. * macrotab.c: Ditto. * main.c: Ditto. * maint.c: Ditto. * mdebugread.c: Ditto. * memattr.c: Ditto. * minsyms.c: Ditto. * monitor.c: Ditto. * monitor.h: Ditto. * objfiles.c: Ditto. * objfiles.h: Ditto. * osabi.c: Ditto. * p-typeprint.c: Ditto. * p-valprint.c: Ditto. * parse.c: Ditto. * printcmd.c: Ditto. * proc-events.c: Ditto. * procfs.c: Ditto. * progspace.c: Ditto. * progspace.h: Ditto. * psympriv.h: Ditto. * psymtab.c: Ditto. * record.c: Ditto. * regcache.c: Ditto. * regcache.h: Ditto. * remote-fileio.c: Ditto. * remote.c: Ditto. * ser-mingw.c: Ditto. * ser-tcp.c: Ditto. * ser-unix.c: Ditto. * serial.c: Ditto. * serial.h: Ditto. * solib-frv.c: Ditto. * solib-irix.c: Ditto. * solib-osf.c: Ditto. * solib-pa64.c: Ditto. * solib-som.c: Ditto. * solib-sunos.c: Ditto. * solib-svr4.c: Ditto. * solib-target.c: Ditto. * solib.c: Ditto. * somread.c: Ditto. * source.c: Ditto. * stabsread.c: Ditto. * stabsread.c: Ditto. * stack.c: Ditto. * stack.h: Ditto. * symfile-mem.c: Ditto. * symfile.c: Ditto. * symfile.h: Ditto. * symmisc.c: Ditto. * symtab.c: Ditto. * symtab.h: Ditto. * target-descriptions.c: Ditto. * target-memory.c: Ditto. * target.c: Ditto. * target.h: Ditto. * terminal.h: Ditto. * thread.c: Ditto. * top.c: Ditto. * tracepoint.c: Ditto. * tracepoint.h: Ditto. * ui-file.c: Ditto. * ui-file.h: Ditto. * ui-out.h: Ditto. * user-regs.c: Ditto. * user-regs.h: Ditto. * utils.c: Ditto. * valarith.c: Ditto. * valops.c: Ditto. * valprint.c: Ditto. * valprint.h: Ditto. * value.c: Ditto. * varobj.c: Ditto. * varobj.h: Ditto. * vec.h: Ditto. * xcoffread.c: Ditto. * xcoffsolib.c: Ditto. * xcoffsolib.h: Ditto. * xml-syscall.c: Ditto. * xml-tdesc.c: Ditto.
2011-01-05 23:22:53 +01:00
/* Use Non-blocking connect. connect() will return 0 if connected
already. */
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
if (connect (sock, ainfo->ai_addr, ainfo->ai_addrlen) < 0)
{
#ifdef USE_WIN32API
int err = WSAGetLastError();
#else
int err = errno;
#endif
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
/* If we've got a "connection refused" error, just return
-1. The caller will know what to do. */
if (
#ifdef USE_WIN32API
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
err == WSAECONNREFUSED
#else
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
err == ECONNREFUSED
#endif
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
)
{
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
close (sock);
errno = err;
return -1;
}
if (
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
/* Any other error (except EINPROGRESS) will be "swallowed"
here. We return without specifying a return value, and
set errno if the caller wants to inspect what
happened. */
#ifdef USE_WIN32API
/* Under Windows, calling "connect" with a non-blocking socket
results in WSAEWOULDBLOCK, not WSAEINPROGRESS. */
err != WSAEWOULDBLOCK
#else
err != EINPROGRESS
#endif
)
{
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
close (sock);
errno = err;
return -1;
}
/* Looks like we need to wait for the connect. */
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
int n;
do
n = wait_for_connect (sock, polls);
while (n == 0);
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
if (n < 0)
{
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
int saved_errno = errno;
/* A negative value here means that we either timed out or
got interrupted by the user. Just return. */
close (sock);
errno = saved_errno;
return -1;
}
}
/* Got something. Is it an error? */
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
int err;
socklen_t len = sizeof (err);
/* On Windows, the fourth parameter to getsockopt is a "char *";
on UNIX systems it is generally "void *". The cast to "char *"
is OK everywhere, since in C++ any data pointer type can be
implicitly converted to "void *". */
int ret = getsockopt (sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len);
if (ret < 0)
{
int saved_errno = errno;
close (sock);
errno = saved_errno;
return -1;
}
else if (ret == 0 && err != 0)
{
close (sock);
errno = err;
return -1;
}
/* The connection succeeded. Return the socket. */
return sock;
}
/* Open a tcp socket. */
int
net_open (struct serial *scb, const char *name)
{
struct addrinfo hint;
struct addrinfo *ainfo;
memset (&hint, 0, sizeof (hint));
/* Assume no prefix will be passed, therefore we should use
AF_UNSPEC. */
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
hint.ai_protocol = IPPROTO_TCP;
parsed_connection_spec parsed = parse_connection_spec (name, &hint);
if (parsed.port_str.empty ())
error (_("Missing port on hostname '%s'"), name);
int r = getaddrinfo (parsed.host_str.c_str (),
parsed.port_str.c_str (),
&hint, &ainfo);
if (r != 0)
{
fprintf_unfiltered (gdb_stderr, _("%s: cannot resolve name: %s\n"),
name, gai_strerror (r));
errno = ENOENT;
return -1;
}
scoped_free_addrinfo free_ainfo (ainfo);
/* Flag to indicate whether we've got a connection refused. It will
be true if any of the connections tried was refused. */
bool got_connrefused;
/* If a connection succeeeds, SUCCESS_AINFO will point to the
'struct addrinfo' that succeed. */
struct addrinfo *success_ainfo = NULL;
unsigned int polls = 0;
/* Assume the worst. */
scb->fd = -1;
do
{
got_connrefused = false;
for (struct addrinfo *iter = ainfo; iter != NULL; iter = iter->ai_next)
{
/* Iterate over the list of possible addresses to connect
to. For each, we'll try to connect and see if it
succeeds. */
int sock = try_connect (iter, &polls);
if (sock >= 0)
{
/* We've gotten a successful connection. Save its
'struct addrinfo', the socket, and break. */
success_ainfo = iter;
scb->fd = sock;
break;
}
else if (
#ifdef USE_WIN32API
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
errno == WSAECONNREFUSED
#else
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
errno == ECONNREFUSED
#endif
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
)
got_connrefused = true;
}
}
/* Just retry if:
- tcp_auto_retry is true, and
- We haven't gotten a connection yet, and
- Any of our connection attempts returned with ECONNREFUSED, and
- wait_for_connect signals that we can keep going. */
while (tcp_auto_retry
&& success_ainfo == NULL
&& got_connrefused
&& wait_for_connect (-1, &polls) >= 0);
if (success_ainfo == NULL)
{
net_close (scb);
return -1;
}
/* Turn off nonblocking. */
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
#ifdef USE_WIN32API
u_long ioarg = 0;
#else
int ioarg = 0;
#endif
ioctl (scb->fd, FIONBIO, &ioarg);
Fix thinko when deciding whether to disable TCP's Nagle algorithm This patch fixes a thinko that happened when I was implementing the IPv6 support on GDB/gdbserver. On certain situations, it is necessary to disable TCP's Nagle algorithm (NODELAY). For obvious reasons, this only applies when we are dealing with a TCP connection. While implementing the IPv6 patch, I noticed that the net_open function (on gdb/ser-tcp.c) kept a flag indicating whether the connection type was UDP or TCP. I eliminated that flag, and started using the 'struct addrinfo *' related to the successful connection directly. However, I made a mistake: if (success_ainfo->ai_socktype == IPPROTO_TCP) ^^^^^^^^^^^ { /* Disable Nagle algorithm. Needed in some cases. */ int tmp = 1; setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY, (char *) &tmp, sizeof (tmp)); } The 'ai_socktype' field specifies the socket type (SOCK_STREAM or SOCK_DGRAM), and not the protocol. This test was always failing, and the Nagle algorithm was never being disabled. The obvious fix is to use the 'ai_protocol' field. This is what this patch does. Huge "thank you" to Joel Brobecker who reported the regression (he was experiencing an unusual delay while debugging a bare-metal program running under QEMU) and helped me set up a proper reproducer for the bug. gdb/ChangeLog: 2018-08-03 Sergio Durigan Junior <sergiodj@redhat.com> * ser-tcp.c (net_open): Fix thinko when deciding whether to disable TCP's Nagle algorithm (use "ai_protocol" instead of "ai_socktype").
2018-08-04 00:04:38 +02:00
if (success_ainfo->ai_protocol == IPPROTO_TCP)
{
/* Disable Nagle algorithm. Needed in some cases. */
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
int tmp = 1;
setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
Implement IPv6 support for GDB/gdbserver This patch implements IPv6 support for both GDB and gdbserver. Based on my research, it is the fourth attempt to do that since 2006. Since I used ideas from all of the previous patches, I also added their authors's names on the ChangeLogs as a way to recognize their efforts. For reference sake, you can find the previous attempts at: https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html The basic idea behind the patch is to start using the new 'getaddrinfo'/'getnameinfo' calls, which are responsible for translating names and addresses in a protocol-independent way. This means that if we ever have a new version of the IP protocol, we won't need to change the code again (or, at least, won't have to change the majority of the code). The function 'getaddrinfo' returns a linked list of possible addresses to connect to. Dealing with multiple addresses proved to be a hard task with the current TCP auto-retry mechanism implemented on ser-tcp:net_open. For example, when gdbserver listened only on an IPv4 socket: $ ./gdbserver --once 127.0.0.1:1234 ./a.out and GDB was instructed to try to connect to both IPv6 and IPv4 sockets: $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out the user would notice a somewhat big delay before GDB was able to connect to the IPv4 socket. This happened because GDB was trying to connect to the IPv6 socket first, and had to wait until the connection timed out before it tried to connect to the IPv4 socket. For that reason, I had to rewrite the main loop and implement a new method for handling multiple connections. After some discussion, Pedro and I agreed on the following algorithm: 1) For each entry returned by 'getaddrinfo', we try to open a socket and connect to it. 2.a) If we have a successful 'connect', we just use that connection. 2.b) If we don't have a successfull 'connect', but if we've got a ECONNREFUSED (meaning the the connection was refused), we keep track of this fact by using a flag. 2.c) If we don't have a successfull 'connect', but if we've got a EINPROGRESS (meaning that the connection is in progress), we perform a 'select' call on the socket until we have a result (either a successful connection, or an error on the socket). 3) If tcp_auto_retry is true, and we haven't gotten a successful connection, and at least one of our attempts failed with ECONNREFUSED, then we wait a little bit (i.e., call 'wait_for_connect'), check to see if there was a timeout/interruption (in which case we bail out), and then go back to (1). After multiple tests, I was able to connect without delay on the scenario described above, and was also able to connect in all other types of scenarios. I also implemented some hostname parsing functions (along with their corresponding unit tests) which are used to help GDB and gdbserver to parse hostname strings provided by the user. These new functions are living inside common/netstuff.[ch]. I've had to do that since IPv6 introduces a new URL scheme, which defines that square brackets can be used to enclose the host part and differentiate it from the port (e.g., "[::1]:1234" means "host ::1, port 1234"). I spent some time thinking about a reasonable way to interpret what the user wants, and I came up with the following: - If the user has provided a prefix that doesn't specify the protocol version (i.e., "tcp:" or "udp:"), or if the user has not provided any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when dealing with 'getaddrinfo') *unless* the host starts with "[" (in which case, assume it's an IPv6 host). - If the user has provided a prefix that does specify the protocol version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect that. This method doesn't follow strictly what RFC 2732 proposes (that literal IPv6 addresses should be provided enclosed in "[" and "]") because IPv6 addresses still can be provided without square brackets in our case, but since we have prefixes to specify protocol versions I think this is not an issue. Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST' testcase parameter, which makes it possible to specify the hostname (without the port) to be used when testing GDB and gdbserver. For example, to run IPv6 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]' Or, to run IPv4 tests: $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1' This required a few changes on the gdbserver-base.exp, and also a minimal adjustment on gdb.server/run-without-local-binary.exp. Finally, I've implemented a new testcase, gdb.server/server-connect.exp, which is supposed to run on the native host and perform various "smoke tests" using different connection methods. This patch has been regression-tested on BuildBot and locally, and also built using a x86_64-w64-mingw32 GCC, and no problems were found. gdb/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add 'unittests/parse-connection-spec-selftests.c'. (COMMON_SFILES): Add 'common/netstuff.c'. (HFILES_NO_SRCDIR): Add 'common/netstuff.h'. * NEWS (Changes since GDB 8.2): Mention IPv6 support. * common/netstuff.c: New file. * common/netstuff.h: New file. * ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'. (wait_for_connect): Update comment. New parameter 'gdb::optional<int> sock' instead of 'struct serial *scb'. Use 'sock' directly instead of 'scb->fd'. (try_connect): New function, with code from 'net_open'. (net_open): Rewrite main loop to deal with multiple sockets/addresses. Handle IPv6-style hostnames; implement support for IPv6 connections. * unittests/parse-connection-spec-selftests.c: New file. gdb/gdbserver/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'. (OBS): Add 'common/netstuff.o'. (GDBREPLAY_OBS): Likewise. * gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'. (remote_open): Implement support for IPv6 connections. * remote-utils.c: Include 'netstuff.h', 'filestuff.h' and 'wspiapi.h'. (handle_accept_event): Accept connections from IPv6 sources. (remote_prepare): Handle IPv6-style hostnames; implement support for IPv6 connections. (remote_open): Implement support for printing connections from IPv6 sources. gdb/testsuite/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST' parameter. * boards/native-extended-gdbserver.exp: Do not set 'sockethost' by default. * boards/native-gdbserver.exp: Likewise. * gdb.server/run-without-local-binary.exp: Improve regexp used for detecting when a remote debugging connection succeeds. * gdb.server/server-connect.exp: New file. * lib/gdbserver-support.exp (gdbserver_default_get_comm_port): Do not prefix the port number with ":". (gdbserver_start): New global GDB_TEST_SOCKETHOST. Implement support for detecting and using it. Add '$debughost_gdbserver' to the list of arguments used to start gdbserver. Handle case when gdbserver cannot resolve a network name. gdb/doc/ChangeLog: 2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com> Paul Fertser <fercerpav@gmail.com> Tsutomu Seki <sekiriki@gmail.com> * gdb.texinfo (Remote Connection Commands): Add explanation about new IPv6 support. Add new connection prefixes.
2018-05-18 07:29:24 +02:00
(char *) &tmp, sizeof (tmp));
}
#ifdef SIGPIPE
/* If we don't do this, then GDB simply exits
when the remote side dies. */
signal (SIGPIPE, SIG_IGN);
#endif
return 0;
}
* NEWS: Mention native Windows support. * Makefile.in (gdb_select_h, ser_tcp_h): New. (ALLDEPFILES): Add ser-mingw.c. (event-loop.o, inflow.o, mingw-hdep.o, posix-hdep.o, ser-base.o) (ser-tcp.o, ser-unix.o): Update. (ser-mingw.o): New rule. * configure: Regenerated. * configure.ac: Add ser-mingw.o for mingw32. * ser-mingw.c: New file. * event-loop.c: Include "gdb_select.h". (gdb_select): Remove, moved to mingw-hdep.c and posix-hdep.c. * ser-base.c: Include "gdb_select.h". (ser_base_wait_for): Use gdb_select. * serial.c (serial_for_fd): New function. (serial_fdopen): Try "terminal" before "hardwire". Initialize the allocated struct serial. (serial_wait_handle): New function. * serial.h (serial_for_fd, serial_wait_handle): New prototypes. (struct serial_ops) [USE_WIN32API]: Add wait_handle. * gdb_select.h: New file. * ser-tcp.c: Include "ser-tcp.h". Remove unused "ser-unix.h" include. (net_close, net_read_prim, net_write_prim): Make global. (net_open): Likewise. Pass an exception set to select. Whitespace fix. Document why we can not use gdb_select. (_initialize_ser_tcp) [USE_WIN32API]: Do not register TCP support here. * ser-tcp.h: New file. * inflow.c (gdb_has_a_terminal): Don't initialize stdin_serial here. (handle_sigio): Use gdb_select. (initialize_stdin_serial): New function. * terminal.h (initialize_stdin_serial): New prototype. * top.c (gdb_init): Call initialize_stdin_serial. * mingw-hdep.c (gdb_select): New function, moved from gdb_select in event-loop.c. Add exception condition support. Use serial_for_fd and serial_wait_handle. Fix timeout handling. * posix-hdep.c: Include "gdb_select.h". (gdb_select): New function. * remote-st.c (connect_command): Use gdb_select. * ser-unix.c: Include "gdb_select.h". (hardwire_send_break, wait_for): Use gdb_select.
2006-02-10 23:01:43 +01:00
void
net_close (struct serial *scb)
{
if (scb->fd == -1)
return;
1999-07-07 22:19:36 +02:00
close (scb->fd);
scb->fd = -1;
}
* NEWS: Mention native Windows support. * Makefile.in (gdb_select_h, ser_tcp_h): New. (ALLDEPFILES): Add ser-mingw.c. (event-loop.o, inflow.o, mingw-hdep.o, posix-hdep.o, ser-base.o) (ser-tcp.o, ser-unix.o): Update. (ser-mingw.o): New rule. * configure: Regenerated. * configure.ac: Add ser-mingw.o for mingw32. * ser-mingw.c: New file. * event-loop.c: Include "gdb_select.h". (gdb_select): Remove, moved to mingw-hdep.c and posix-hdep.c. * ser-base.c: Include "gdb_select.h". (ser_base_wait_for): Use gdb_select. * serial.c (serial_for_fd): New function. (serial_fdopen): Try "terminal" before "hardwire". Initialize the allocated struct serial. (serial_wait_handle): New function. * serial.h (serial_for_fd, serial_wait_handle): New prototypes. (struct serial_ops) [USE_WIN32API]: Add wait_handle. * gdb_select.h: New file. * ser-tcp.c: Include "ser-tcp.h". Remove unused "ser-unix.h" include. (net_close, net_read_prim, net_write_prim): Make global. (net_open): Likewise. Pass an exception set to select. Whitespace fix. Document why we can not use gdb_select. (_initialize_ser_tcp) [USE_WIN32API]: Do not register TCP support here. * ser-tcp.h: New file. * inflow.c (gdb_has_a_terminal): Don't initialize stdin_serial here. (handle_sigio): Use gdb_select. (initialize_stdin_serial): New function. * terminal.h (initialize_stdin_serial): New prototype. * top.c (gdb_init): Call initialize_stdin_serial. * mingw-hdep.c (gdb_select): New function, moved from gdb_select in event-loop.c. Add exception condition support. Use serial_for_fd and serial_wait_handle. Fix timeout handling. * posix-hdep.c: Include "gdb_select.h". (gdb_select): New function. * remote-st.c (connect_command): Use gdb_select. * ser-unix.c: Include "gdb_select.h". (hardwire_send_break, wait_for): Use gdb_select.
2006-02-10 23:01:43 +01:00
int
net_read_prim (struct serial *scb, size_t count)
{
/* Need to cast to silence -Wpointer-sign on MinGW, as Winsock's
'recv' takes 'char *' as second argument, while 'scb->buf' is
'unsigned char *'. */
return recv (scb->fd, (char *) scb->buf, count, 0);
}
* NEWS: Mention native Windows support. * Makefile.in (gdb_select_h, ser_tcp_h): New. (ALLDEPFILES): Add ser-mingw.c. (event-loop.o, inflow.o, mingw-hdep.o, posix-hdep.o, ser-base.o) (ser-tcp.o, ser-unix.o): Update. (ser-mingw.o): New rule. * configure: Regenerated. * configure.ac: Add ser-mingw.o for mingw32. * ser-mingw.c: New file. * event-loop.c: Include "gdb_select.h". (gdb_select): Remove, moved to mingw-hdep.c and posix-hdep.c. * ser-base.c: Include "gdb_select.h". (ser_base_wait_for): Use gdb_select. * serial.c (serial_for_fd): New function. (serial_fdopen): Try "terminal" before "hardwire". Initialize the allocated struct serial. (serial_wait_handle): New function. * serial.h (serial_for_fd, serial_wait_handle): New prototypes. (struct serial_ops) [USE_WIN32API]: Add wait_handle. * gdb_select.h: New file. * ser-tcp.c: Include "ser-tcp.h". Remove unused "ser-unix.h" include. (net_close, net_read_prim, net_write_prim): Make global. (net_open): Likewise. Pass an exception set to select. Whitespace fix. Document why we can not use gdb_select. (_initialize_ser_tcp) [USE_WIN32API]: Do not register TCP support here. * ser-tcp.h: New file. * inflow.c (gdb_has_a_terminal): Don't initialize stdin_serial here. (handle_sigio): Use gdb_select. (initialize_stdin_serial): New function. * terminal.h (initialize_stdin_serial): New prototype. * top.c (gdb_init): Call initialize_stdin_serial. * mingw-hdep.c (gdb_select): New function, moved from gdb_select in event-loop.c. Add exception condition support. Use serial_for_fd and serial_wait_handle. Fix timeout handling. * posix-hdep.c: Include "gdb_select.h". (gdb_select): New function. * remote-st.c (connect_command): Use gdb_select. * ser-unix.c: Include "gdb_select.h". (hardwire_send_break, wait_for): Use gdb_select.
2006-02-10 23:01:43 +01:00
int
net_write_prim (struct serial *scb, const void *buf, size_t count)
{
/* On Windows, the second parameter to send is a "const char *"; on
UNIX systems it is generally "const void *". The cast to "const
char *" is OK everywhere, since in C++ any data pointer type can
be implicitly converted to "const void *". */
return send (scb->fd, (const char *) buf, count, 0);
}
int
ser_tcp_send_break (struct serial *scb)
{
/* Send telnet IAC and BREAK characters. */
return (serial_write (scb, "\377\363", 2));
}
/* Support for "set tcp" and "show tcp" commands. */
static void
Constify add_prefix_cmd This changes add_prefix_cmd to accept a const-taking function as an argument; then fixes up all the callers. In a couple of spots I had to add a non-const overload of a function, because the function is passed to two different command-adding "constructors". These overloads are temporary; once constification is complete they can be removed. This patch also fixes a typo I happened to notice while constifying. Note that this touches a couple of files (gnu-nat.c and go32-nat.c) that I can't build. So, while I made a best-effort there, I am not certain they will still compile. Tested by rebuilding. gdb/ChangeLog 2017-10-11 Tom Tromey <tom@tromey.com> * gdbthread.h (thread_command): Constify. * inferior.h (detach_command): Constify. * top.h (set_history, show_history): Constify. * arm-tdep.c (set_arm_command, show_arm_command): Constify. * serial.c (serial_set_cmd, serial_show_cmd): Constify. * bsd-kvm.c (bsd_kvm_cmd): Constify. * printcmd.c (set_command): Constify. (non_const_set_command): New function. * dcache.c (set_dcache_command, show_dcache_command): Constify. * breakpoint.c (enable_command, disable_command, delete_command) (catch_command, tcatch_command, set_breakpoint_cmd) (show_breakpoint_cmd): Constify. * macrocmd.c (macro_command): Constify. * infcmd.c (unset_command, kill_command, detach_command) (info_proc_cmd): Constify. * i386-tdep.c (set_mpx_cmd, show_mpx_cmd): Constify. * auto-load.c (show_auto_load_cmd, set_auto_load_cmd) (info_auto_load_cmd): Constify. * target-descriptions.c (set_tdesc_cmd, show_tdesc_cmd) (unset_tdesc_cmd): Constify. * ada-lang.c (set_ada_command, show_ada_command) (maint_set_ada_cmd, maint_show_ada_cmd): Constify. * guile/guile.c (set_guile_command, show_guile_command) (info_guile_command): Constify. * tui/tui-win.c (tui_command, set_tui_cmd, show_tui_cmd): Constify. * skip.c (skip_command): Constify. * compile/compile.c (_initialize_compile): Constify. * dwarf2read.c (set_dwarf_cmd, show_dwarf_cmd): Constify. * btrace.c (maint_btrace_cmd, maint_btrace_set_cmd) (maint_btrace_show_cmd, maint_btrace_pt_set_cmd) (maint_btrace_pt_show_cmd): Constify. * remote.c (set_remote_cmd, show_remote_cmd, remote_command): Constify. * python/python.c (user_show_python, user_set_python): Constify. * mips-tdep.c (set_mips_command, show_mips_command) (set_mipsfpu_command): Constify. * record-btrace.c (cmd_record_btrace_start) (cmd_set_record_btrace, cmd_show_record_btrace) (cmd_set_record_btrace_bts, cmd_show_record_btrace_bts) (cmd_set_record_btrace_pt, cmd_show_record_btrace_pt): Constify. * rs6000-tdep.c (set_powerpc_command, show_powerpc_command): Constify. * symfile.c (overlay_command): Constify. * spu-tdep.c (set_spu_command, show_spu_command): Constify. * cli/cli-logging.c (set_logging_command, show_logging_command): Constify. * cli/cli-dump.c (dump_command, append_command) (srec_dump_command, ihex_dump_command, verilog_dump_command) (tekhex_dump_command, binary_dump_command) (binary_append_command): Constify. * cli/cli-decode.c (struct cmd_list_element): Change type of "fun". * cli/cli-cmds.c (info_command, show_command, set_debug) (show_debug): Constify. (show_command): Add non-const overload. * top.c (set_history, show_history): Constify. * sh-tdep.c (set_sh_command, show_sh_command): Constify. * command.h (add_prefix_cmd): Accept a cmd_const_cfunc_ftype. * target.c (target_command): Constify. * sparc64-tdep.c (info_adi_command): Constify. * record-full.c (cmd_record_full_start): Constify. (set_record_full_command): Constify. Fix typo. (show_record_full_command): Constify. * thread.c (thread_command, thread_apply_command): Constify. * memattr.c (dummy_cmd): Constify. * value.c (function_command): Constify. * frame.c (set_backtrace_cmd, show_backtrace_cmd): Constify. * probe.c (info_probes_command): Constify. * ser-tcp.c (set_tcp_cmd, show_tcp_cmd): Constify. * gnu-nat.c (set_task_cmd, show_task_cmd, set_thread_cmd) (show_thread_cmd, set_thread_default_cmd) (show_thread_default_cmd): Constify. (check_empty): Constify. * tracepoint.c (tfind_command): Constify. * cp-support.c (maint_cplus_command): Constify. * windows-tdep.c (info_w32_command): Constify. * record.c (cmd_record_start, set_record_command) (show_record_command, info_record_command, cmd_record_goto): Constify. * ravenscar-thread.c (set_ravenscar_command) (show_ravenscar_command): Constify. * utils.c (set_internal_problem_cmd, show_internal_problem_cmd): Constify. (add_internal_problem_command): Remove casts. * arc-tdep.c (maintenance_print_arc_command): Constify. * valprint.c (set_print, show_print, set_print_raw) (show_print_raw): Constify. * maint.c (maintenance_command, maintenance_info_command) (maintenance_print_command, maintenance_set_cmd) (maintenance_show_cmd, set_per_command_cmd) (show_per_command_cmd, maintenance_check_command): Constify. * language.c (set_check, show_check): Constify. * typeprint.c (show_print_type, set_print_type): Constify. * go32-nat.c (go32_info_dos_command): Constify.
2017-09-26 06:28:30 +02:00
set_tcp_cmd (const char *args, int from_tty)
{
make calls to help_list use enumerator Currently there are many calls to help_list that pass the constant -1 as the "class" value. However, the parameter is declared as being of type enum command_class, and uses of the constant violate this abstraction. This patch fixes the error everywhere it occurs in the gdb sources. Tested by rebuilding. 2014-06-13 Tom Tromey <tromey@redhat.com> * cp-support.c (maint_cplus_command): Pass all_commands, not -1, to help_list. * guile/guile.c (info_guile_command): Pass all_commands, not -1, to help_list. * tui/tui-win.c (tui_command): Pass all_commands, not -1, to help_list. * tui/tui-regs.c (tui_reg_command): Pass all_commands, not -1, to help_list.Pass all_commands, not -1, to help_list. * cli/cli-dump.c (dump_command, append_command) (srec_dump_command, ihex_dump_command, tekhex_dump_command) (binary_dump_command, binary_append_command): Pass all_commands, not -1, to help_list. * cli/cli-cmds.c (info_command, set_debug): Pass all_commands, not -1, to help_list. * valprint.c (set_print, set_print_raw): Pass all_commands, not -1, to help_list. * typeprint.c (set_print_type): Pass all_commands, not -1, to help_list. * top.c (set_history): Pass all_commands, not -1, to help_list. * target-descriptions.c (set_tdesc_cmd, unset_tdesc_cmd): Pass all_commands, not -1, to help_list. * symfile.c (overlay_command): Pass all_commands, not -1, to help_list. * spu-tdep.c (info_spu_command): Pass all_commands, not -1, to help_list. * serial.c (serial_set_cmd): Pass all_commands, not -1, to help_list. * ser-tcp.c (set_tcp_cmd, show_tcp_cmd): Pass all_commands, not -1, to help_list. * remote.c (remote_command, set_remote_cmd): Pass all_commands, not -1, to help_list. * ravenscar-thread.c (set_ravenscar_command): Pass all_commands, not -1, to help_list. * maint.c (maintenance_command, maintenance_info_command) (maintenance_print_command, maintenance_set_cmd): Pass all_commands, not -1, to help_list. * macrocmd.c (macro_command): Pass all_commands, not -1, to help_list. * language.c (set_check): Pass all_commands, not -1, to help_list. * infcmd.c (unset_command): Pass all_commands, not -1, to help_list. * frame.c (set_backtrace_cmd): Pass all_commands, not -1, to help_list. * dwarf2read.c (set_dwarf2_cmd): Pass all_commands, not -1, to help_list. * dcache.c (set_dcache_command): Pass all_commands, not -1, to help_list. * breakpoint.c (save_command): Pass all_commands, not -1, to help_list. * ada-lang.c (maint_set_ada_cmd, set_ada_command): Pass all_commands, not -1, to help_list.
2014-06-05 16:25:00 +02:00
help_list (tcp_set_cmdlist, "set tcp ", all_commands, gdb_stdout);
}
static void
Constify add_prefix_cmd This changes add_prefix_cmd to accept a const-taking function as an argument; then fixes up all the callers. In a couple of spots I had to add a non-const overload of a function, because the function is passed to two different command-adding "constructors". These overloads are temporary; once constification is complete they can be removed. This patch also fixes a typo I happened to notice while constifying. Note that this touches a couple of files (gnu-nat.c and go32-nat.c) that I can't build. So, while I made a best-effort there, I am not certain they will still compile. Tested by rebuilding. gdb/ChangeLog 2017-10-11 Tom Tromey <tom@tromey.com> * gdbthread.h (thread_command): Constify. * inferior.h (detach_command): Constify. * top.h (set_history, show_history): Constify. * arm-tdep.c (set_arm_command, show_arm_command): Constify. * serial.c (serial_set_cmd, serial_show_cmd): Constify. * bsd-kvm.c (bsd_kvm_cmd): Constify. * printcmd.c (set_command): Constify. (non_const_set_command): New function. * dcache.c (set_dcache_command, show_dcache_command): Constify. * breakpoint.c (enable_command, disable_command, delete_command) (catch_command, tcatch_command, set_breakpoint_cmd) (show_breakpoint_cmd): Constify. * macrocmd.c (macro_command): Constify. * infcmd.c (unset_command, kill_command, detach_command) (info_proc_cmd): Constify. * i386-tdep.c (set_mpx_cmd, show_mpx_cmd): Constify. * auto-load.c (show_auto_load_cmd, set_auto_load_cmd) (info_auto_load_cmd): Constify. * target-descriptions.c (set_tdesc_cmd, show_tdesc_cmd) (unset_tdesc_cmd): Constify. * ada-lang.c (set_ada_command, show_ada_command) (maint_set_ada_cmd, maint_show_ada_cmd): Constify. * guile/guile.c (set_guile_command, show_guile_command) (info_guile_command): Constify. * tui/tui-win.c (tui_command, set_tui_cmd, show_tui_cmd): Constify. * skip.c (skip_command): Constify. * compile/compile.c (_initialize_compile): Constify. * dwarf2read.c (set_dwarf_cmd, show_dwarf_cmd): Constify. * btrace.c (maint_btrace_cmd, maint_btrace_set_cmd) (maint_btrace_show_cmd, maint_btrace_pt_set_cmd) (maint_btrace_pt_show_cmd): Constify. * remote.c (set_remote_cmd, show_remote_cmd, remote_command): Constify. * python/python.c (user_show_python, user_set_python): Constify. * mips-tdep.c (set_mips_command, show_mips_command) (set_mipsfpu_command): Constify. * record-btrace.c (cmd_record_btrace_start) (cmd_set_record_btrace, cmd_show_record_btrace) (cmd_set_record_btrace_bts, cmd_show_record_btrace_bts) (cmd_set_record_btrace_pt, cmd_show_record_btrace_pt): Constify. * rs6000-tdep.c (set_powerpc_command, show_powerpc_command): Constify. * symfile.c (overlay_command): Constify. * spu-tdep.c (set_spu_command, show_spu_command): Constify. * cli/cli-logging.c (set_logging_command, show_logging_command): Constify. * cli/cli-dump.c (dump_command, append_command) (srec_dump_command, ihex_dump_command, verilog_dump_command) (tekhex_dump_command, binary_dump_command) (binary_append_command): Constify. * cli/cli-decode.c (struct cmd_list_element): Change type of "fun". * cli/cli-cmds.c (info_command, show_command, set_debug) (show_debug): Constify. (show_command): Add non-const overload. * top.c (set_history, show_history): Constify. * sh-tdep.c (set_sh_command, show_sh_command): Constify. * command.h (add_prefix_cmd): Accept a cmd_const_cfunc_ftype. * target.c (target_command): Constify. * sparc64-tdep.c (info_adi_command): Constify. * record-full.c (cmd_record_full_start): Constify. (set_record_full_command): Constify. Fix typo. (show_record_full_command): Constify. * thread.c (thread_command, thread_apply_command): Constify. * memattr.c (dummy_cmd): Constify. * value.c (function_command): Constify. * frame.c (set_backtrace_cmd, show_backtrace_cmd): Constify. * probe.c (info_probes_command): Constify. * ser-tcp.c (set_tcp_cmd, show_tcp_cmd): Constify. * gnu-nat.c (set_task_cmd, show_task_cmd, set_thread_cmd) (show_thread_cmd, set_thread_default_cmd) (show_thread_default_cmd): Constify. (check_empty): Constify. * tracepoint.c (tfind_command): Constify. * cp-support.c (maint_cplus_command): Constify. * windows-tdep.c (info_w32_command): Constify. * record.c (cmd_record_start, set_record_command) (show_record_command, info_record_command, cmd_record_goto): Constify. * ravenscar-thread.c (set_ravenscar_command) (show_ravenscar_command): Constify. * utils.c (set_internal_problem_cmd, show_internal_problem_cmd): Constify. (add_internal_problem_command): Remove casts. * arc-tdep.c (maintenance_print_arc_command): Constify. * valprint.c (set_print, show_print, set_print_raw) (show_print_raw): Constify. * maint.c (maintenance_command, maintenance_info_command) (maintenance_print_command, maintenance_set_cmd) (maintenance_show_cmd, set_per_command_cmd) (show_per_command_cmd, maintenance_check_command): Constify. * language.c (set_check, show_check): Constify. * typeprint.c (show_print_type, set_print_type): Constify. * go32-nat.c (go32_info_dos_command): Constify.
2017-09-26 06:28:30 +02:00
show_tcp_cmd (const char *args, int from_tty)
{
make calls to help_list use enumerator Currently there are many calls to help_list that pass the constant -1 as the "class" value. However, the parameter is declared as being of type enum command_class, and uses of the constant violate this abstraction. This patch fixes the error everywhere it occurs in the gdb sources. Tested by rebuilding. 2014-06-13 Tom Tromey <tromey@redhat.com> * cp-support.c (maint_cplus_command): Pass all_commands, not -1, to help_list. * guile/guile.c (info_guile_command): Pass all_commands, not -1, to help_list. * tui/tui-win.c (tui_command): Pass all_commands, not -1, to help_list. * tui/tui-regs.c (tui_reg_command): Pass all_commands, not -1, to help_list.Pass all_commands, not -1, to help_list. * cli/cli-dump.c (dump_command, append_command) (srec_dump_command, ihex_dump_command, tekhex_dump_command) (binary_dump_command, binary_append_command): Pass all_commands, not -1, to help_list. * cli/cli-cmds.c (info_command, set_debug): Pass all_commands, not -1, to help_list. * valprint.c (set_print, set_print_raw): Pass all_commands, not -1, to help_list. * typeprint.c (set_print_type): Pass all_commands, not -1, to help_list. * top.c (set_history): Pass all_commands, not -1, to help_list. * target-descriptions.c (set_tdesc_cmd, unset_tdesc_cmd): Pass all_commands, not -1, to help_list. * symfile.c (overlay_command): Pass all_commands, not -1, to help_list. * spu-tdep.c (info_spu_command): Pass all_commands, not -1, to help_list. * serial.c (serial_set_cmd): Pass all_commands, not -1, to help_list. * ser-tcp.c (set_tcp_cmd, show_tcp_cmd): Pass all_commands, not -1, to help_list. * remote.c (remote_command, set_remote_cmd): Pass all_commands, not -1, to help_list. * ravenscar-thread.c (set_ravenscar_command): Pass all_commands, not -1, to help_list. * maint.c (maintenance_command, maintenance_info_command) (maintenance_print_command, maintenance_set_cmd): Pass all_commands, not -1, to help_list. * macrocmd.c (macro_command): Pass all_commands, not -1, to help_list. * language.c (set_check): Pass all_commands, not -1, to help_list. * infcmd.c (unset_command): Pass all_commands, not -1, to help_list. * frame.c (set_backtrace_cmd): Pass all_commands, not -1, to help_list. * dwarf2read.c (set_dwarf2_cmd): Pass all_commands, not -1, to help_list. * dcache.c (set_dcache_command): Pass all_commands, not -1, to help_list. * breakpoint.c (save_command): Pass all_commands, not -1, to help_list. * ada-lang.c (maint_set_ada_cmd, set_ada_command): Pass all_commands, not -1, to help_list.
2014-06-05 16:25:00 +02:00
help_list (tcp_show_cmdlist, "show tcp ", all_commands, gdb_stdout);
}
#ifndef USE_WIN32API
/* The TCP ops. */
static const struct serial_ops tcp_ops =
{
"tcp",
net_open,
net_close,
NULL,
ser_base_readchar,
ser_base_write,
ser_base_flush_output,
ser_base_flush_input,
ser_tcp_send_break,
ser_base_raw,
ser_base_get_tty_state,
ser_base_copy_tty_state,
ser_base_set_tty_state,
ser_base_print_tty_state,
ser_base_setbaudrate,
ser_base_setstopbits,
GDB: Add set/show serial parity command. The "set serial parity" command allows the user to control which parity to use when communicating over a serial connection, rather than having the parity hardcoded to none. gdb/ChangeLog: * NEWS: Mention set/show serial parity command. * monitor.c (monitor_open): Call serial_setparity. * remote.c (remote_open_1): Likewise. * ser-base.c (ser_base_serparity): New function. * ser-base.h (ser_base_setparity): Add declaration. * ser-go32.c (dos_ops): Set "setparity" field. * ser-mingw.c (ser_windows_raw): Do not set state.fParity and state.Parity. (ser_windows_setparity): New function. (hardwire_ops): Add ser_windows_setparity. (tty_ops): Add NULL for setparity field. (pipe_ops): Add ser_base_setparity. (tcp_ops): Likewise. * ser-pipe.c (pipe_ops): Likewise. * ser-tcp.c (tcp_ops): Likewise. * ser-unix.c (hardwire_setparity): Add declaration. (hardwire_raw): Don't reset PARENB flag. (hardwire_setparity): New function. (hardwire_ops): Add hardwire_setparity. * serial.c (serial_setparity): New function. (serial_parity): New global. (parity_none, parity_odd, parity_even, parity_enums, parity): New static globals. (set_parity): New function. (_initialize_serial): Add set/show serial parity commands. * serial.h (GDBPARITY_NONE): Define. (GDBPARITY_ODD): Define. (GDBPARITY_EVEN): Define. (serial_setparity) Add declaration. (struct serial_ops): Add setparity field. * target.h (serial_parity): Add declaration. gdb/doc/ChangeLog: * gdb.texinfo (Remote configuration): Document "set/show serial parity" command.
2015-03-23 22:15:42 +01:00
ser_base_setparity,
ser_base_drain_output,
ser_base_async,
net_read_prim,
net_write_prim
};
#endif /* USE_WIN32API */
void
1999-09-22 05:28:34 +02:00
_initialize_ser_tcp (void)
{
#ifdef USE_WIN32API
* NEWS: Mention native Windows support. * Makefile.in (gdb_select_h, ser_tcp_h): New. (ALLDEPFILES): Add ser-mingw.c. (event-loop.o, inflow.o, mingw-hdep.o, posix-hdep.o, ser-base.o) (ser-tcp.o, ser-unix.o): Update. (ser-mingw.o): New rule. * configure: Regenerated. * configure.ac: Add ser-mingw.o for mingw32. * ser-mingw.c: New file. * event-loop.c: Include "gdb_select.h". (gdb_select): Remove, moved to mingw-hdep.c and posix-hdep.c. * ser-base.c: Include "gdb_select.h". (ser_base_wait_for): Use gdb_select. * serial.c (serial_for_fd): New function. (serial_fdopen): Try "terminal" before "hardwire". Initialize the allocated struct serial. (serial_wait_handle): New function. * serial.h (serial_for_fd, serial_wait_handle): New prototypes. (struct serial_ops) [USE_WIN32API]: Add wait_handle. * gdb_select.h: New file. * ser-tcp.c: Include "ser-tcp.h". Remove unused "ser-unix.h" include. (net_close, net_read_prim, net_write_prim): Make global. (net_open): Likewise. Pass an exception set to select. Whitespace fix. Document why we can not use gdb_select. (_initialize_ser_tcp) [USE_WIN32API]: Do not register TCP support here. * ser-tcp.h: New file. * inflow.c (gdb_has_a_terminal): Don't initialize stdin_serial here. (handle_sigio): Use gdb_select. (initialize_stdin_serial): New function. * terminal.h (initialize_stdin_serial): New prototype. * top.c (gdb_init): Call initialize_stdin_serial. * mingw-hdep.c (gdb_select): New function, moved from gdb_select in event-loop.c. Add exception condition support. Use serial_for_fd and serial_wait_handle. Fix timeout handling. * posix-hdep.c: Include "gdb_select.h". (gdb_select): New function. * remote-st.c (connect_command): Use gdb_select. * ser-unix.c: Include "gdb_select.h". (hardwire_send_break, wait_for): Use gdb_select.
2006-02-10 23:01:43 +01:00
/* Do nothing; the TCP serial operations will be initialized in
ser-mingw.c. */
#else
serial_add_interface (&tcp_ops);
* NEWS: Mention native Windows support. * Makefile.in (gdb_select_h, ser_tcp_h): New. (ALLDEPFILES): Add ser-mingw.c. (event-loop.o, inflow.o, mingw-hdep.o, posix-hdep.o, ser-base.o) (ser-tcp.o, ser-unix.o): Update. (ser-mingw.o): New rule. * configure: Regenerated. * configure.ac: Add ser-mingw.o for mingw32. * ser-mingw.c: New file. * event-loop.c: Include "gdb_select.h". (gdb_select): Remove, moved to mingw-hdep.c and posix-hdep.c. * ser-base.c: Include "gdb_select.h". (ser_base_wait_for): Use gdb_select. * serial.c (serial_for_fd): New function. (serial_fdopen): Try "terminal" before "hardwire". Initialize the allocated struct serial. (serial_wait_handle): New function. * serial.h (serial_for_fd, serial_wait_handle): New prototypes. (struct serial_ops) [USE_WIN32API]: Add wait_handle. * gdb_select.h: New file. * ser-tcp.c: Include "ser-tcp.h". Remove unused "ser-unix.h" include. (net_close, net_read_prim, net_write_prim): Make global. (net_open): Likewise. Pass an exception set to select. Whitespace fix. Document why we can not use gdb_select. (_initialize_ser_tcp) [USE_WIN32API]: Do not register TCP support here. * ser-tcp.h: New file. * inflow.c (gdb_has_a_terminal): Don't initialize stdin_serial here. (handle_sigio): Use gdb_select. (initialize_stdin_serial): New function. * terminal.h (initialize_stdin_serial): New prototype. * top.c (gdb_init): Call initialize_stdin_serial. * mingw-hdep.c (gdb_select): New function, moved from gdb_select in event-loop.c. Add exception condition support. Use serial_for_fd and serial_wait_handle. Fix timeout handling. * posix-hdep.c: Include "gdb_select.h". (gdb_select): New function. * remote-st.c (connect_command): Use gdb_select. * ser-unix.c: Include "gdb_select.h". (hardwire_send_break, wait_for): Use gdb_select.
2006-02-10 23:01:43 +01:00
#endif /* USE_WIN32API */
add_prefix_cmd ("tcp", class_maintenance, set_tcp_cmd, _("\
TCP protocol specific variables\n\
Configure variables specific to remote TCP connections"),
&tcp_set_cmdlist, "set tcp ",
0 /* allow-unknown */, &setlist);
add_prefix_cmd ("tcp", class_maintenance, show_tcp_cmd, _("\
TCP protocol specific variables\n\
Configure variables specific to remote TCP connections"),
&tcp_show_cmdlist, "show tcp ",
0 /* allow-unknown */, &showlist);
add_setshow_boolean_cmd ("auto-retry", class_obscure,
&tcp_auto_retry, _("\
Set auto-retry on socket connect"), _("\
Show auto-retry on socket connect"),
NULL, NULL, NULL,
&tcp_set_cmdlist, &tcp_show_cmdlist);
add_setshow_uinteger_cmd ("connect-timeout", class_obscure,
&tcp_retry_limit, _("\
Accept "set foo unlimited" in integer/uinteger/zuinteger_unlimited commands. Currently, several commands take "0" or "-1" to mean "unlimited". "show" knows when to print "unlimited": (gdb) show height Number of lines gdb thinks are in a page is 45. (gdb) set height 0 (gdb) show height Number of lines gdb thinks are in a page is unlimited. However, the user can't herself specify "unlimited" directly: (gdb) set height unlimited No symbol table is loaded. Use the "file" command. (gdb) This patch addresses that, by adjusting the set handler for all integer/uinteger/zuinteger_unlimited commands to accept literal "unlimited". It also installs a completer. Presently, we complete on symbols by default, and at <http://sourceware.org/ml/gdb-patches/2013-03/msg00864.html> I've shown a WIP prototype that tried to keep that half working in these commands. In the end, it turned out to be more complicated than justifiable, IMO. It's super rare to want to pass the value of a variable/symbol in the program to a GDB set/show knob. That'll still work, it's just that we won't assist with completion anymore. This patch just sticks with the simple, and completes on "unlimited", and nothing else. This simplification means that "set he<tab><tab>" is all it takes to get to: "set height unlimited" The patch then goes through all integer/uinteger/zuinteger_unlimited commands in the tree, and updates both the online help and the manual to mention that "unlimited" is accepted in addition to 0/-1. In the cases where the command had no online help text at all, this adds it. I've tried to make the texts read in a way that "unlimited" is suggested before "0" or "-1" is. Tested on x86_64 Fedora 17. gdb/ 2013-04-10 Pedro Alves <palves@redhat.com> * cli/cli-decode.c (integer_unlimited_completer): New function. (add_setshow_integer_cmd, add_setshow_uinteger_cmd) (add_setshow_zuinteger_unlimited_cmd): Install the "unlimited" completer. * cli/cli-setshow.c: Include "cli/cli-utils.h". (is_unlimited_literal): New function. (do_set_command): Handle literal "unlimited" arguments. * frame.c (_initialize_frame) <set backtrace limit>: Document "unlimited". * printcmd.c (_initialize_printcmd) <set print max-symbolic-offset>: Add help text. * record-full.c (_initialize_record_full) <set record full insn-number-max>: Likewise. * record.c (_initialize_record) <set record instruction-history-size, set record function-call-history-size>: Add help text. * ser-tcp.c (_initialize_ser_tcp) <set tcp connect-timeout>: Add help text. * tracepoint.c (_initialize_tracepoint) <set trace-buffer-size>: Likewise. * source.c (_initialize_source) <set listsize>: Add help text. * utils.c (initialize_utils) <set height, set width>: Likewise. <set pagination>: Mention "set height unlimited". * valprint.c (_initialize_valprint) <set print elements, set print repeats>: Document "unlimited". gdb/doc/ 2013-04-10 Pedro Alves <palves@redhat.com> * gdb.texinfo (Process Record and Replay): Document that "set record full insn-number-max", "set record instruction-history-size" and "set record function-call-history-size" accept "unlimited". (Backtrace): Document that "set backtrace limit" accepts "unlimited". (List): Document that "set listsize" accepts "unlimited". (Print Settings)" Document that "set print max-symbolic-offset", "set print elements" and "set print repeats" accept "unlimited". (Starting and Stopping Trace Experiments): Document that "set trace-buffer-size" accepts "unlimited". (Remote Configuration): Document that "set tcp connect-timeout" accepts "unlimited". (Command History): Document that "set history size" accepts "unlimited". (Screen Size): Document that "set height" and "set width" accepts "unlimited". Adjust "set pagination"'s description to suggest "set height unlimited" instead of "set height 0". gdb/testsuite/ 2013-04-10 Pedro Alves <palves@redhat.com> * gdb.base/completion.exp: Test "set height", "set listsize" and "set trace-buffer-size" completion. * gdb.base/setshow.exp: Test "set height unlimited". * gdb.trace/trace-buffer-size.exp: Test "set trace-buffer-size unlimited".
2013-04-10 17:11:12 +02:00
Set timeout limit in seconds for socket connection"), _("\
Show timeout limit in seconds for socket connection"), _("\
If set to \"unlimited\", GDB will keep attempting to establish a\n\
connection forever, unless interrupted with Ctrl-c.\n\
The default is 15 seconds."),
NULL, NULL,
&tcp_set_cmdlist, &tcp_show_cmdlist);
}