Fix gdbserver build failure on targets without fork
This commit fixes nat/linux-namespaces.c to build correctly on targets without fork. gdb/ChangeLog: * nat/linux-namespaces.c (do_fork): New function. (linux_mntns_get_helper): Use the above. gdb/gdbserver/ChangeLog: * configure.ac (AC_FUNC_FORK): New check. * config.in: Regenerate. * configure: Likewise.
This commit is contained in:
parent
760f6ee894
commit
eb0edac83f
6 changed files with 326 additions and 55 deletions
|
@ -1,3 +1,8 @@
|
|||
2016-01-18 Gary Benson <gbenson@redhat.com>
|
||||
|
||||
* nat/linux-namespaces.c (do_fork): New function.
|
||||
(linux_mntns_get_helper): Use the above.
|
||||
|
||||
2016-01-17 Jonas Hahnfeld <Hahnfeld@itc.rwth-aachen.de> (tiny change)
|
||||
|
||||
Pushed by Joel Brobecker <brobecker@adacore.com>.
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2016-01-18 Gary Benson <gbenson@redhat.com>
|
||||
|
||||
* configure.ac (AC_FUNC_FORK): New check.
|
||||
* config.in: Regenerate.
|
||||
* configure: Likewise.
|
||||
|
||||
2016-01-14 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* linux-aarch32-low.c (thumb2_breakpoint): Make it static.
|
||||
|
|
|
@ -99,6 +99,9 @@
|
|||
/* Define to 1 if you have the `fdwalk' function. */
|
||||
#undef HAVE_FDWALK
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#undef HAVE_FORK
|
||||
|
||||
/* Define to 1 if you have the `getauxval' function. */
|
||||
#undef HAVE_GETAUXVAL
|
||||
|
||||
|
@ -286,9 +289,21 @@
|
|||
/* Define if UST is available */
|
||||
#undef HAVE_UST
|
||||
|
||||
/* Define to 1 if you have the `vfork' function. */
|
||||
#undef HAVE_VFORK
|
||||
|
||||
/* Define to 1 if you have the <vfork.h> header file. */
|
||||
#undef HAVE_VFORK_H
|
||||
|
||||
/* Define to 1 if you have the <wait.h> header file. */
|
||||
#undef HAVE_WAIT_H
|
||||
|
||||
/* Define to 1 if `fork' works. */
|
||||
#undef HAVE_WORKING_FORK
|
||||
|
||||
/* Define to 1 if `vfork' works. */
|
||||
#undef HAVE_WORKING_VFORK
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
|
@ -393,3 +408,9 @@
|
|||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define as `fork' if `vfork' does not work. */
|
||||
#undef vfork
|
||||
|
|
333
gdb/gdbserver/configure
vendored
333
gdb/gdbserver/configure
vendored
|
@ -1772,6 +1772,60 @@ fi
|
|||
|
||||
} # ac_fn_c_try_link
|
||||
|
||||
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
|
||||
# -------------------------------------------
|
||||
# Tests whether TYPE exists after having included INCLUDES, setting cache
|
||||
# variable VAR accordingly.
|
||||
ac_fn_c_check_type ()
|
||||
{
|
||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
|
||||
$as_echo_n "checking for $2... " >&6; }
|
||||
if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
eval "$3=no"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (sizeof ($2))
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (sizeof (($2)))
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
|
||||
else
|
||||
eval "$3=yes"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
eval ac_res=\$$3
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
$as_echo "$ac_res" >&6; }
|
||||
eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
|
||||
|
||||
} # ac_fn_c_check_type
|
||||
|
||||
# ac_fn_c_check_func LINENO FUNC VAR
|
||||
# ----------------------------------
|
||||
# Tests whether FUNC exists, setting the cache variable VAR accordingly
|
||||
|
@ -1929,60 +1983,6 @@ $as_echo "$ac_res" >&6; }
|
|||
|
||||
} # ac_fn_cxx_check_decl
|
||||
|
||||
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
|
||||
# -------------------------------------------
|
||||
# Tests whether TYPE exists after having included INCLUDES, setting cache
|
||||
# variable VAR accordingly.
|
||||
ac_fn_c_check_type ()
|
||||
{
|
||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
|
||||
$as_echo_n "checking for $2... " >&6; }
|
||||
if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
eval "$3=no"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (sizeof ($2))
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (sizeof (($2)))
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
|
||||
else
|
||||
eval "$3=yes"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
eval ac_res=\$$3
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
$as_echo "$ac_res" >&6; }
|
||||
eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
|
||||
|
||||
} # ac_fn_c_check_type
|
||||
|
||||
# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
|
||||
# --------------------------------------------
|
||||
# Tries to find the compile-time value of EXPR in a program that includes
|
||||
|
@ -5360,6 +5360,231 @@ fi
|
|||
|
||||
done
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_pid_t" = x""yes; then :
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define pid_t int
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
for ac_header in vfork.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_vfork_h" = x""yes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_VFORK_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
for ac_func in fork vfork
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
eval as_val=\$$as_ac_var
|
||||
if test "x$as_val" = x""yes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
if test "x$ac_cv_func_fork" = xyes; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
|
||||
$as_echo_n "checking for working fork... " >&6; }
|
||||
if test "${ac_cv_func_fork_works+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test "$cross_compiling" = yes; then :
|
||||
ac_cv_func_fork_works=cross
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
/* By Ruediger Kuhlmann. */
|
||||
return fork () < 0;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_run "$LINENO"; then :
|
||||
ac_cv_func_fork_works=yes
|
||||
else
|
||||
ac_cv_func_fork_works=no
|
||||
fi
|
||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
|
||||
conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
fi
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
|
||||
$as_echo "$ac_cv_func_fork_works" >&6; }
|
||||
|
||||
else
|
||||
ac_cv_func_fork_works=$ac_cv_func_fork
|
||||
fi
|
||||
if test "x$ac_cv_func_fork_works" = xcross; then
|
||||
case $host in
|
||||
*-*-amigaos* | *-*-msdosdjgpp*)
|
||||
# Override, as these systems have only a dummy fork() stub
|
||||
ac_cv_func_fork_works=no
|
||||
;;
|
||||
*)
|
||||
ac_cv_func_fork_works=yes
|
||||
;;
|
||||
esac
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
|
||||
$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
|
||||
fi
|
||||
ac_cv_func_vfork_works=$ac_cv_func_vfork
|
||||
if test "x$ac_cv_func_vfork" = xyes; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
|
||||
$as_echo_n "checking for working vfork... " >&6; }
|
||||
if test "${ac_cv_func_vfork_works+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test "$cross_compiling" = yes; then :
|
||||
ac_cv_func_vfork_works=cross
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
/* Thanks to Paul Eggert for this test. */
|
||||
$ac_includes_default
|
||||
#include <sys/wait.h>
|
||||
#ifdef HAVE_VFORK_H
|
||||
# include <vfork.h>
|
||||
#endif
|
||||
/* On some sparc systems, changes by the child to local and incoming
|
||||
argument registers are propagated back to the parent. The compiler
|
||||
is told about this with #include <vfork.h>, but some compilers
|
||||
(e.g. gcc -O) don't grok <vfork.h>. Test for this by using a
|
||||
static variable whose address is put into a register that is
|
||||
clobbered by the vfork. */
|
||||
static void
|
||||
#ifdef __cplusplus
|
||||
sparc_address_test (int arg)
|
||||
# else
|
||||
sparc_address_test (arg) int arg;
|
||||
#endif
|
||||
{
|
||||
static pid_t child;
|
||||
if (!child) {
|
||||
child = vfork ();
|
||||
if (child < 0) {
|
||||
perror ("vfork");
|
||||
_exit(2);
|
||||
}
|
||||
if (!child) {
|
||||
arg = getpid();
|
||||
write(-1, "", 0);
|
||||
_exit (arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
pid_t parent = getpid ();
|
||||
pid_t child;
|
||||
|
||||
sparc_address_test (0);
|
||||
|
||||
child = vfork ();
|
||||
|
||||
if (child == 0) {
|
||||
/* Here is another test for sparc vfork register problems. This
|
||||
test uses lots of local variables, at least as many local
|
||||
variables as main has allocated so far including compiler
|
||||
temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
|
||||
4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
|
||||
reuse the register of parent for one of the local variables,
|
||||
since it will think that parent can't possibly be used any more
|
||||
in this routine. Assigning to the local variable will thus
|
||||
munge parent in the parent process. */
|
||||
pid_t
|
||||
p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
|
||||
p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
|
||||
/* Convince the compiler that p..p7 are live; otherwise, it might
|
||||
use the same hardware register for all 8 local variables. */
|
||||
if (p != p1 || p != p2 || p != p3 || p != p4
|
||||
|| p != p5 || p != p6 || p != p7)
|
||||
_exit(1);
|
||||
|
||||
/* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
|
||||
from child file descriptors. If the child closes a descriptor
|
||||
before it execs or exits, this munges the parent's descriptor
|
||||
as well. Test for this by closing stdout in the child. */
|
||||
_exit(close(fileno(stdout)) != 0);
|
||||
} else {
|
||||
int status;
|
||||
struct stat st;
|
||||
|
||||
while (wait(&status) != child)
|
||||
;
|
||||
return (
|
||||
/* Was there some problem with vforking? */
|
||||
child < 0
|
||||
|
||||
/* Did the child fail? (This shouldn't happen.) */
|
||||
|| status
|
||||
|
||||
/* Did the vfork/compiler bug occur? */
|
||||
|| parent != getpid()
|
||||
|
||||
/* Did the file descriptor bug occur? */
|
||||
|| fstat(fileno(stdout), &st) != 0
|
||||
);
|
||||
}
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_run "$LINENO"; then :
|
||||
ac_cv_func_vfork_works=yes
|
||||
else
|
||||
ac_cv_func_vfork_works=no
|
||||
fi
|
||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
|
||||
conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
fi
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
|
||||
$as_echo "$ac_cv_func_vfork_works" >&6; }
|
||||
|
||||
fi;
|
||||
if test "x$ac_cv_func_fork_works" = xcross; then
|
||||
ac_cv_func_vfork_works=$ac_cv_func_vfork
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
|
||||
$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
|
||||
fi
|
||||
|
||||
if test "x$ac_cv_func_vfork_works" = xyes; then
|
||||
|
||||
$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
|
||||
|
||||
else
|
||||
|
||||
$as_echo "#define vfork fork" >>confdefs.h
|
||||
|
||||
fi
|
||||
if test "x$ac_cv_func_fork_works" = xyes; then
|
||||
|
||||
$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
for ac_func in getauxval pread pwrite pread64 setns
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
|
|
|
@ -94,6 +94,7 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
|
|||
fcntl.h signal.h sys/file.h dnl
|
||||
sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
|
||||
netinet/tcp.h arpa/inet.h)
|
||||
AC_FUNC_FORK
|
||||
AC_CHECK_FUNCS(getauxval pread pwrite pread64 setns)
|
||||
|
||||
GDB_AC_COMMON
|
||||
|
|
|
@ -32,6 +32,19 @@
|
|||
/* See nat/linux-namespaces.h. */
|
||||
int debug_linux_namespaces;
|
||||
|
||||
/* Handle systems without fork. */
|
||||
|
||||
static inline pid_t
|
||||
do_fork (void)
|
||||
{
|
||||
#ifdef HAVE_FORK
|
||||
return fork ();
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Handle systems without setns. */
|
||||
|
||||
static inline int
|
||||
|
@ -644,7 +657,7 @@ linux_mntns_get_helper (void)
|
|||
if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, sv) < 0)
|
||||
return NULL;
|
||||
|
||||
h.pid = fork ();
|
||||
h.pid = do_fork ();
|
||||
if (h.pid < 0)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
|
|
Loading…
Reference in a new issue