mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 04:24:43 +00:00
Compare commits
14 Commits
efbd9add96
...
users/cbie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d13d16c4d8 | ||
|
|
52300df201 | ||
|
|
6ce6dd4b8c | ||
|
|
fee9737afc | ||
|
|
792581b91e | ||
|
|
cec2f67ef7 | ||
|
|
8c0fae46d6 | ||
|
|
0e0174f4d5 | ||
|
|
7e3ed550be | ||
|
|
64a0d2a239 | ||
|
|
236bb4b23d | ||
|
|
43a189f903 | ||
|
|
15c2f6395b | ||
|
|
536a122989 |
@@ -1,3 +1,90 @@
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* python/python.c (class gdbpy_gil): New.
|
||||
(struct gdbpy_event): Add constructor, destructor, operator().
|
||||
(gdbpy_post_event): Use run_on_main_thread.
|
||||
(gdbpy_initialize_events): Remove.
|
||||
(do_start_initialization): Update.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* NEWS: Add entry.
|
||||
* maint.c (_initialize_maint_cmds): Add "max-worker-threads" maint
|
||||
commands.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* minsyms.c (minimal_symbol_reader::install): Use
|
||||
parallel_for_each.
|
||||
* gdbsupport/parallel-for.h: New file.
|
||||
* gdbsupport/parallel-for.c: New file.
|
||||
* Makefile.in (HFILES_NO_SRCDIR): Add gdbsupport/parallel-for.h.
|
||||
(COMMON_SFILES): Add gdbsupport/parallel-for.c.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* event-top.h (thread_local_segv_handler): Declare.
|
||||
* event-top.c (thread_local_segv_handler): New global.
|
||||
(install_handle_sigsegv, handle_sigsegv): New functions.
|
||||
(async_init_signals): Install SIGSEGV handler.
|
||||
* cp-support.c (gdb_demangle_jmp_buf): Change type. Now
|
||||
thread-local.
|
||||
(report_failed_demangle): New function.
|
||||
(gdb_demangle): Make core_dump_allowed atomic. Remove signal
|
||||
handler-setting code, instead use segv_handler. Run warning code
|
||||
on main thread.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* unittests/main-thread-selftests.c: New file.
|
||||
* Makefile.in (SUBDIR_UNITTESTS_SRCS): Add
|
||||
main-thread-selftests.c.
|
||||
* ser-event.h (run_on_main_thread): Declare.
|
||||
* ser-event.c (runnable_event, runnables, runnable_mutex): New
|
||||
globals.
|
||||
(run_events, run_on_main_thread, _initialize_ser_event): New
|
||||
functions.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* symtab.c (demangled_mutex): New global.
|
||||
(symbol_set_names): Use a lock_guard.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* main.c (setup_alternate_signal_stack): Remove.
|
||||
(captured_main_1): Use gdb::alternate_signal_stack.
|
||||
* gdbsupport/alt-stack.h: New file.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* gdbsupport/common.m4 (GDB_AC_COMMON): Check for
|
||||
pthread_sigmask.
|
||||
* configure: Rebuild.
|
||||
* gdbsupport/block-signals.h: New file.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* acinclude.m4: Include ax_pthread.m4.
|
||||
* Makefile.in (PTHREAD_CFLAGS, PTHREAD_LIBS): New variables.
|
||||
(INTERNAL_CFLAGS_BASE): Use PTHREAD_CFLAGS.
|
||||
(CLIBS): Use PTHREAD_LIBS.
|
||||
(aclocal_m4_deps): Add ax_pthread.m4.
|
||||
* config.in, configure: Rebuild.
|
||||
* gdbsupport/common.m4 (GDB_AC_COMMON): Check for std::thread.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* symtab.h (struct minimal_symbol) <name_set>: New member.
|
||||
* minsyms.c (minimal_symbol_reader::record_full): Copy name.
|
||||
Don't call symbol_set_names.
|
||||
(minimal_symbol_reader::install): Call symbol_set_names.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* configure: Rebuild.
|
||||
* acinclude.m4: Use m4_include, not sinclude.
|
||||
|
||||
2019-09-30 Ali Tamur <tamur@google.com>
|
||||
|
||||
* dwarf2read.c (skip_one_die): Handle DW_FORM_strx forms.
|
||||
|
||||
@@ -203,6 +203,9 @@ WERROR_CFLAGS = @WERROR_CFLAGS@
|
||||
GDB_WARN_CFLAGS = $(WARN_CFLAGS)
|
||||
GDB_WERROR_CFLAGS = $(WERROR_CFLAGS)
|
||||
|
||||
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
|
||||
PTHREAD_LIBS = @PTHREAD_LIBS@
|
||||
|
||||
RDYNAMIC = @RDYNAMIC@
|
||||
|
||||
# Where is the INTL library? Typically in ../intl.
|
||||
@@ -423,6 +426,7 @@ SUBDIR_UNITTESTS_SRCS = \
|
||||
unittests/optional-selftests.c \
|
||||
unittests/parse-connection-spec-selftests.c \
|
||||
unittests/ptid-selftests.c \
|
||||
unittests/main-thread-selftests.c \
|
||||
unittests/mkdir-recursive-selftests.c \
|
||||
unittests/rsp-low-selftests.c \
|
||||
unittests/scoped_fd-selftests.c \
|
||||
@@ -569,7 +573,7 @@ INTERNAL_CFLAGS_BASE = \
|
||||
$(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) $(ZLIBINC) \
|
||||
$(BFD_CFLAGS) $(INCLUDE_CFLAGS) $(LIBDECNUMBER_CFLAGS) \
|
||||
$(INTL_CFLAGS) $(INCGNU) $(ENABLE_CFLAGS) $(INTERNAL_CPPFLAGS) \
|
||||
$(SRCHIGH_CFLAGS)
|
||||
$(SRCHIGH_CFLAGS) $(PTHREAD_CFLAGS)
|
||||
INTERNAL_WARN_CFLAGS = $(INTERNAL_CFLAGS_BASE) $(GDB_WARN_CFLAGS)
|
||||
INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS)
|
||||
|
||||
@@ -583,7 +587,7 @@ LDFLAGS = @LDFLAGS@
|
||||
# PROFILE_CFLAGS is _not_ included, however, because we use monstartup.
|
||||
INTERNAL_LDFLAGS = \
|
||||
$(CXXFLAGS) $(GLOBAL_CFLAGS) $(MH_LDFLAGS) \
|
||||
$(LDFLAGS) $(CONFIG_LDFLAGS)
|
||||
$(LDFLAGS) $(CONFIG_LDFLAGS) $(PTHREAD_CFLAGS)
|
||||
|
||||
# Libraries and corresponding dependencies for compiling gdb.
|
||||
# XM_CLIBS, defined in *config files, have host-dependent libs.
|
||||
@@ -593,7 +597,7 @@ CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(ZLIB) $(INTL) $(LIBIBERTY) $(LIBD
|
||||
@LIBS@ @GUILE_LIBS@ @PYTHON_LIBS@ \
|
||||
$(LIBEXPAT) $(LIBLZMA) $(LIBBABELTRACE) $(LIBIPT) \
|
||||
$(LIBIBERTY) $(WIN32LIBS) $(LIBGNU) $(LIBICONV) $(LIBMPFR) \
|
||||
$(SRCHIGH_LIBS)
|
||||
$(SRCHIGH_LIBS) $(PTHREAD_LIBS)
|
||||
CDEPS = $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE_DEPS) \
|
||||
$(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS) $(LIBGNU)
|
||||
|
||||
@@ -966,6 +970,7 @@ COMMON_SFILES = \
|
||||
gdbsupport/gdb_vecs.c \
|
||||
gdbsupport/netstuff.c \
|
||||
gdbsupport/new-op.c \
|
||||
gdbsupport/parallel-for.c \
|
||||
gdbsupport/pathstuff.c \
|
||||
gdbsupport/print-utils.c \
|
||||
gdbsupport/ptid.c \
|
||||
@@ -975,6 +980,7 @@ COMMON_SFILES = \
|
||||
gdbsupport/signals.c \
|
||||
gdbsupport/signals-state-save-restore.c \
|
||||
gdbsupport/tdesc.c \
|
||||
gdbsupport/thread_pool.c \
|
||||
gdbsupport/vec.c \
|
||||
gdbsupport/xml-utils.c \
|
||||
complaints.c \
|
||||
@@ -1465,6 +1471,7 @@ HFILES_NO_SRCDIR = \
|
||||
gdbsupport/common-inferior.h \
|
||||
gdbsupport/netstuff.h \
|
||||
gdbsupport/host-defs.h \
|
||||
gdbsupport/parallel-for.h \
|
||||
gdbsupport/pathstuff.h \
|
||||
gdbsupport/print-utils.h \
|
||||
gdbsupport/ptid.h \
|
||||
@@ -2054,7 +2061,8 @@ aclocal_m4_deps = \
|
||||
../config/depstand.m4 \
|
||||
../config/lcmessage.m4 \
|
||||
../config/codeset.m4 \
|
||||
../config/zlib.m4
|
||||
../config/zlib.m4 \
|
||||
../config/ax_pthread.m4
|
||||
|
||||
$(srcdir)/aclocal.m4: @MAINTAINER_MODE_TRUE@ $(aclocal_m4_deps)
|
||||
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||
|
||||
6
gdb/NEWS
6
gdb/NEWS
@@ -122,6 +122,12 @@ set style highlight background COLOR
|
||||
set style highlight intensity VALUE
|
||||
Control the styling of highlightings.
|
||||
|
||||
maint set max-worker-threads
|
||||
maint show max-worker-threads
|
||||
Control the maximum number of worker threads that can be used by GDB.
|
||||
The default is "unlimited". Currently worker threads are only used when
|
||||
demangling the names of linker symbols.
|
||||
|
||||
maint set test-settings KIND
|
||||
maint show test-settings KIND
|
||||
A set of commands used by the testsuite for exercising the settings
|
||||
|
||||
@@ -4,64 +4,64 @@ dnl major rewriting for Tcl 7.5 by Don Libes <libes@nist.gov>
|
||||
# Keep these includes in sync with the aclocal_m4_deps list in
|
||||
# Makefile.in.
|
||||
|
||||
sinclude(acx_configure_dir.m4)
|
||||
m4_include(acx_configure_dir.m4)
|
||||
|
||||
# This gets GDB_AC_TRANSFORM.
|
||||
sinclude(transform.m4)
|
||||
m4_include(transform.m4)
|
||||
|
||||
# This gets AM_GDB_WARNINGS.
|
||||
sinclude(warning.m4)
|
||||
m4_include(warning.m4)
|
||||
|
||||
# AM_GDB_UBSAN
|
||||
sinclude(sanitize.m4)
|
||||
m4_include(sanitize.m4)
|
||||
|
||||
# This gets GDB_AC_SELFTEST.
|
||||
sinclude(selftest.m4)
|
||||
m4_include(selftest.m4)
|
||||
|
||||
dnl gdb/configure.in uses BFD_NEED_DECLARATION, so get its definition.
|
||||
sinclude(../bfd/bfd.m4)
|
||||
m4_include(../bfd/bfd.m4)
|
||||
|
||||
dnl This gets the standard macros.
|
||||
sinclude(../config/acinclude.m4)
|
||||
m4_include(../config/acinclude.m4)
|
||||
|
||||
dnl This gets AC_PLUGINS, needed by ACX_LARGEFILE.
|
||||
sinclude(../config/plugins.m4)
|
||||
m4_include(../config/plugins.m4)
|
||||
|
||||
dnl For ACX_LARGEFILE.
|
||||
sinclude(../config/largefile.m4)
|
||||
m4_include(../config/largefile.m4)
|
||||
|
||||
dnl For AM_SET_LEADING_DOT.
|
||||
sinclude(../config/lead-dot.m4)
|
||||
m4_include(../config/lead-dot.m4)
|
||||
|
||||
dnl This gets autoconf bugfixes.
|
||||
sinclude(../config/override.m4)
|
||||
m4_include(../config/override.m4)
|
||||
|
||||
dnl For ZW_GNU_GETTEXT_SISTER_DIR.
|
||||
sinclude(../config/gettext-sister.m4)
|
||||
m4_include(../config/gettext-sister.m4)
|
||||
|
||||
dnl For AC_LIB_HAVE_LINKFLAGS.
|
||||
sinclude(../config/lib-ld.m4)
|
||||
sinclude(../config/lib-prefix.m4)
|
||||
sinclude(../config/lib-link.m4)
|
||||
m4_include(../config/lib-ld.m4)
|
||||
m4_include(../config/lib-prefix.m4)
|
||||
m4_include(../config/lib-link.m4)
|
||||
|
||||
dnl For ACX_PKGVERSION and ACX_BUGURL.
|
||||
sinclude(../config/acx.m4)
|
||||
m4_include(../config/acx.m4)
|
||||
|
||||
dnl for TCL definitions
|
||||
sinclude(../config/tcl.m4)
|
||||
m4_include(../config/tcl.m4)
|
||||
|
||||
dnl For dependency tracking macros.
|
||||
sinclude([../config/depstand.m4])
|
||||
m4_include([../config/depstand.m4])
|
||||
|
||||
dnl For AM_LC_MESSAGES
|
||||
sinclude([../config/lcmessage.m4])
|
||||
m4_include([../config/lcmessage.m4])
|
||||
|
||||
dnl For AM_LANGINFO_CODESET.
|
||||
sinclude([../config/codeset.m4])
|
||||
m4_include([../config/codeset.m4])
|
||||
|
||||
sinclude([../config/iconv.m4])
|
||||
m4_include([../config/iconv.m4])
|
||||
|
||||
sinclude([../config/zlib.m4])
|
||||
m4_include([../config/zlib.m4])
|
||||
|
||||
m4_include([gdbsupport/common.m4])
|
||||
|
||||
@@ -73,6 +73,8 @@ m4_include(ptrace.m4)
|
||||
|
||||
m4_include(ax_cxx_compile_stdcxx.m4)
|
||||
|
||||
m4_include([../config/ax_pthread.m4])
|
||||
|
||||
## ----------------------------------------- ##
|
||||
## ANSIfy the C compiler whenever possible. ##
|
||||
## From Franc,ois Pinard ##
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
*/
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define to 1 if std::thread works. */
|
||||
#undef CXX_STD_THREAD
|
||||
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
|
||||
849
gdb/configure
vendored
849
gdb/configure
vendored
@@ -697,6 +697,11 @@ SYSTEM_GDBINIT
|
||||
TARGET_SYSTEM_ROOT
|
||||
CONFIG_LDFLAGS
|
||||
RDYNAMIC
|
||||
PTHREAD_CFLAGS
|
||||
PTHREAD_LIBS
|
||||
PTHREAD_CC
|
||||
ax_pthread_config
|
||||
SED
|
||||
ALLOCA
|
||||
LTLIBIPT
|
||||
LIBIPT
|
||||
@@ -2501,6 +2506,73 @@ fi
|
||||
as_fn_set_status $ac_retval
|
||||
|
||||
} # ac_fn_cxx_try_link
|
||||
|
||||
# ac_fn_cxx_check_func LINENO FUNC VAR
|
||||
# ------------------------------------
|
||||
# Tests whether FUNC exists, setting the cache variable VAR accordingly
|
||||
ac_fn_cxx_check_func ()
|
||||
{
|
||||
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 eval \${$3+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define $2 innocuous_$2
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $2 (); below.
|
||||
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
<limits.h> exists even on freestanding compilers. */
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
#else
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef $2
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char $2 ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_$2 || defined __stub___$2
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return $2 ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_link "$LINENO"; then :
|
||||
eval "$3=yes"
|
||||
else
|
||||
eval "$3=no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext 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; ${as_lineno_stack:+:} unset as_lineno
|
||||
|
||||
} # ac_fn_cxx_check_func
|
||||
cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
@@ -13180,6 +13252,75 @@ _ACEOF
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
|
||||
$as_echo_n "checking for a sed that does not truncate output... " >&6; }
|
||||
if ${ac_cv_path_SED+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
|
||||
for ac_i in 1 2 3 4 5 6 7; do
|
||||
ac_script="$ac_script$as_nl$ac_script"
|
||||
done
|
||||
echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
|
||||
{ ac_script=; unset ac_script;}
|
||||
if test -z "$SED"; then
|
||||
ac_path_SED_found=false
|
||||
# Loop through the user's path and test for each of PROGNAME-LIST
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_prog in sed gsed; do
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
|
||||
as_fn_executable_p "$ac_path_SED" || continue
|
||||
# Check for GNU ac_path_SED and select it if it is found.
|
||||
# Check for GNU $ac_path_SED
|
||||
case `"$ac_path_SED" --version 2>&1` in
|
||||
*GNU*)
|
||||
ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
|
||||
*)
|
||||
ac_count=0
|
||||
$as_echo_n 0123456789 >"conftest.in"
|
||||
while :
|
||||
do
|
||||
cat "conftest.in" "conftest.in" >"conftest.tmp"
|
||||
mv "conftest.tmp" "conftest.in"
|
||||
cp "conftest.in" "conftest.nl"
|
||||
$as_echo '' >> "conftest.nl"
|
||||
"$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
|
||||
diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
|
||||
as_fn_arith $ac_count + 1 && ac_count=$as_val
|
||||
if test $ac_count -gt ${ac_path_SED_max-0}; then
|
||||
# Best one so far, save it but keep looking for a better one
|
||||
ac_cv_path_SED="$ac_path_SED"
|
||||
ac_path_SED_max=$ac_count
|
||||
fi
|
||||
# 10*(2^10) chars as input seems more than enough
|
||||
test $ac_count -gt 10 && break
|
||||
done
|
||||
rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
|
||||
esac
|
||||
|
||||
$ac_path_SED_found && break 3
|
||||
done
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
if test -z "$ac_cv_path_SED"; then
|
||||
as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
|
||||
fi
|
||||
else
|
||||
ac_cv_path_SED=$SED
|
||||
fi
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
|
||||
$as_echo "$ac_cv_path_SED" >&6; }
|
||||
SED="$ac_cv_path_SED"
|
||||
rm -f conftest.sed
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
|
||||
$as_echo_n "checking for ANSI C header files... " >&6; }
|
||||
@@ -13564,6 +13705,714 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
# Check for std::thread. This does not work on some platforms, like
|
||||
# mingw and DJGPP.
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
ax_pthread_ok=no
|
||||
|
||||
# We used to check for pthread.h first, but this fails if pthread.h
|
||||
# requires special compiler flags (e.g. on Tru64 or Sequent).
|
||||
# It gets checked for in the link test anyway.
|
||||
|
||||
# First of all, check if the user has set any of the PTHREAD_LIBS,
|
||||
# etcetera environment variables, and if threads linking works using
|
||||
# them:
|
||||
if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
|
||||
ax_pthread_save_CC="$CC"
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
ax_pthread_save_LIBS="$LIBS"
|
||||
if test "x$PTHREAD_CC" != "x"; then :
|
||||
CC="$PTHREAD_CC"
|
||||
fi
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5
|
||||
$as_echo_n "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char pthread_join ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return pthread_join ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ax_pthread_ok=yes
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
|
||||
$as_echo "$ax_pthread_ok" >&6; }
|
||||
if test "x$ax_pthread_ok" = "xno"; then
|
||||
PTHREAD_LIBS=""
|
||||
PTHREAD_CFLAGS=""
|
||||
fi
|
||||
CC="$ax_pthread_save_CC"
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
LIBS="$ax_pthread_save_LIBS"
|
||||
fi
|
||||
|
||||
# We must check for the threads library under a number of different
|
||||
# names; the ordering is very important because some systems
|
||||
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
|
||||
# libraries is broken (non-POSIX).
|
||||
|
||||
# Create a list of thread flags to try. Items starting with a "-" are
|
||||
# C compiler flags, and other items are library names, except for "none"
|
||||
# which indicates that we try without any flags at all, and "pthread-config"
|
||||
# which is a program returning the flags for the Pth emulation library.
|
||||
|
||||
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
|
||||
|
||||
# The ordering *is* (sometimes) important. Some notes on the
|
||||
# individual items follow:
|
||||
|
||||
# pthreads: AIX (must check this before -lpthread)
|
||||
# none: in case threads are in libc; should be tried before -Kthread and
|
||||
# other compiler flags to prevent continual compiler warnings
|
||||
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
|
||||
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
|
||||
# (Note: HP C rejects this with "bad form for `-t' option")
|
||||
# -pthreads: Solaris/gcc (Note: HP C also rejects)
|
||||
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
|
||||
# doesn't hurt to check since this sometimes defines pthreads and
|
||||
# -D_REENTRANT too), HP C (must be checked before -lpthread, which
|
||||
# is present but should not be used directly; and before -mthreads,
|
||||
# because the compiler interprets this as "-mt" + "-hreads")
|
||||
# -mthreads: Mingw32/gcc, Lynx/gcc
|
||||
# pthread: Linux, etcetera
|
||||
# --thread-safe: KAI C++
|
||||
# pthread-config: use pthread-config program (for GNU Pth library)
|
||||
|
||||
case $host_os in
|
||||
|
||||
freebsd*)
|
||||
|
||||
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
|
||||
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
|
||||
|
||||
ax_pthread_flags="-kthread lthread $ax_pthread_flags"
|
||||
;;
|
||||
|
||||
hpux*)
|
||||
|
||||
# From the cc(1) man page: "[-mt] Sets various -D flags to enable
|
||||
# multi-threading and also sets -lpthread."
|
||||
|
||||
ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
|
||||
;;
|
||||
|
||||
openedition*)
|
||||
|
||||
# IBM z/OS requires a feature-test macro to be defined in order to
|
||||
# enable POSIX threads at all, so give the user a hint if this is
|
||||
# not set. (We don't define these ourselves, as they can affect
|
||||
# other portions of the system API in unpredictable ways.)
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
|
||||
AX_PTHREAD_ZOS_MISSING
|
||||
# endif
|
||||
|
||||
_ACEOF
|
||||
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
||||
$EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5
|
||||
$as_echo "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;}
|
||||
fi
|
||||
rm -f conftest*
|
||||
|
||||
;;
|
||||
|
||||
solaris*)
|
||||
|
||||
# On Solaris (at least, for some versions), libc contains stubbed
|
||||
# (non-functional) versions of the pthreads routines, so link-based
|
||||
# tests will erroneously succeed. (N.B.: The stubs are missing
|
||||
# pthread_cleanup_push, or rather a function called by this macro,
|
||||
# so we could check for that, but who knows whether they'll stub
|
||||
# that too in a future libc.) So we'll check first for the
|
||||
# standard Solaris way of linking pthreads (-mt -lpthread).
|
||||
|
||||
ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
|
||||
;;
|
||||
esac
|
||||
|
||||
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
|
||||
|
||||
if test "x$GCC" = "xyes"; then :
|
||||
ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"
|
||||
fi
|
||||
|
||||
# The presence of a feature test macro requesting re-entrant function
|
||||
# definitions is, on some systems, a strong hint that pthreads support is
|
||||
# correctly enabled
|
||||
|
||||
case $host_os in
|
||||
darwin* | hpux* | linux* | osf* | solaris*)
|
||||
ax_pthread_check_macro="_REENTRANT"
|
||||
;;
|
||||
|
||||
aix*)
|
||||
ax_pthread_check_macro="_THREAD_SAFE"
|
||||
;;
|
||||
|
||||
*)
|
||||
ax_pthread_check_macro="--"
|
||||
;;
|
||||
esac
|
||||
if test "x$ax_pthread_check_macro" = "x--"; then :
|
||||
ax_pthread_check_cond=0
|
||||
else
|
||||
ax_pthread_check_cond="!defined($ax_pthread_check_macro)"
|
||||
fi
|
||||
|
||||
# Are we compiling with Clang?
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5
|
||||
$as_echo_n "checking whether $CC is Clang... " >&6; }
|
||||
if ${ax_cv_PTHREAD_CLANG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ax_cv_PTHREAD_CLANG=no
|
||||
# Note that Autoconf sets GCC=yes for Clang as well as GCC
|
||||
if test "x$GCC" = "xyes"; then
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
|
||||
# if defined(__clang__) && defined(__llvm__)
|
||||
AX_PTHREAD_CC_IS_CLANG
|
||||
# endif
|
||||
|
||||
_ACEOF
|
||||
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
||||
$EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1; then :
|
||||
ax_cv_PTHREAD_CLANG=yes
|
||||
fi
|
||||
rm -f conftest*
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5
|
||||
$as_echo "$ax_cv_PTHREAD_CLANG" >&6; }
|
||||
ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
|
||||
|
||||
ax_pthread_clang_warning=no
|
||||
|
||||
# Clang needs special handling, because older versions handle the -pthread
|
||||
# option in a rather... idiosyncratic way
|
||||
|
||||
if test "x$ax_pthread_clang" = "xyes"; then
|
||||
|
||||
# Clang takes -pthread; it has never supported any other flag
|
||||
|
||||
# (Note 1: This will need to be revisited if a system that Clang
|
||||
# supports has POSIX threads in a separate library. This tends not
|
||||
# to be the way of modern systems, but it's conceivable.)
|
||||
|
||||
# (Note 2: On some systems, notably Darwin, -pthread is not needed
|
||||
# to get POSIX threads support; the API is always present and
|
||||
# active. We could reasonably leave PTHREAD_CFLAGS empty. But
|
||||
# -pthread does define _REENTRANT, and while the Darwin headers
|
||||
# ignore this macro, third-party headers might not.)
|
||||
|
||||
PTHREAD_CFLAGS="-pthread"
|
||||
PTHREAD_LIBS=
|
||||
|
||||
ax_pthread_ok=yes
|
||||
|
||||
# However, older versions of Clang make a point of warning the user
|
||||
# that, in an invocation where only linking and no compilation is
|
||||
# taking place, the -pthread option has no effect ("argument unused
|
||||
# during compilation"). They expect -pthread to be passed in only
|
||||
# when source code is being compiled.
|
||||
#
|
||||
# Problem is, this is at odds with the way Automake and most other
|
||||
# C build frameworks function, which is that the same flags used in
|
||||
# compilation (CFLAGS) are also used in linking. Many systems
|
||||
# supported by AX_PTHREAD require exactly this for POSIX threads
|
||||
# support, and in fact it is often not straightforward to specify a
|
||||
# flag that is used only in the compilation phase and not in
|
||||
# linking. Such a scenario is extremely rare in practice.
|
||||
#
|
||||
# Even though use of the -pthread flag in linking would only print
|
||||
# a warning, this can be a nuisance for well-run software projects
|
||||
# that build with -Werror. So if the active version of Clang has
|
||||
# this misfeature, we search for an option to squash it.
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5
|
||||
$as_echo_n "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; }
|
||||
if ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
|
||||
# Create an alternate version of $ac_link that compiles and
|
||||
# links in two steps (.c -> .o, .o -> exe) instead of one
|
||||
# (.c -> exe), because the warning occurs only in the second
|
||||
# step
|
||||
ax_pthread_save_ac_link="$ac_link"
|
||||
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
|
||||
ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
|
||||
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
|
||||
if test "x$ax_pthread_try" = "xunknown"; then :
|
||||
break
|
||||
fi
|
||||
CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
|
||||
ac_link="$ax_pthread_save_ac_link"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
int main(void){return 0;}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_link="$ax_pthread_2step_ac_link"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
int main(void){return 0;}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
done
|
||||
ac_link="$ax_pthread_save_ac_link"
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
if test "x$ax_pthread_try" = "x"; then :
|
||||
ax_pthread_try=no
|
||||
fi
|
||||
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5
|
||||
$as_echo "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; }
|
||||
|
||||
case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
|
||||
no | unknown) ;;
|
||||
*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
|
||||
esac
|
||||
|
||||
fi # $ax_pthread_clang = yes
|
||||
|
||||
if test "x$ax_pthread_ok" = "xno"; then
|
||||
for ax_pthread_try_flag in $ax_pthread_flags; do
|
||||
|
||||
case $ax_pthread_try_flag in
|
||||
none)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
|
||||
$as_echo_n "checking whether pthreads work without any flags... " >&6; }
|
||||
;;
|
||||
|
||||
-mt,pthread)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with -mt -lpthread" >&5
|
||||
$as_echo_n "checking whether pthreads work with -mt -lpthread... " >&6; }
|
||||
PTHREAD_CFLAGS="-mt"
|
||||
PTHREAD_LIBS="-lpthread"
|
||||
;;
|
||||
|
||||
-*)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5
|
||||
$as_echo_n "checking whether pthreads work with $ax_pthread_try_flag... " >&6; }
|
||||
PTHREAD_CFLAGS="$ax_pthread_try_flag"
|
||||
;;
|
||||
|
||||
pthread-config)
|
||||
# Extract the first word of "pthread-config", so it can be a program name with args.
|
||||
set dummy pthread-config; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_prog_ax_pthread_config+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test -n "$ax_pthread_config"; then
|
||||
ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_ax_pthread_config="yes"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no"
|
||||
fi
|
||||
fi
|
||||
ax_pthread_config=$ac_cv_prog_ax_pthread_config
|
||||
if test -n "$ax_pthread_config"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5
|
||||
$as_echo "$ax_pthread_config" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test "x$ax_pthread_config" = "xno"; then :
|
||||
continue
|
||||
fi
|
||||
PTHREAD_CFLAGS="`pthread-config --cflags`"
|
||||
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
|
||||
;;
|
||||
|
||||
*)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5
|
||||
$as_echo_n "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; }
|
||||
PTHREAD_LIBS="-l$ax_pthread_try_flag"
|
||||
;;
|
||||
esac
|
||||
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
ax_pthread_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
|
||||
# Check for various functions. We must include pthread.h,
|
||||
# since some functions may be macros. (On the Sequent, we
|
||||
# need a special flag -Kthread to make this header compile.)
|
||||
# We check for pthread_join because it is in -lpthread on IRIX
|
||||
# while pthread_create is in libc. We check for pthread_attr_init
|
||||
# due to DEC craziness with -lpthreads. We check for
|
||||
# pthread_cleanup_push because it is one of the few pthread
|
||||
# functions on Solaris that doesn't have a non-functional libc stub.
|
||||
# We try pthread_create on general principles.
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <pthread.h>
|
||||
# if $ax_pthread_check_cond
|
||||
# error "$ax_pthread_check_macro must be defined"
|
||||
# endif
|
||||
static void routine(void *a) { a = 0; }
|
||||
static void *start_routine(void *a) { return a; }
|
||||
int
|
||||
main ()
|
||||
{
|
||||
pthread_t th; pthread_attr_t attr;
|
||||
pthread_create(&th, 0, start_routine, 0);
|
||||
pthread_join(th, 0);
|
||||
pthread_attr_init(&attr);
|
||||
pthread_cleanup_push(routine, 0);
|
||||
pthread_cleanup_pop(0) /* ; */
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ax_pthread_ok=yes
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
LIBS="$ax_pthread_save_LIBS"
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
|
||||
$as_echo "$ax_pthread_ok" >&6; }
|
||||
if test "x$ax_pthread_ok" = "xyes"; then :
|
||||
break
|
||||
fi
|
||||
|
||||
PTHREAD_LIBS=""
|
||||
PTHREAD_CFLAGS=""
|
||||
done
|
||||
fi
|
||||
|
||||
# Various other checks:
|
||||
if test "x$ax_pthread_ok" = "xyes"; then
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
ax_pthread_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
|
||||
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
|
||||
$as_echo_n "checking for joinable pthread attribute... " >&6; }
|
||||
if ${ax_cv_PTHREAD_JOINABLE_ATTR+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ax_cv_PTHREAD_JOINABLE_ATTR=unknown
|
||||
for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <pthread.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int attr = $ax_pthread_attr; return attr /* ; */
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
done
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5
|
||||
$as_echo "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; }
|
||||
if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
|
||||
test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
|
||||
test "x$ax_pthread_joinable_attr_defined" != "xyes"; then :
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR
|
||||
_ACEOF
|
||||
|
||||
ax_pthread_joinable_attr_defined=yes
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5
|
||||
$as_echo_n "checking whether more special flags are required for pthreads... " >&6; }
|
||||
if ${ax_cv_PTHREAD_SPECIAL_FLAGS+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ax_cv_PTHREAD_SPECIAL_FLAGS=no
|
||||
case $host_os in
|
||||
solaris*)
|
||||
ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5
|
||||
$as_echo "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; }
|
||||
if test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
|
||||
test "x$ax_pthread_special_flags_added" != "xyes"; then :
|
||||
PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
|
||||
ax_pthread_special_flags_added=yes
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5
|
||||
$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; }
|
||||
if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <pthread.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int i = PTHREAD_PRIO_INHERIT;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ax_cv_PTHREAD_PRIO_INHERIT=yes
|
||||
else
|
||||
ax_cv_PTHREAD_PRIO_INHERIT=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5
|
||||
$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; }
|
||||
if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
|
||||
test "x$ax_pthread_prio_inherit_defined" != "xyes"; then :
|
||||
|
||||
$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h
|
||||
|
||||
ax_pthread_prio_inherit_defined=yes
|
||||
|
||||
fi
|
||||
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
LIBS="$ax_pthread_save_LIBS"
|
||||
|
||||
# More AIX lossage: compile with *_r variant
|
||||
if test "x$GCC" != "xyes"; then
|
||||
case $host_os in
|
||||
aix*)
|
||||
case "x/$CC" in #(
|
||||
x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) :
|
||||
#handle absolute path differently from PATH based program lookup
|
||||
case "x$CC" in #(
|
||||
x/*) :
|
||||
if as_fn_executable_p ${CC}_r; then :
|
||||
PTHREAD_CC="${CC}_r"
|
||||
fi ;; #(
|
||||
*) :
|
||||
for ac_prog in ${CC}_r
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_prog_PTHREAD_CC+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test -n "$PTHREAD_CC"; then
|
||||
ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_PTHREAD_CC="$ac_prog"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
fi
|
||||
fi
|
||||
PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
|
||||
if test -n "$PTHREAD_CC"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
|
||||
$as_echo "$PTHREAD_CC" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
test -n "$PTHREAD_CC" && break
|
||||
done
|
||||
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
|
||||
;;
|
||||
esac ;; #(
|
||||
*) :
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
|
||||
if test "x$ax_pthread_ok" = "xyes"; then
|
||||
threads=yes
|
||||
:
|
||||
else
|
||||
ax_pthread_ok=no
|
||||
threads=no
|
||||
fi
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
|
||||
if test "$threads" = "yes"; then
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$PTHREAD_CFLAGS $save_CFLAGS"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::thread" >&5
|
||||
$as_echo_n "checking for std::thread... " >&6; }
|
||||
if ${gdb_cv_cxx_std_thread+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <thread>
|
||||
void callback() { }
|
||||
int
|
||||
main ()
|
||||
{
|
||||
std::thread t(callback);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_compile "$LINENO"; then :
|
||||
gdb_cv_cxx_std_thread=yes
|
||||
else
|
||||
gdb_cv_cxx_std_thread=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_cxx_std_thread" >&5
|
||||
$as_echo "$gdb_cv_cxx_std_thread" >&6; }
|
||||
|
||||
# This check must be here, while LIBS includes any necessary
|
||||
# threading library.
|
||||
for ac_func in pthread_sigmask
|
||||
do :
|
||||
ac_fn_cxx_check_func "$LINENO" "pthread_sigmask" "ac_cv_func_pthread_sigmask"
|
||||
if test "x$ac_cv_func_pthread_sigmask" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_PTHREAD_SIGMASK 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
CXXFLAGS="$save_CXXFLAGS"
|
||||
fi
|
||||
if test $gdb_cv_cxx_std_thread = yes; then
|
||||
|
||||
$as_echo "#define CXX_STD_THREAD 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigsetjmp" >&5
|
||||
$as_echo_n "checking for sigsetjmp... " >&6; }
|
||||
if ${gdb_cv_func_sigsetjmp+:} false; then :
|
||||
|
||||
139
gdb/cp-support.c
139
gdb/cp-support.c
@@ -37,6 +37,9 @@
|
||||
#include "gdbsupport/gdb_setjmp.h"
|
||||
#include "safe-ctype.h"
|
||||
#include "gdbsupport/selftest.h"
|
||||
#include <atomic>
|
||||
#include "event-top.h"
|
||||
#include "ser-event.h"
|
||||
|
||||
#define d_left(dc) (dc)->u.s_binary.left
|
||||
#define d_right(dc) (dc)->u.s_binary.right
|
||||
@@ -1476,11 +1479,11 @@ static bool catch_demangler_crashes = true;
|
||||
|
||||
/* Stack context and environment for demangler crash recovery. */
|
||||
|
||||
static SIGJMP_BUF gdb_demangle_jmp_buf;
|
||||
static thread_local SIGJMP_BUF *gdb_demangle_jmp_buf;
|
||||
|
||||
/* If nonzero, attempt to dump core from the signal handler. */
|
||||
|
||||
static int gdb_demangle_attempt_core_dump = 1;
|
||||
static std::atomic<bool> gdb_demangle_attempt_core_dump;
|
||||
|
||||
/* Signal handler for gdb_demangle. */
|
||||
|
||||
@@ -1492,10 +1495,46 @@ gdb_demangle_signal_handler (int signo)
|
||||
if (fork () == 0)
|
||||
dump_core ();
|
||||
|
||||
gdb_demangle_attempt_core_dump = 0;
|
||||
gdb_demangle_attempt_core_dump = false;
|
||||
}
|
||||
|
||||
SIGLONGJMP (gdb_demangle_jmp_buf, signo);
|
||||
SIGLONGJMP (*gdb_demangle_jmp_buf, signo);
|
||||
}
|
||||
|
||||
/* A helper for gdb_demangle that reports a demangling failure. */
|
||||
|
||||
static void
|
||||
report_failed_demangle (const char *name, bool core_dump_allowed,
|
||||
int crash_signal)
|
||||
{
|
||||
static bool error_reported = false;
|
||||
|
||||
if (!error_reported)
|
||||
{
|
||||
std::string short_msg
|
||||
= string_printf (_("unable to demangle '%s' "
|
||||
"(demangler failed with signal %d)"),
|
||||
name, crash_signal);
|
||||
|
||||
std::string long_msg
|
||||
= string_printf ("%s:%d: %s: %s", __FILE__, __LINE__,
|
||||
"demangler-warning", short_msg.c_str ());
|
||||
|
||||
target_terminal::scoped_restore_terminal_state term_state;
|
||||
target_terminal::ours_for_output ();
|
||||
|
||||
begin_line ();
|
||||
if (core_dump_allowed)
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
_("%s\nAttempting to dump core.\n"),
|
||||
long_msg.c_str ());
|
||||
else
|
||||
warn_cant_dump_core (long_msg.c_str ());
|
||||
|
||||
demangler_warning (__FILE__, __LINE__, "%s", short_msg.c_str ());
|
||||
|
||||
error_reported = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1509,38 +1548,18 @@ gdb_demangle (const char *name, int options)
|
||||
int crash_signal = 0;
|
||||
|
||||
#ifdef HAVE_WORKING_FORK
|
||||
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
|
||||
struct sigaction sa, old_sa;
|
||||
#else
|
||||
sighandler_t ofunc;
|
||||
#endif
|
||||
static int core_dump_allowed = -1;
|
||||
|
||||
if (core_dump_allowed == -1)
|
||||
{
|
||||
core_dump_allowed = can_dump_core (LIMIT_CUR);
|
||||
|
||||
if (!core_dump_allowed)
|
||||
gdb_demangle_attempt_core_dump = 0;
|
||||
}
|
||||
scoped_restore restore_segv
|
||||
= make_scoped_restore (&thread_local_segv_handler,
|
||||
catch_demangler_crashes
|
||||
? gdb_demangle_signal_handler
|
||||
: nullptr);
|
||||
|
||||
bool core_dump_allowed = gdb_demangle_attempt_core_dump;
|
||||
SIGJMP_BUF jmp_buf;
|
||||
scoped_restore restore_jmp_buf
|
||||
= make_scoped_restore (&gdb_demangle_jmp_buf, &jmp_buf);
|
||||
if (catch_demangler_crashes)
|
||||
{
|
||||
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
|
||||
sa.sa_handler = gdb_demangle_signal_handler;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
#ifdef HAVE_SIGALTSTACK
|
||||
sa.sa_flags = SA_ONSTACK;
|
||||
#else
|
||||
sa.sa_flags = 0;
|
||||
#endif
|
||||
sigaction (SIGSEGV, &sa, &old_sa);
|
||||
#else
|
||||
ofunc = signal (SIGSEGV, gdb_demangle_signal_handler);
|
||||
#endif
|
||||
|
||||
crash_signal = SIGSETJMP (gdb_demangle_jmp_buf);
|
||||
}
|
||||
crash_signal = SIGSETJMP (jmp_buf);
|
||||
#endif
|
||||
|
||||
if (crash_signal == 0)
|
||||
@@ -1549,45 +1568,20 @@ gdb_demangle (const char *name, int options)
|
||||
#ifdef HAVE_WORKING_FORK
|
||||
if (catch_demangler_crashes)
|
||||
{
|
||||
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
|
||||
sigaction (SIGSEGV, &old_sa, NULL);
|
||||
#else
|
||||
signal (SIGSEGV, ofunc);
|
||||
#endif
|
||||
|
||||
if (crash_signal != 0)
|
||||
{
|
||||
static int error_reported = 0;
|
||||
{
|
||||
/* If there was a failure, we can't report it here, because
|
||||
we might be in a background thread. Instead, arrange for
|
||||
the reporting to happen on the main thread. */
|
||||
std::string copy = name;
|
||||
run_on_main_thread ([=] ()
|
||||
{
|
||||
report_failed_demangle (copy.c_str (), core_dump_allowed,
|
||||
crash_signal);
|
||||
});
|
||||
|
||||
if (!error_reported)
|
||||
{
|
||||
std::string short_msg
|
||||
= string_printf (_("unable to demangle '%s' "
|
||||
"(demangler failed with signal %d)"),
|
||||
name, crash_signal);
|
||||
|
||||
std::string long_msg
|
||||
= string_printf ("%s:%d: %s: %s", __FILE__, __LINE__,
|
||||
"demangler-warning", short_msg.c_str ());
|
||||
|
||||
target_terminal::scoped_restore_terminal_state term_state;
|
||||
target_terminal::ours_for_output ();
|
||||
|
||||
begin_line ();
|
||||
if (core_dump_allowed)
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
_("%s\nAttempting to dump core.\n"),
|
||||
long_msg.c_str ());
|
||||
else
|
||||
warn_cant_dump_core (long_msg.c_str ());
|
||||
|
||||
demangler_warning (__FILE__, __LINE__, "%s", short_msg.c_str ());
|
||||
|
||||
error_reported = 1;
|
||||
}
|
||||
|
||||
result = NULL;
|
||||
}
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2194,4 +2188,7 @@ display the offending symbol."),
|
||||
selftests::register_test ("cp_remove_params",
|
||||
selftests::test_cp_remove_params);
|
||||
#endif
|
||||
|
||||
if (!can_dump_core (LIMIT_CUR))
|
||||
gdb_demangle_attempt_core_dump = false;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* gdb.texinfo (Maintenance Commands): Document new maint
|
||||
commands.
|
||||
|
||||
2019-09-20 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* doc/gdb.texinfo (Remote Configuration): Remove documentation for
|
||||
|
||||
@@ -37663,6 +37663,20 @@ with the DWARF frame unwinders enabled.
|
||||
|
||||
If DWARF frame unwinders are not supported for a particular target
|
||||
architecture, then enabling this flag does not cause them to be used.
|
||||
|
||||
@kindex maint set max-worker-threads
|
||||
@kindex maint show max-worker-threads
|
||||
@item maint set max-worker-threads
|
||||
@item maint show max-worker-threads
|
||||
Control the number of worker threads that may be used by @value{GDBN}.
|
||||
On capable hosts, @value{GDBN} may use multiple threads to speed up
|
||||
certain CPU-intensive operations, such as demangling symbol names.
|
||||
While the number of threads used by @value{GDBN} may vary, this
|
||||
command can be used to set an upper bound on this number. The default
|
||||
is @code{unlimited}. Note that this only controls worker threads
|
||||
started by @value{GDBN} itself; libraries used by @value{GDBN} may
|
||||
start threads of their own.
|
||||
|
||||
@kindex maint set profile
|
||||
@kindex maint show profile
|
||||
@cindex profiling GDB
|
||||
|
||||
@@ -847,6 +847,45 @@ gdb_readline_no_editing_callback (gdb_client_data client_data)
|
||||
}
|
||||
|
||||
|
||||
/* See event-top.h. */
|
||||
|
||||
thread_local void (*thread_local_segv_handler) (int);
|
||||
|
||||
static void handle_sigsegv (int sig);
|
||||
|
||||
/* Install the SIGSEGV handler. */
|
||||
static void
|
||||
install_handle_sigsegv ()
|
||||
{
|
||||
#if defined (HAVE_SIGACTION)
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = handle_sigsegv;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
#ifdef HAVE_SIGALTSTACK
|
||||
sa.sa_flags = SA_ONSTACK;
|
||||
#else
|
||||
sa.sa_flags = 0;
|
||||
#endif
|
||||
sigaction (SIGSEGV, &sa, nullptr);
|
||||
#else
|
||||
signal (SIGSEGV, handle_sigsegv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Handler for SIGSEGV. */
|
||||
|
||||
static void
|
||||
handle_sigsegv (int sig)
|
||||
{
|
||||
install_handle_sigsegv ();
|
||||
|
||||
if (thread_local_segv_handler == nullptr)
|
||||
abort ();
|
||||
thread_local_segv_handler (sig);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The serial event associated with the QUIT flag. set_quit_flag sets
|
||||
this, and check_quit_flag clears it. Used by interruptible_select
|
||||
to be able to do interruptible I/O with no race with the SIGINT
|
||||
@@ -914,6 +953,8 @@ async_init_signals (void)
|
||||
sigtstp_token =
|
||||
create_async_signal_handler (async_sigtstp_handler, NULL);
|
||||
#endif
|
||||
|
||||
install_handle_sigsegv ();
|
||||
}
|
||||
|
||||
/* See defs.h. */
|
||||
|
||||
@@ -70,4 +70,10 @@ extern void gdb_rl_callback_handler_install (const char *prompt);
|
||||
currently installed. */
|
||||
extern void gdb_rl_callback_handler_reinstall (void);
|
||||
|
||||
/* The SIGSEGV handler for this thread, or NULL if there is none. GDB
|
||||
always installs a global SIGSEGV handler, and then lets threads
|
||||
indicate their interest in handling the signal by setting this
|
||||
thread-local variable. */
|
||||
extern thread_local void (*thread_local_segv_handler) (int);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* configure: Rebuild.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* acinclude.m4: Include ax_pthread.m4.
|
||||
* config.in, configure: Rebuild.
|
||||
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* configure: Rebuild.
|
||||
* acinclude.m4: Use m4_include, not sinclude.
|
||||
|
||||
2019-09-20 Christian Biesinger <cbiesinger@google.com>
|
||||
|
||||
* debug.c (debug_threads): Remove comment in favor of the header.
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
dnl gdb/gdbserver/configure.in uses BFD_HAVE_SYS_PROCFS_TYPE.
|
||||
sinclude(../../bfd/bfd.m4)
|
||||
m4_include(../../bfd/bfd.m4)
|
||||
|
||||
sinclude(../acx_configure_dir.m4)
|
||||
m4_include(../acx_configure_dir.m4)
|
||||
|
||||
# This gets AM_GDB_WARNINGS.
|
||||
sinclude(../warning.m4)
|
||||
m4_include(../warning.m4)
|
||||
|
||||
dnl This gets autoconf bugfixes
|
||||
sinclude(../../config/override.m4)
|
||||
m4_include(../../config/override.m4)
|
||||
|
||||
dnl For ACX_PKGVERSION and ACX_BUGURL.
|
||||
sinclude(../../config/acx.m4)
|
||||
m4_include(../../config/acx.m4)
|
||||
|
||||
m4_include(../../config/depstand.m4)
|
||||
m4_include(../../config/lead-dot.m4)
|
||||
@@ -31,6 +31,8 @@ m4_include(../ax_cxx_compile_stdcxx.m4)
|
||||
dnl For GDB_AC_SELFTEST.
|
||||
m4_include(../selftest.m4)
|
||||
|
||||
m4_include([../../config/ax_pthread.m4])
|
||||
|
||||
dnl Check for existence of a type $1 in libthread_db.h
|
||||
dnl Based on BFD_HAVE_SYS_PROCFS_TYPE in bfd/bfd.m4.
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
*/
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define to 1 if std::thread works. */
|
||||
#undef CXX_STD_THREAD
|
||||
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
|
||||
895
gdb/gdbserver/configure
vendored
895
gdb/gdbserver/configure
vendored
@@ -636,6 +636,11 @@ WERROR_CFLAGS
|
||||
WARN_CFLAGS
|
||||
ustinc
|
||||
ustlibs
|
||||
PTHREAD_CFLAGS
|
||||
PTHREAD_LIBS
|
||||
PTHREAD_CC
|
||||
ax_pthread_config
|
||||
SED
|
||||
ALLOCA
|
||||
CCDEPMODE
|
||||
CONFIG_SRC_SUBDIR
|
||||
@@ -1967,6 +1972,119 @@ $as_echo "$ac_res" >&6; }
|
||||
|
||||
} # ac_fn_c_check_decl
|
||||
|
||||
# ac_fn_cxx_try_link LINENO
|
||||
# -------------------------
|
||||
# Try to link conftest.$ac_ext, and return whether this succeeded.
|
||||
ac_fn_cxx_try_link ()
|
||||
{
|
||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { { ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||
$as_echo "$ac_try_echo"; } >&5
|
||||
(eval "$ac_link") 2>conftest.err
|
||||
ac_status=$?
|
||||
if test -s conftest.err; then
|
||||
grep -v '^ *+' conftest.err >conftest.er1
|
||||
cat conftest.er1 >&5
|
||||
mv -f conftest.er1 conftest.err
|
||||
fi
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; } && {
|
||||
test -z "$ac_cxx_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext && {
|
||||
test "$cross_compiling" = yes ||
|
||||
test -x conftest$ac_exeext
|
||||
}; then :
|
||||
ac_retval=0
|
||||
else
|
||||
$as_echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_retval=1
|
||||
fi
|
||||
# Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
|
||||
# created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
|
||||
# interfere with the next link command; also delete a directory that is
|
||||
# left behind by Apple's compiler. We do this before executing the actions.
|
||||
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
|
||||
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
|
||||
as_fn_set_status $ac_retval
|
||||
|
||||
} # ac_fn_cxx_try_link
|
||||
|
||||
# ac_fn_cxx_check_func LINENO FUNC VAR
|
||||
# ------------------------------------
|
||||
# Tests whether FUNC exists, setting the cache variable VAR accordingly
|
||||
ac_fn_cxx_check_func ()
|
||||
{
|
||||
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 eval \${$3+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define $2 innocuous_$2
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $2 (); below.
|
||||
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
<limits.h> exists even on freestanding compilers. */
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
#else
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef $2
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char $2 ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_$2 || defined __stub___$2
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return $2 ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_link "$LINENO"; then :
|
||||
eval "$3=yes"
|
||||
else
|
||||
eval "$3=no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext 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; ${as_lineno_stack:+:} unset as_lineno
|
||||
|
||||
} # ac_fn_cxx_check_func
|
||||
|
||||
# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
|
||||
# --------------------------------------------
|
||||
# Tries to find the compile-time value of EXPR in a program that includes
|
||||
@@ -6472,6 +6590,75 @@ _ACEOF
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
|
||||
$as_echo_n "checking for a sed that does not truncate output... " >&6; }
|
||||
if ${ac_cv_path_SED+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
|
||||
for ac_i in 1 2 3 4 5 6 7; do
|
||||
ac_script="$ac_script$as_nl$ac_script"
|
||||
done
|
||||
echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
|
||||
{ ac_script=; unset ac_script;}
|
||||
if test -z "$SED"; then
|
||||
ac_path_SED_found=false
|
||||
# Loop through the user's path and test for each of PROGNAME-LIST
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_prog in sed gsed; do
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
|
||||
as_fn_executable_p "$ac_path_SED" || continue
|
||||
# Check for GNU ac_path_SED and select it if it is found.
|
||||
# Check for GNU $ac_path_SED
|
||||
case `"$ac_path_SED" --version 2>&1` in
|
||||
*GNU*)
|
||||
ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
|
||||
*)
|
||||
ac_count=0
|
||||
$as_echo_n 0123456789 >"conftest.in"
|
||||
while :
|
||||
do
|
||||
cat "conftest.in" "conftest.in" >"conftest.tmp"
|
||||
mv "conftest.tmp" "conftest.in"
|
||||
cp "conftest.in" "conftest.nl"
|
||||
$as_echo '' >> "conftest.nl"
|
||||
"$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
|
||||
diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
|
||||
as_fn_arith $ac_count + 1 && ac_count=$as_val
|
||||
if test $ac_count -gt ${ac_path_SED_max-0}; then
|
||||
# Best one so far, save it but keep looking for a better one
|
||||
ac_cv_path_SED="$ac_path_SED"
|
||||
ac_path_SED_max=$ac_count
|
||||
fi
|
||||
# 10*(2^10) chars as input seems more than enough
|
||||
test $ac_count -gt 10 && break
|
||||
done
|
||||
rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
|
||||
esac
|
||||
|
||||
$ac_path_SED_found && break 3
|
||||
done
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
if test -z "$ac_cv_path_SED"; then
|
||||
as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
|
||||
fi
|
||||
else
|
||||
ac_cv_path_SED=$SED
|
||||
fi
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
|
||||
$as_echo "$ac_cv_path_SED" >&6; }
|
||||
SED="$ac_cv_path_SED"
|
||||
rm -f conftest.sed
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
|
||||
$as_echo_n "checking for ANSI C header files... " >&6; }
|
||||
@@ -6856,6 +7043,714 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
# Check for std::thread. This does not work on some platforms, like
|
||||
# mingw and DJGPP.
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
ax_pthread_ok=no
|
||||
|
||||
# We used to check for pthread.h first, but this fails if pthread.h
|
||||
# requires special compiler flags (e.g. on Tru64 or Sequent).
|
||||
# It gets checked for in the link test anyway.
|
||||
|
||||
# First of all, check if the user has set any of the PTHREAD_LIBS,
|
||||
# etcetera environment variables, and if threads linking works using
|
||||
# them:
|
||||
if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
|
||||
ax_pthread_save_CC="$CC"
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
ax_pthread_save_LIBS="$LIBS"
|
||||
if test "x$PTHREAD_CC" != "x"; then :
|
||||
CC="$PTHREAD_CC"
|
||||
fi
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5
|
||||
$as_echo_n "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char pthread_join ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return pthread_join ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ax_pthread_ok=yes
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
|
||||
$as_echo "$ax_pthread_ok" >&6; }
|
||||
if test "x$ax_pthread_ok" = "xno"; then
|
||||
PTHREAD_LIBS=""
|
||||
PTHREAD_CFLAGS=""
|
||||
fi
|
||||
CC="$ax_pthread_save_CC"
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
LIBS="$ax_pthread_save_LIBS"
|
||||
fi
|
||||
|
||||
# We must check for the threads library under a number of different
|
||||
# names; the ordering is very important because some systems
|
||||
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
|
||||
# libraries is broken (non-POSIX).
|
||||
|
||||
# Create a list of thread flags to try. Items starting with a "-" are
|
||||
# C compiler flags, and other items are library names, except for "none"
|
||||
# which indicates that we try without any flags at all, and "pthread-config"
|
||||
# which is a program returning the flags for the Pth emulation library.
|
||||
|
||||
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
|
||||
|
||||
# The ordering *is* (sometimes) important. Some notes on the
|
||||
# individual items follow:
|
||||
|
||||
# pthreads: AIX (must check this before -lpthread)
|
||||
# none: in case threads are in libc; should be tried before -Kthread and
|
||||
# other compiler flags to prevent continual compiler warnings
|
||||
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
|
||||
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
|
||||
# (Note: HP C rejects this with "bad form for `-t' option")
|
||||
# -pthreads: Solaris/gcc (Note: HP C also rejects)
|
||||
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
|
||||
# doesn't hurt to check since this sometimes defines pthreads and
|
||||
# -D_REENTRANT too), HP C (must be checked before -lpthread, which
|
||||
# is present but should not be used directly; and before -mthreads,
|
||||
# because the compiler interprets this as "-mt" + "-hreads")
|
||||
# -mthreads: Mingw32/gcc, Lynx/gcc
|
||||
# pthread: Linux, etcetera
|
||||
# --thread-safe: KAI C++
|
||||
# pthread-config: use pthread-config program (for GNU Pth library)
|
||||
|
||||
case $host_os in
|
||||
|
||||
freebsd*)
|
||||
|
||||
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
|
||||
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
|
||||
|
||||
ax_pthread_flags="-kthread lthread $ax_pthread_flags"
|
||||
;;
|
||||
|
||||
hpux*)
|
||||
|
||||
# From the cc(1) man page: "[-mt] Sets various -D flags to enable
|
||||
# multi-threading and also sets -lpthread."
|
||||
|
||||
ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
|
||||
;;
|
||||
|
||||
openedition*)
|
||||
|
||||
# IBM z/OS requires a feature-test macro to be defined in order to
|
||||
# enable POSIX threads at all, so give the user a hint if this is
|
||||
# not set. (We don't define these ourselves, as they can affect
|
||||
# other portions of the system API in unpredictable ways.)
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
|
||||
AX_PTHREAD_ZOS_MISSING
|
||||
# endif
|
||||
|
||||
_ACEOF
|
||||
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
||||
$EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5
|
||||
$as_echo "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;}
|
||||
fi
|
||||
rm -f conftest*
|
||||
|
||||
;;
|
||||
|
||||
solaris*)
|
||||
|
||||
# On Solaris (at least, for some versions), libc contains stubbed
|
||||
# (non-functional) versions of the pthreads routines, so link-based
|
||||
# tests will erroneously succeed. (N.B.: The stubs are missing
|
||||
# pthread_cleanup_push, or rather a function called by this macro,
|
||||
# so we could check for that, but who knows whether they'll stub
|
||||
# that too in a future libc.) So we'll check first for the
|
||||
# standard Solaris way of linking pthreads (-mt -lpthread).
|
||||
|
||||
ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
|
||||
;;
|
||||
esac
|
||||
|
||||
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
|
||||
|
||||
if test "x$GCC" = "xyes"; then :
|
||||
ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"
|
||||
fi
|
||||
|
||||
# The presence of a feature test macro requesting re-entrant function
|
||||
# definitions is, on some systems, a strong hint that pthreads support is
|
||||
# correctly enabled
|
||||
|
||||
case $host_os in
|
||||
darwin* | hpux* | linux* | osf* | solaris*)
|
||||
ax_pthread_check_macro="_REENTRANT"
|
||||
;;
|
||||
|
||||
aix*)
|
||||
ax_pthread_check_macro="_THREAD_SAFE"
|
||||
;;
|
||||
|
||||
*)
|
||||
ax_pthread_check_macro="--"
|
||||
;;
|
||||
esac
|
||||
if test "x$ax_pthread_check_macro" = "x--"; then :
|
||||
ax_pthread_check_cond=0
|
||||
else
|
||||
ax_pthread_check_cond="!defined($ax_pthread_check_macro)"
|
||||
fi
|
||||
|
||||
# Are we compiling with Clang?
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5
|
||||
$as_echo_n "checking whether $CC is Clang... " >&6; }
|
||||
if ${ax_cv_PTHREAD_CLANG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ax_cv_PTHREAD_CLANG=no
|
||||
# Note that Autoconf sets GCC=yes for Clang as well as GCC
|
||||
if test "x$GCC" = "xyes"; then
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
|
||||
# if defined(__clang__) && defined(__llvm__)
|
||||
AX_PTHREAD_CC_IS_CLANG
|
||||
# endif
|
||||
|
||||
_ACEOF
|
||||
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
||||
$EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1; then :
|
||||
ax_cv_PTHREAD_CLANG=yes
|
||||
fi
|
||||
rm -f conftest*
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5
|
||||
$as_echo "$ax_cv_PTHREAD_CLANG" >&6; }
|
||||
ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
|
||||
|
||||
ax_pthread_clang_warning=no
|
||||
|
||||
# Clang needs special handling, because older versions handle the -pthread
|
||||
# option in a rather... idiosyncratic way
|
||||
|
||||
if test "x$ax_pthread_clang" = "xyes"; then
|
||||
|
||||
# Clang takes -pthread; it has never supported any other flag
|
||||
|
||||
# (Note 1: This will need to be revisited if a system that Clang
|
||||
# supports has POSIX threads in a separate library. This tends not
|
||||
# to be the way of modern systems, but it's conceivable.)
|
||||
|
||||
# (Note 2: On some systems, notably Darwin, -pthread is not needed
|
||||
# to get POSIX threads support; the API is always present and
|
||||
# active. We could reasonably leave PTHREAD_CFLAGS empty. But
|
||||
# -pthread does define _REENTRANT, and while the Darwin headers
|
||||
# ignore this macro, third-party headers might not.)
|
||||
|
||||
PTHREAD_CFLAGS="-pthread"
|
||||
PTHREAD_LIBS=
|
||||
|
||||
ax_pthread_ok=yes
|
||||
|
||||
# However, older versions of Clang make a point of warning the user
|
||||
# that, in an invocation where only linking and no compilation is
|
||||
# taking place, the -pthread option has no effect ("argument unused
|
||||
# during compilation"). They expect -pthread to be passed in only
|
||||
# when source code is being compiled.
|
||||
#
|
||||
# Problem is, this is at odds with the way Automake and most other
|
||||
# C build frameworks function, which is that the same flags used in
|
||||
# compilation (CFLAGS) are also used in linking. Many systems
|
||||
# supported by AX_PTHREAD require exactly this for POSIX threads
|
||||
# support, and in fact it is often not straightforward to specify a
|
||||
# flag that is used only in the compilation phase and not in
|
||||
# linking. Such a scenario is extremely rare in practice.
|
||||
#
|
||||
# Even though use of the -pthread flag in linking would only print
|
||||
# a warning, this can be a nuisance for well-run software projects
|
||||
# that build with -Werror. So if the active version of Clang has
|
||||
# this misfeature, we search for an option to squash it.
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5
|
||||
$as_echo_n "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; }
|
||||
if ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
|
||||
# Create an alternate version of $ac_link that compiles and
|
||||
# links in two steps (.c -> .o, .o -> exe) instead of one
|
||||
# (.c -> exe), because the warning occurs only in the second
|
||||
# step
|
||||
ax_pthread_save_ac_link="$ac_link"
|
||||
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
|
||||
ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
|
||||
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
|
||||
if test "x$ax_pthread_try" = "xunknown"; then :
|
||||
break
|
||||
fi
|
||||
CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
|
||||
ac_link="$ax_pthread_save_ac_link"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
int main(void){return 0;}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_link="$ax_pthread_2step_ac_link"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
int main(void){return 0;}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
done
|
||||
ac_link="$ax_pthread_save_ac_link"
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
if test "x$ax_pthread_try" = "x"; then :
|
||||
ax_pthread_try=no
|
||||
fi
|
||||
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5
|
||||
$as_echo "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; }
|
||||
|
||||
case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
|
||||
no | unknown) ;;
|
||||
*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
|
||||
esac
|
||||
|
||||
fi # $ax_pthread_clang = yes
|
||||
|
||||
if test "x$ax_pthread_ok" = "xno"; then
|
||||
for ax_pthread_try_flag in $ax_pthread_flags; do
|
||||
|
||||
case $ax_pthread_try_flag in
|
||||
none)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
|
||||
$as_echo_n "checking whether pthreads work without any flags... " >&6; }
|
||||
;;
|
||||
|
||||
-mt,pthread)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with -mt -lpthread" >&5
|
||||
$as_echo_n "checking whether pthreads work with -mt -lpthread... " >&6; }
|
||||
PTHREAD_CFLAGS="-mt"
|
||||
PTHREAD_LIBS="-lpthread"
|
||||
;;
|
||||
|
||||
-*)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5
|
||||
$as_echo_n "checking whether pthreads work with $ax_pthread_try_flag... " >&6; }
|
||||
PTHREAD_CFLAGS="$ax_pthread_try_flag"
|
||||
;;
|
||||
|
||||
pthread-config)
|
||||
# Extract the first word of "pthread-config", so it can be a program name with args.
|
||||
set dummy pthread-config; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_prog_ax_pthread_config+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test -n "$ax_pthread_config"; then
|
||||
ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_ax_pthread_config="yes"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no"
|
||||
fi
|
||||
fi
|
||||
ax_pthread_config=$ac_cv_prog_ax_pthread_config
|
||||
if test -n "$ax_pthread_config"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5
|
||||
$as_echo "$ax_pthread_config" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test "x$ax_pthread_config" = "xno"; then :
|
||||
continue
|
||||
fi
|
||||
PTHREAD_CFLAGS="`pthread-config --cflags`"
|
||||
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
|
||||
;;
|
||||
|
||||
*)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5
|
||||
$as_echo_n "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; }
|
||||
PTHREAD_LIBS="-l$ax_pthread_try_flag"
|
||||
;;
|
||||
esac
|
||||
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
ax_pthread_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
|
||||
# Check for various functions. We must include pthread.h,
|
||||
# since some functions may be macros. (On the Sequent, we
|
||||
# need a special flag -Kthread to make this header compile.)
|
||||
# We check for pthread_join because it is in -lpthread on IRIX
|
||||
# while pthread_create is in libc. We check for pthread_attr_init
|
||||
# due to DEC craziness with -lpthreads. We check for
|
||||
# pthread_cleanup_push because it is one of the few pthread
|
||||
# functions on Solaris that doesn't have a non-functional libc stub.
|
||||
# We try pthread_create on general principles.
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <pthread.h>
|
||||
# if $ax_pthread_check_cond
|
||||
# error "$ax_pthread_check_macro must be defined"
|
||||
# endif
|
||||
static void routine(void *a) { a = 0; }
|
||||
static void *start_routine(void *a) { return a; }
|
||||
int
|
||||
main ()
|
||||
{
|
||||
pthread_t th; pthread_attr_t attr;
|
||||
pthread_create(&th, 0, start_routine, 0);
|
||||
pthread_join(th, 0);
|
||||
pthread_attr_init(&attr);
|
||||
pthread_cleanup_push(routine, 0);
|
||||
pthread_cleanup_pop(0) /* ; */
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ax_pthread_ok=yes
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
LIBS="$ax_pthread_save_LIBS"
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
|
||||
$as_echo "$ax_pthread_ok" >&6; }
|
||||
if test "x$ax_pthread_ok" = "xyes"; then :
|
||||
break
|
||||
fi
|
||||
|
||||
PTHREAD_LIBS=""
|
||||
PTHREAD_CFLAGS=""
|
||||
done
|
||||
fi
|
||||
|
||||
# Various other checks:
|
||||
if test "x$ax_pthread_ok" = "xyes"; then
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
ax_pthread_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
|
||||
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
|
||||
$as_echo_n "checking for joinable pthread attribute... " >&6; }
|
||||
if ${ax_cv_PTHREAD_JOINABLE_ATTR+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ax_cv_PTHREAD_JOINABLE_ATTR=unknown
|
||||
for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <pthread.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int attr = $ax_pthread_attr; return attr /* ; */
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
done
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5
|
||||
$as_echo "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; }
|
||||
if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
|
||||
test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
|
||||
test "x$ax_pthread_joinable_attr_defined" != "xyes"; then :
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR
|
||||
_ACEOF
|
||||
|
||||
ax_pthread_joinable_attr_defined=yes
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5
|
||||
$as_echo_n "checking whether more special flags are required for pthreads... " >&6; }
|
||||
if ${ax_cv_PTHREAD_SPECIAL_FLAGS+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ax_cv_PTHREAD_SPECIAL_FLAGS=no
|
||||
case $host_os in
|
||||
solaris*)
|
||||
ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5
|
||||
$as_echo "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; }
|
||||
if test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
|
||||
test "x$ax_pthread_special_flags_added" != "xyes"; then :
|
||||
PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
|
||||
ax_pthread_special_flags_added=yes
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5
|
||||
$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; }
|
||||
if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <pthread.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int i = PTHREAD_PRIO_INHERIT;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ax_cv_PTHREAD_PRIO_INHERIT=yes
|
||||
else
|
||||
ax_cv_PTHREAD_PRIO_INHERIT=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5
|
||||
$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; }
|
||||
if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
|
||||
test "x$ax_pthread_prio_inherit_defined" != "xyes"; then :
|
||||
|
||||
$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h
|
||||
|
||||
ax_pthread_prio_inherit_defined=yes
|
||||
|
||||
fi
|
||||
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
LIBS="$ax_pthread_save_LIBS"
|
||||
|
||||
# More AIX lossage: compile with *_r variant
|
||||
if test "x$GCC" != "xyes"; then
|
||||
case $host_os in
|
||||
aix*)
|
||||
case "x/$CC" in #(
|
||||
x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) :
|
||||
#handle absolute path differently from PATH based program lookup
|
||||
case "x$CC" in #(
|
||||
x/*) :
|
||||
if as_fn_executable_p ${CC}_r; then :
|
||||
PTHREAD_CC="${CC}_r"
|
||||
fi ;; #(
|
||||
*) :
|
||||
for ac_prog in ${CC}_r
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_prog_PTHREAD_CC+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test -n "$PTHREAD_CC"; then
|
||||
ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_PTHREAD_CC="$ac_prog"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
fi
|
||||
fi
|
||||
PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
|
||||
if test -n "$PTHREAD_CC"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
|
||||
$as_echo "$PTHREAD_CC" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
test -n "$PTHREAD_CC" && break
|
||||
done
|
||||
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
|
||||
;;
|
||||
esac ;; #(
|
||||
*) :
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
|
||||
if test "x$ax_pthread_ok" = "xyes"; then
|
||||
threads=yes
|
||||
:
|
||||
else
|
||||
ax_pthread_ok=no
|
||||
threads=no
|
||||
fi
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
|
||||
if test "$threads" = "yes"; then
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$PTHREAD_CFLAGS $save_CFLAGS"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::thread" >&5
|
||||
$as_echo_n "checking for std::thread... " >&6; }
|
||||
if ${gdb_cv_cxx_std_thread+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <thread>
|
||||
void callback() { }
|
||||
int
|
||||
main ()
|
||||
{
|
||||
std::thread t(callback);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_compile "$LINENO"; then :
|
||||
gdb_cv_cxx_std_thread=yes
|
||||
else
|
||||
gdb_cv_cxx_std_thread=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_cxx_std_thread" >&5
|
||||
$as_echo "$gdb_cv_cxx_std_thread" >&6; }
|
||||
|
||||
# This check must be here, while LIBS includes any necessary
|
||||
# threading library.
|
||||
for ac_func in pthread_sigmask
|
||||
do :
|
||||
ac_fn_cxx_check_func "$LINENO" "pthread_sigmask" "ac_cv_func_pthread_sigmask"
|
||||
if test "x$ac_cv_func_pthread_sigmask" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_PTHREAD_SIGMASK 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
CXXFLAGS="$save_CXXFLAGS"
|
||||
fi
|
||||
if test $gdb_cv_cxx_std_thread = yes; then
|
||||
|
||||
$as_echo "#define CXX_STD_THREAD 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigsetjmp" >&5
|
||||
$as_echo_n "checking for sigsetjmp... " >&6; }
|
||||
if ${gdb_cv_func_sigsetjmp+:} false; then :
|
||||
|
||||
70
gdb/gdbsupport/alt-stack.h
Normal file
70
gdb/gdbsupport/alt-stack.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* Temporarily install an alternate signal stack
|
||||
|
||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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
|
||||
(at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GDBSUPPORT_ALT_STACK_H
|
||||
#define GDBSUPPORT_ALT_STACK_H
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
namespace gdb
|
||||
{
|
||||
|
||||
/* Try to set up an alternate signal stack for SIGSEGV handlers.
|
||||
This allows us to handle SIGSEGV signals generated when the
|
||||
normal process stack is exhausted. If this stack is not set
|
||||
up (sigaltstack is unavailable or fails) and a SIGSEGV is
|
||||
generated when the normal stack is exhausted then the program
|
||||
will behave as though no SIGSEGV handler was installed. */
|
||||
class alternate_signal_stack
|
||||
{
|
||||
public:
|
||||
alternate_signal_stack ()
|
||||
{
|
||||
#ifdef HAVE_SIGALTSTACK
|
||||
m_stack.reset ((char *) xmalloc (SIGSTKSZ));
|
||||
|
||||
stack_t stack;
|
||||
stack.ss_sp = m_stack.get ();
|
||||
stack.ss_size = SIGSTKSZ;
|
||||
stack.ss_flags = 0;
|
||||
|
||||
sigaltstack (&stack, &m_old_stack);
|
||||
#endif
|
||||
}
|
||||
|
||||
~alternate_signal_stack ()
|
||||
{
|
||||
#ifdef HAVE_SIGALTSTACK
|
||||
sigaltstack (&m_old_stack, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
DISABLE_COPY_AND_ASSIGN (alternate_signal_stack);
|
||||
|
||||
private:
|
||||
|
||||
#ifdef HAVE_SIGALTSTACK
|
||||
gdb::unique_xmalloc_ptr<char> m_stack;
|
||||
stack_t m_old_stack;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* GDBSUPPORT_ALT_STACK_H */
|
||||
65
gdb/gdbsupport/block-signals.h
Normal file
65
gdb/gdbsupport/block-signals.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* Block signals used by gdb
|
||||
|
||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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
|
||||
(at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GDBSUPPORT_BLOCK_SIGNALS_H
|
||||
#define GDBSUPPORT_BLOCK_SIGNALS_H
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
namespace gdb
|
||||
{
|
||||
|
||||
/* This is an RAII class that temporarily blocks the signals needed by
|
||||
gdb. This can be used before starting a new thread to ensure that
|
||||
this thread starts with the appropriate signals blocked. */
|
||||
class block_signals
|
||||
{
|
||||
public:
|
||||
block_signals ()
|
||||
{
|
||||
#ifdef HAVE_PTHREAD_SIGMASK
|
||||
sigset_t mask;
|
||||
sigemptyset (&mask);
|
||||
sigaddset (&mask, SIGINT);
|
||||
sigaddset (&mask, SIGCHLD);
|
||||
sigaddset (&mask, SIGALRM);
|
||||
sigaddset (&mask, SIGWINCH);
|
||||
pthread_sigmask (SIG_BLOCK, &mask, &m_old_mask);
|
||||
#endif
|
||||
}
|
||||
|
||||
~block_signals ()
|
||||
{
|
||||
#ifdef HAVE_PTHREAD_SIGMASK
|
||||
pthread_sigmask (SIG_SETMASK, &m_old_mask, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
DISABLE_COPY_AND_ASSIGN (block_signals);
|
||||
|
||||
private:
|
||||
|
||||
#ifdef HAVE_PTHREAD_SIGMASK
|
||||
sigset_t m_old_mask;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* GDBSUPPORT_BLOCK_SIGNALS_H */
|
||||
@@ -36,6 +36,37 @@ AC_DEFUN([GDB_AC_COMMON], [
|
||||
|
||||
AC_CHECK_DECLS([strerror, strstr])
|
||||
|
||||
# Check for std::thread. This does not work on some platforms, like
|
||||
# mingw and DJGPP.
|
||||
AC_LANG_PUSH([C++])
|
||||
AX_PTHREAD([threads=yes], [threads=no])
|
||||
if test "$threads" = "yes"; then
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$PTHREAD_CFLAGS $save_CFLAGS"
|
||||
AC_CACHE_CHECK([for std::thread],
|
||||
gdb_cv_cxx_std_thread,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||
[[#include <thread>
|
||||
void callback() { }]],
|
||||
[[std::thread t(callback);]])],
|
||||
gdb_cv_cxx_std_thread=yes,
|
||||
gdb_cv_cxx_std_thread=no)])
|
||||
|
||||
# This check must be here, while LIBS includes any necessary
|
||||
# threading library.
|
||||
AC_CHECK_FUNCS([pthread_sigmask])
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
CXXFLAGS="$save_CXXFLAGS"
|
||||
fi
|
||||
if test $gdb_cv_cxx_std_thread = yes; then
|
||||
AC_DEFINE(CXX_STD_THREAD, 1,
|
||||
[Define to 1 if std::thread works.])
|
||||
fi
|
||||
AC_LANG_POP
|
||||
|
||||
dnl Check if sigsetjmp is available. Using AC_CHECK_FUNCS won't
|
||||
dnl do since sigsetjmp might only be defined as a macro.
|
||||
AC_CACHE_CHECK([for sigsetjmp], gdb_cv_func_sigsetjmp,
|
||||
|
||||
28
gdb/gdbsupport/parallel-for.c
Normal file
28
gdb/gdbsupport/parallel-for.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/* Parallel for loops
|
||||
|
||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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
|
||||
(at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
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 "gdbsupport/common-defs.h"
|
||||
#include "gdbsupport/parallel-for.h"
|
||||
|
||||
namespace gdb
|
||||
{
|
||||
/* See parallel-for.h. */
|
||||
int max_threads = -1;
|
||||
thread_pool parallel_for_pool;
|
||||
}
|
||||
100
gdb/gdbsupport/parallel-for.h
Normal file
100
gdb/gdbsupport/parallel-for.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/* Parallel for loops
|
||||
|
||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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
|
||||
(at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GDBSUPPORT_PARALLEL_FOR_H
|
||||
#define GDBSUPPORT_PARALLEL_FOR_H
|
||||
|
||||
#include <algorithm>
|
||||
#if CXX_STD_THREAD
|
||||
#include <condition_variable>
|
||||
#include <system_error>
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
#include "gdbsupport/block-signals.h"
|
||||
#include "gdbsupport/thread_pool.h"
|
||||
|
||||
namespace gdb
|
||||
{
|
||||
|
||||
/* True if threading should be enabled. */
|
||||
|
||||
extern int max_threads;
|
||||
|
||||
extern thread_pool parallel_for_pool;
|
||||
|
||||
/* A very simple "parallel for". This splits the range of iterators
|
||||
into subranges, and then passes each subrange to the callback. The
|
||||
work may or may not be done in separate threads.
|
||||
|
||||
This approach was chosen over having the callback work on single
|
||||
items because it makes it simple for the caller to do
|
||||
once-per-subrange initialization and destruction. */
|
||||
|
||||
template<class RandomIt, class RangeFunction>
|
||||
void
|
||||
parallel_for_each (RandomIt first, RandomIt last, RangeFunction callback)
|
||||
{
|
||||
#if CXX_STD_THREAD
|
||||
int n_threads = std::thread::hardware_concurrency ();
|
||||
/* So we can use a local array below. */
|
||||
const int local_max = 16;
|
||||
/* Be sure to handle the "unlimited" case. */
|
||||
if (max_threads >= 0 && n_threads > max_threads)
|
||||
n_threads = max_threads;
|
||||
if (n_threads > local_max)
|
||||
n_threads = local_max;
|
||||
if (!parallel_for_pool.started ())
|
||||
{
|
||||
/* Ensure that signals used by gdb are blocked in the new
|
||||
threads. */
|
||||
block_signals blocker;
|
||||
parallel_for_pool.start (n_threads);
|
||||
}
|
||||
|
||||
std::future<void> futures[n_threads];
|
||||
|
||||
size_t n_elements = last - first;
|
||||
if (n_threads > 1 && 2 * n_threads <= n_elements)
|
||||
{
|
||||
size_t elts_per_thread = n_elements / n_threads;
|
||||
for (int i = 0; i < n_threads; ++i)
|
||||
{
|
||||
RandomIt end = first + elts_per_thread;
|
||||
futures[i] = parallel_for_pool.post_task ([&, first, end] () {
|
||||
callback (first, end);
|
||||
});
|
||||
first = end;
|
||||
}
|
||||
}
|
||||
else
|
||||
n_threads = 0;
|
||||
#endif /* CXX_STD_THREAD */
|
||||
|
||||
/* Process all the remaining elements in the main thread. */
|
||||
callback (first, last);
|
||||
#ifdef CXX_STD_THREAD
|
||||
for (size_t i = 0; i < n_threads; ++i)
|
||||
futures[i].wait ();
|
||||
#endif /* CXX_STD_THREAD */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* GDBSUPPORT_PARALLEL_FOR_H */
|
||||
50
gdb/gdbsupport/thread_pool.c
Normal file
50
gdb/gdbsupport/thread_pool.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "thread_pool.h"
|
||||
|
||||
namespace gdb {
|
||||
|
||||
thread_pool::~thread_pool ()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> guard (m_tasks_mutex);
|
||||
m_shutdown = true;
|
||||
m_tasks_cv.notify_all ();
|
||||
}
|
||||
for (auto& t : m_threads)
|
||||
t.join();
|
||||
}
|
||||
|
||||
void
|
||||
thread_pool::start (size_t num_threads)
|
||||
{
|
||||
for (size_t i = 0; i < num_threads; ++i)
|
||||
{
|
||||
m_threads.emplace_back (&thread_pool::thread_function, this);
|
||||
}
|
||||
m_started = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
thread_pool::thread_function ()
|
||||
{
|
||||
while (!m_shutdown)
|
||||
{
|
||||
task t;
|
||||
{
|
||||
std::unique_lock<std::mutex> guard (m_tasks_mutex);
|
||||
if (m_shutdown)
|
||||
break;
|
||||
if (m_tasks.empty ())
|
||||
m_tasks_cv.wait (guard);
|
||||
if (m_shutdown)
|
||||
break;
|
||||
if (m_tasks.empty ())
|
||||
continue;
|
||||
t = std::move (m_tasks.front());
|
||||
m_tasks.pop();
|
||||
}
|
||||
t ();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
47
gdb/gdbsupport/thread_pool.h
Normal file
47
gdb/gdbsupport/thread_pool.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef PARALLEL_FOR_H
|
||||
#define PARALLEL_FOR_H
|
||||
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <future>
|
||||
|
||||
namespace gdb {
|
||||
|
||||
class thread_pool {
|
||||
public:
|
||||
thread_pool() : m_started (false), m_shutdown (false) {}
|
||||
~thread_pool();
|
||||
|
||||
bool started() const { return m_started; }
|
||||
|
||||
void start(size_t num_threads);
|
||||
|
||||
typedef std::packaged_task<void()> task;
|
||||
std::future<void> post_task(std::function<void ()> func) {
|
||||
task t(func);
|
||||
std::future<void> f = t.get_future();
|
||||
std::lock_guard<std::mutex> guard (m_tasks_mutex);
|
||||
m_tasks.push (std::move (t));
|
||||
m_tasks_cv.notify_one ();
|
||||
return f;
|
||||
}
|
||||
|
||||
private:
|
||||
void thread_function();
|
||||
|
||||
bool m_started;
|
||||
std::vector<std::thread> m_threads;
|
||||
std::atomic<bool> m_shutdown;
|
||||
std::queue<task> m_tasks;
|
||||
std::condition_variable m_tasks_cv;
|
||||
std::mutex m_tasks_mutex;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
26
gdb/main.c
26
gdb/main.c
@@ -48,6 +48,7 @@
|
||||
#include <vector>
|
||||
#include "gdbsupport/pathstuff.h"
|
||||
#include "cli/cli-style.h"
|
||||
#include "gdbsupport/alt-stack.h"
|
||||
|
||||
/* The selected interpreter. This will be used as a set command
|
||||
variable, so it should always be malloc'ed - since
|
||||
@@ -290,29 +291,6 @@ get_init_files (std::string *system_gdbinit,
|
||||
*local_gdbinit = localinit;
|
||||
}
|
||||
|
||||
/* Try to set up an alternate signal stack for SIGSEGV handlers.
|
||||
This allows us to handle SIGSEGV signals generated when the
|
||||
normal process stack is exhausted. If this stack is not set
|
||||
up (sigaltstack is unavailable or fails) and a SIGSEGV is
|
||||
generated when the normal stack is exhausted then the program
|
||||
will behave as though no SIGSEGV handler was installed. */
|
||||
|
||||
static void
|
||||
setup_alternate_signal_stack (void)
|
||||
{
|
||||
#ifdef HAVE_SIGALTSTACK
|
||||
stack_t ss;
|
||||
|
||||
/* FreeBSD versions older than 11.0 use char * for ss_sp instead of
|
||||
void *. This cast works with both types. */
|
||||
ss.ss_sp = (char *) xmalloc (SIGSTKSZ);
|
||||
ss.ss_size = SIGSTKSZ;
|
||||
ss.ss_flags = 0;
|
||||
|
||||
sigaltstack(&ss, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Call command_loop. */
|
||||
|
||||
/* Prevent inlining this function for the benefit of GDB's selftests
|
||||
@@ -859,7 +837,7 @@ captured_main_1 (struct captured_main_args *context)
|
||||
save_original_signals_state (quiet);
|
||||
|
||||
/* Try to set up an alternate signal stack for SIGSEGV handlers. */
|
||||
setup_alternate_signal_stack ();
|
||||
gdb::alternate_signal_stack signal_stack;
|
||||
|
||||
/* Initialize all files. */
|
||||
gdb_init (gdb_program_name);
|
||||
|
||||
12
gdb/maint.c
12
gdb/maint.c
@@ -40,6 +40,7 @@
|
||||
#include "top.h"
|
||||
#include "maint.h"
|
||||
#include "gdbsupport/selftest.h"
|
||||
#include "gdbsupport/parallel-for.h"
|
||||
|
||||
#include "cli/cli-decode.h"
|
||||
#include "cli/cli-utils.h"
|
||||
@@ -1312,4 +1313,15 @@ When enabled GDB is profiled."),
|
||||
show_maintenance_profile_p,
|
||||
&maintenance_set_cmdlist,
|
||||
&maintenance_show_cmdlist);
|
||||
|
||||
add_setshow_zuinteger_unlimited_cmd ("max-worker-threads",
|
||||
class_maintenance,
|
||||
&gdb::max_threads, _("\
|
||||
Set the maximum number of worker threads GDB can use."), _("\
|
||||
Set the maximum number of worker threads GDB can use."), _("\
|
||||
GDB may use multiple threads to speed up certain CPU-intensive operations,\n\
|
||||
such as demangling symbol names."),
|
||||
NULL, NULL,
|
||||
&maintenance_set_cmdlist,
|
||||
&maintenance_show_cmdlist);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,23 @@
|
||||
#include "gdbsupport/symbol.h"
|
||||
#include <algorithm>
|
||||
#include "safe-ctype.h"
|
||||
#include "gdbsupport/alt-stack.h"
|
||||
#include "gdbsupport/parallel-for.h"
|
||||
|
||||
#if CXX_STD_THREAD
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
#if CXX_STD_THREAD
|
||||
/* Mutex that is used when modifying or accessing the demangled hash
|
||||
table. This is a global mutex simply because the only current
|
||||
multi-threaded user of the hash table does not process multiple
|
||||
objfiles in parallel. The mutex could easily live on the per-BFD
|
||||
object, but this approach avoids using extra memory when it is not
|
||||
needed. */
|
||||
static std::mutex demangled_mutex;
|
||||
#endif
|
||||
|
||||
/* See minsyms.h. */
|
||||
|
||||
@@ -1106,7 +1123,11 @@ minimal_symbol_reader::record_full (const char *name, int name_len,
|
||||
msymbol = &m_msym_bunch->contents[m_msym_bunch_index];
|
||||
symbol_set_language (msymbol, language_auto,
|
||||
&m_objfile->per_bfd->storage_obstack);
|
||||
symbol_set_names (msymbol, name, name_len, copy_name, m_objfile->per_bfd);
|
||||
|
||||
if (copy_name)
|
||||
name = (char *) obstack_copy0 (&m_objfile->per_bfd->storage_obstack,
|
||||
name, name_len);
|
||||
msymbol->name = name;
|
||||
|
||||
SET_MSYMBOL_VALUE_ADDRESS (msymbol, address);
|
||||
MSYMBOL_SECTION (msymbol) = section;
|
||||
@@ -1327,6 +1348,42 @@ minimal_symbol_reader::install ()
|
||||
m_objfile->per_bfd->minimal_symbol_count = mcount;
|
||||
m_objfile->per_bfd->msymbols = std::move (msym_holder);
|
||||
|
||||
msymbols = m_objfile->per_bfd->msymbols.get ();
|
||||
gdb::parallel_for_each
|
||||
(&msymbols[0], &msymbols[mcount],
|
||||
[&] (minimal_symbol *start, minimal_symbol *end)
|
||||
{
|
||||
/* Ensure that SIGSEGV is delivered to an alternate signal
|
||||
stack. */
|
||||
gdb::alternate_signal_stack signal_stack;
|
||||
|
||||
for (minimal_symbol *msym = start; msym < end; ++msym)
|
||||
{
|
||||
if (!msym->name_set)
|
||||
{
|
||||
/* This will be freed later, by symbol_set_names. */
|
||||
char* demangled_name = symbol_find_demangled_name (msym,
|
||||
msym->name);
|
||||
symbol_set_demangled_name (msym, demangled_name,
|
||||
&m_objfile->per_bfd->storage_obstack);
|
||||
msym->name_set = 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
/* To limit how long we hold the lock, we only acquire it here
|
||||
and not while we demangle the names above. */
|
||||
#if CXX_STD_THREAD
|
||||
std::lock_guard<std::mutex> guard (demangled_mutex);
|
||||
#endif
|
||||
for (minimal_symbol *msym = start; msym < end; ++msym)
|
||||
{
|
||||
symbol_set_names (msym, msym->name,
|
||||
strlen (msym->name), 0,
|
||||
m_objfile->per_bfd);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
build_minimal_symbol_hash_tables (m_objfile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "value.h"
|
||||
#include "language.h"
|
||||
#include "event-loop.h"
|
||||
#include "serial.h"
|
||||
#include "readline/tilde.h"
|
||||
#include "python.h"
|
||||
#include "extension-priv.h"
|
||||
@@ -940,63 +939,81 @@ gdbpy_source_script (const struct extension_language_defn *extlang,
|
||||
|
||||
/* Posting and handling events. */
|
||||
|
||||
/* A helper class to save and restore the GIL, but without touching
|
||||
the other globals that are handled by gdbpy_enter. */
|
||||
|
||||
class gdbpy_gil
|
||||
{
|
||||
public:
|
||||
|
||||
gdbpy_gil ()
|
||||
: m_state (PyGILState_Ensure ())
|
||||
{
|
||||
}
|
||||
|
||||
~gdbpy_gil ()
|
||||
{
|
||||
PyGILState_Release (m_state);
|
||||
}
|
||||
|
||||
DISABLE_COPY_AND_ASSIGN (gdbpy_gil);
|
||||
|
||||
private:
|
||||
|
||||
PyGILState_STATE m_state;
|
||||
};
|
||||
|
||||
/* A single event. */
|
||||
struct gdbpy_event
|
||||
{
|
||||
/* The Python event. This is just a callable object. */
|
||||
PyObject *event;
|
||||
/* The next event. */
|
||||
struct gdbpy_event *next;
|
||||
gdbpy_event (gdbpy_ref<> &&func)
|
||||
: m_func (func.release ())
|
||||
{
|
||||
}
|
||||
|
||||
gdbpy_event (gdbpy_event &&other)
|
||||
: m_func (other.m_func)
|
||||
{
|
||||
other.m_func = nullptr;
|
||||
}
|
||||
|
||||
gdbpy_event (const gdbpy_event &other)
|
||||
: m_func (other.m_func)
|
||||
{
|
||||
gdbpy_gil gil;
|
||||
Py_XINCREF (m_func);
|
||||
}
|
||||
|
||||
~gdbpy_event ()
|
||||
{
|
||||
gdbpy_gil gil;
|
||||
Py_XDECREF (m_func);
|
||||
}
|
||||
|
||||
gdbpy_event &operator= (const gdbpy_event &other) = delete;
|
||||
|
||||
void operator() ()
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
|
||||
gdbpy_ref<> call_result (PyObject_CallObject (m_func, NULL));
|
||||
if (call_result == NULL)
|
||||
gdbpy_print_stack ();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/* The Python event. This is just a callable object. Note that
|
||||
this is not a gdbpy_ref<>, because we have to take particular
|
||||
care to only destroy the reference when holding the GIL. */
|
||||
PyObject *m_func;
|
||||
};
|
||||
|
||||
/* All pending events. */
|
||||
static struct gdbpy_event *gdbpy_event_list;
|
||||
/* The final link of the event list. */
|
||||
static struct gdbpy_event **gdbpy_event_list_end;
|
||||
|
||||
/* So that we can wake up the main thread even when it is blocked in
|
||||
poll(). */
|
||||
static struct serial_event *gdbpy_serial_event;
|
||||
|
||||
/* The file handler callback. This reads from the internal pipe, and
|
||||
then processes the Python event queue. This will always be run in
|
||||
the main gdb thread. */
|
||||
|
||||
static void
|
||||
gdbpy_run_events (int error, gdb_client_data client_data)
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
|
||||
/* Clear the event fd. Do this before flushing the events list, so
|
||||
that any new event post afterwards is sure to re-awake the event
|
||||
loop. */
|
||||
serial_event_clear (gdbpy_serial_event);
|
||||
|
||||
while (gdbpy_event_list)
|
||||
{
|
||||
/* Dispatching the event might push a new element onto the event
|
||||
loop, so we update here "atomically enough". */
|
||||
struct gdbpy_event *item = gdbpy_event_list;
|
||||
gdbpy_event_list = gdbpy_event_list->next;
|
||||
if (gdbpy_event_list == NULL)
|
||||
gdbpy_event_list_end = &gdbpy_event_list;
|
||||
|
||||
gdbpy_ref<> call_result (PyObject_CallObject (item->event, NULL));
|
||||
if (call_result == NULL)
|
||||
gdbpy_print_stack ();
|
||||
|
||||
Py_DECREF (item->event);
|
||||
xfree (item);
|
||||
}
|
||||
}
|
||||
|
||||
/* Submit an event to the gdb thread. */
|
||||
static PyObject *
|
||||
gdbpy_post_event (PyObject *self, PyObject *args)
|
||||
{
|
||||
struct gdbpy_event *event;
|
||||
PyObject *func;
|
||||
int wakeup;
|
||||
|
||||
if (!PyArg_ParseTuple (args, "O", &func))
|
||||
return NULL;
|
||||
@@ -1010,36 +1027,13 @@ gdbpy_post_event (PyObject *self, PyObject *args)
|
||||
|
||||
Py_INCREF (func);
|
||||
|
||||
/* From here until the end of the function, we have the GIL, so we
|
||||
can operate on our global data structures without worrying. */
|
||||
wakeup = gdbpy_event_list == NULL;
|
||||
|
||||
event = XNEW (struct gdbpy_event);
|
||||
event->event = func;
|
||||
event->next = NULL;
|
||||
*gdbpy_event_list_end = event;
|
||||
gdbpy_event_list_end = &event->next;
|
||||
|
||||
/* Wake up gdb when needed. */
|
||||
if (wakeup)
|
||||
serial_event_set (gdbpy_serial_event);
|
||||
gdbpy_ref<> func_ref = gdbpy_ref<>::new_reference (func);
|
||||
gdbpy_event event (std::move (func_ref));
|
||||
run_on_main_thread (event);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/* Initialize the Python event handler. */
|
||||
static int
|
||||
gdbpy_initialize_events (void)
|
||||
{
|
||||
gdbpy_event_list_end = &gdbpy_event_list;
|
||||
|
||||
gdbpy_serial_event = make_serial_event ();
|
||||
add_file_handler (serial_event_fd (gdbpy_serial_event),
|
||||
gdbpy_run_events, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This is the extension_language_ops.before_prompt "method". */
|
||||
@@ -1704,7 +1698,6 @@ do_start_initialization ()
|
||||
|| gdbpy_initialize_linetable () < 0
|
||||
|| gdbpy_initialize_thread () < 0
|
||||
|| gdbpy_initialize_inferior () < 0
|
||||
|| gdbpy_initialize_events () < 0
|
||||
|| gdbpy_initialize_eventregistry () < 0
|
||||
|| gdbpy_initialize_py_events () < 0
|
||||
|| gdbpy_initialize_event () < 0
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
#include "ser-event.h"
|
||||
#include "serial.h"
|
||||
#include "gdbsupport/filestuff.h"
|
||||
#if CXX_STD_THREAD
|
||||
#include <mutex>
|
||||
#endif
|
||||
#include "event-loop.h"
|
||||
|
||||
/* On POSIX hosts, a serial_event is basically an abstraction for the
|
||||
classical self-pipe trick.
|
||||
@@ -217,3 +221,77 @@ serial_event_clear (struct serial_event *event)
|
||||
ResetEvent (state->event);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The serial event used when posting runnables. */
|
||||
|
||||
static struct serial_event *runnable_event;
|
||||
|
||||
/* Runnables that have been posted. */
|
||||
|
||||
static std::vector<std::function<void ()>> runnables;
|
||||
|
||||
#if CXX_STD_THREAD
|
||||
|
||||
/* Mutex to hold when handling runnable_event or runnables. */
|
||||
|
||||
static std::mutex runnable_mutex;
|
||||
|
||||
#endif
|
||||
|
||||
/* Run all the queued runnables. */
|
||||
|
||||
static void
|
||||
run_events (int error, gdb_client_data client_data)
|
||||
{
|
||||
std::vector<std::function<void ()>> local;
|
||||
|
||||
/* Hold the lock while changing the globals, but not while running
|
||||
the runnables. */
|
||||
{
|
||||
#if CXX_STD_THREAD
|
||||
std::lock_guard<std::mutex> lock (runnable_mutex);
|
||||
#endif
|
||||
|
||||
/* Clear the event fd. Do this before flushing the events list,
|
||||
so that any new event post afterwards is sure to re-awaken the
|
||||
event loop. */
|
||||
serial_event_clear (runnable_event);
|
||||
|
||||
/* Move the vector in case running a runnable pushes a new
|
||||
runnable. */
|
||||
local = std::move (runnables);
|
||||
}
|
||||
|
||||
for (auto &item : local)
|
||||
{
|
||||
try
|
||||
{
|
||||
item ();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
/* Ignore exceptions in the callback. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* See ser-event.h. */
|
||||
|
||||
void
|
||||
run_on_main_thread (std::function<void ()> &&func)
|
||||
{
|
||||
#if CXX_STD_THREAD
|
||||
std::lock_guard<std::mutex> lock (runnable_mutex);
|
||||
#endif
|
||||
runnables.emplace_back (std::move (func));
|
||||
serial_event_set (runnable_event);
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_ser_event ()
|
||||
{
|
||||
runnable_event = make_serial_event ();
|
||||
add_file_handler (serial_event_fd (runnable_event), run_events, nullptr);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#ifndef SER_EVENT_H
|
||||
#define SER_EVENT_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
/* This is used to be able to signal the event loop (or any other
|
||||
select/poll) of events, in a race-free manner.
|
||||
|
||||
@@ -48,4 +50,8 @@ extern void serial_event_set (struct serial_event *event);
|
||||
call is made. */
|
||||
extern void serial_event_clear (struct serial_event *event);
|
||||
|
||||
/* Send a runnable to the main thread. */
|
||||
|
||||
extern void run_on_main_thread (std::function<void ()> &&);
|
||||
|
||||
#endif
|
||||
|
||||
107
gdb/symtab.c
107
gdb/symtab.c
@@ -759,13 +759,9 @@ create_demangled_names_hash (struct objfile_per_bfd_storage *per_bfd)
|
||||
NULL, xcalloc, xfree));
|
||||
}
|
||||
|
||||
/* Try to determine the demangled name for a symbol, based on the
|
||||
language of that symbol. If the language is set to language_auto,
|
||||
it will attempt to find any demangling algorithm that works and
|
||||
then set the language appropriately. The returned name is allocated
|
||||
by the demangler and should be xfree'd. */
|
||||
/* See symtab.h */
|
||||
|
||||
static char *
|
||||
char *
|
||||
symbol_find_demangled_name (struct general_symbol_info *gsymbol,
|
||||
const char *mangled)
|
||||
{
|
||||
@@ -839,9 +835,6 @@ symbol_set_names (struct general_symbol_info *gsymbol,
|
||||
return;
|
||||
}
|
||||
|
||||
if (per_bfd->demangled_names_hash == NULL)
|
||||
create_demangled_names_hash (per_bfd);
|
||||
|
||||
if (linkage_name[len] != '\0')
|
||||
{
|
||||
char *alloc_name;
|
||||
@@ -855,71 +848,85 @@ symbol_set_names (struct general_symbol_info *gsymbol,
|
||||
else
|
||||
linkage_name_copy = linkage_name;
|
||||
|
||||
struct demangled_name_entry *found_entry;
|
||||
|
||||
if (per_bfd->demangled_names_hash == NULL)
|
||||
create_demangled_names_hash (per_bfd);
|
||||
|
||||
entry.mangled = linkage_name_copy;
|
||||
slot = ((struct demangled_name_entry **)
|
||||
htab_find_slot (per_bfd->demangled_names_hash.get (),
|
||||
&entry, INSERT));
|
||||
htab_find_slot (per_bfd->demangled_names_hash.get (),
|
||||
&entry, INSERT));
|
||||
|
||||
/* If this name is not in the hash table, add it. */
|
||||
if (*slot == NULL
|
||||
/* A C version of the symbol may have already snuck into the table.
|
||||
This happens to, e.g., main.init (__go_init_main). Cope. */
|
||||
This happens to, e.g., main.init (__go_init_main). Cope. */
|
||||
|| (gsymbol->language == language_go
|
||||
&& (*slot)->demangled[0] == '\0'))
|
||||
&& (*slot)->demangled[0] == '\0'))
|
||||
{
|
||||
/* The const_cast is safe because the only reason it is already initialized
|
||||
is if we purposefully set it from a background thread to avoid doing the
|
||||
work here. However, it is still allocated from the heap and needs to
|
||||
be freed by us, just like if we called symbol_find_demangled_name
|
||||
here. */
|
||||
char *demangled_name_ptr
|
||||
= symbol_find_demangled_name (gsymbol, linkage_name_copy);
|
||||
= gsymbol->language_specific.demangled_name
|
||||
? const_cast<char*>(gsymbol->language_specific.demangled_name)
|
||||
: symbol_find_demangled_name (gsymbol, linkage_name_copy);
|
||||
gdb::unique_xmalloc_ptr<char> demangled_name (demangled_name_ptr);
|
||||
int demangled_len = demangled_name ? strlen (demangled_name.get ()) : 0;
|
||||
|
||||
/* Suppose we have demangled_name==NULL, copy_name==0, and
|
||||
linkage_name_copy==linkage_name. In this case, we already have the
|
||||
mangled name saved, and we don't have a demangled name. So,
|
||||
you might think we could save a little space by not recording
|
||||
this in the hash table at all.
|
||||
|
||||
It turns out that it is actually important to still save such
|
||||
an entry in the hash table, because storing this name gives
|
||||
us better bcache hit rates for partial symbols. */
|
||||
linkage_name_copy==linkage_name. In this case, we already have the
|
||||
mangled name saved, and we don't have a demangled name. So,
|
||||
you might think we could save a little space by not recording
|
||||
this in the hash table at all.
|
||||
|
||||
It turns out that it is actually important to still save such
|
||||
an entry in the hash table, because storing this name gives
|
||||
us better bcache hit rates for partial symbols. */
|
||||
if (!copy_name && linkage_name_copy == linkage_name)
|
||||
{
|
||||
*slot
|
||||
= ((struct demangled_name_entry *)
|
||||
obstack_alloc (&per_bfd->storage_obstack,
|
||||
offsetof (struct demangled_name_entry, demangled)
|
||||
+ demangled_len + 1));
|
||||
(*slot)->mangled = linkage_name;
|
||||
}
|
||||
{
|
||||
*slot
|
||||
= ((struct demangled_name_entry *)
|
||||
obstack_alloc (&per_bfd->storage_obstack,
|
||||
offsetof (struct demangled_name_entry, demangled)
|
||||
+ demangled_len + 1));
|
||||
(*slot)->mangled = linkage_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *mangled_ptr;
|
||||
{
|
||||
char *mangled_ptr;
|
||||
|
||||
/* If we must copy the mangled name, put it directly after
|
||||
the demangled name so we can have a single
|
||||
allocation. */
|
||||
*slot
|
||||
= ((struct demangled_name_entry *)
|
||||
obstack_alloc (&per_bfd->storage_obstack,
|
||||
offsetof (struct demangled_name_entry, demangled)
|
||||
+ len + demangled_len + 2));
|
||||
mangled_ptr = &((*slot)->demangled[demangled_len + 1]);
|
||||
strcpy (mangled_ptr, linkage_name_copy);
|
||||
(*slot)->mangled = mangled_ptr;
|
||||
}
|
||||
/* If we must copy the mangled name, put it directly after
|
||||
the demangled name so we can have a single
|
||||
allocation. */
|
||||
*slot
|
||||
= ((struct demangled_name_entry *)
|
||||
obstack_alloc (&per_bfd->storage_obstack,
|
||||
offsetof (struct demangled_name_entry, demangled)
|
||||
+ len + demangled_len + 2));
|
||||
mangled_ptr = &((*slot)->demangled[demangled_len + 1]);
|
||||
strcpy (mangled_ptr, linkage_name_copy);
|
||||
(*slot)->mangled = mangled_ptr;
|
||||
}
|
||||
(*slot)->language = gsymbol->language;
|
||||
|
||||
if (demangled_name != NULL)
|
||||
strcpy ((*slot)->demangled, demangled_name.get ());
|
||||
strcpy ((*slot)->demangled, demangled_name.get ());
|
||||
else
|
||||
(*slot)->demangled[0] = '\0';
|
||||
(*slot)->demangled[0] = '\0';
|
||||
}
|
||||
else if (gsymbol->language == language_unknown
|
||||
|| gsymbol->language == language_auto)
|
||||
|| gsymbol->language == language_auto)
|
||||
gsymbol->language = (*slot)->language;
|
||||
|
||||
gsymbol->name = (*slot)->mangled;
|
||||
if ((*slot)->demangled[0] != '\0')
|
||||
symbol_set_demangled_name (gsymbol, (*slot)->demangled,
|
||||
found_entry = *slot;
|
||||
|
||||
gsymbol->name = found_entry->mangled;
|
||||
if (found_entry->demangled[0] != '\0')
|
||||
symbol_set_demangled_name (gsymbol, found_entry->demangled,
|
||||
&per_bfd->storage_obstack);
|
||||
else
|
||||
symbol_set_demangled_name (gsymbol, NULL, &per_bfd->storage_obstack);
|
||||
|
||||
14
gdb/symtab.h
14
gdb/symtab.h
@@ -483,6 +483,16 @@ extern void symbol_set_language (struct general_symbol_info *symbol,
|
||||
enum language language,
|
||||
struct obstack *obstack);
|
||||
|
||||
|
||||
/* Try to determine the demangled name for a symbol, based on the
|
||||
language of that symbol. If the language is set to language_auto,
|
||||
it will attempt to find any demangling algorithm that works and
|
||||
then set the language appropriately. The returned name is allocated
|
||||
by the demangler and should be xfree'd. */
|
||||
|
||||
extern char *symbol_find_demangled_name (struct general_symbol_info *gsymbol,
|
||||
const char *mangled);
|
||||
|
||||
/* Set just the linkage name of a symbol; do not try to demangle
|
||||
it. Used for constructs which do not have a mangled name,
|
||||
e.g. struct tags. Unlike SYMBOL_SET_NAMES, linkage_name must
|
||||
@@ -669,6 +679,10 @@ struct minimal_symbol : public general_symbol_info
|
||||
the object file format may not carry that piece of information. */
|
||||
unsigned int has_size : 1;
|
||||
|
||||
/* Non-zero if this symbol ever had its demangled name set (even if
|
||||
it was set to NULL). */
|
||||
unsigned int name_set : 1;
|
||||
|
||||
/* Minimal symbols with the same hash key are kept on a linked
|
||||
list. This is the link. */
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
2019-09-30 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* configure: Rebuild.
|
||||
* aclocal.m4: Use m4_include, not sinclude.
|
||||
|
||||
2019-09-30 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
* gdb.rust/traits.rs: Disable all warnings.
|
||||
|
||||
6
gdb/testsuite/aclocal.m4
vendored
6
gdb/testsuite/aclocal.m4
vendored
@@ -1,6 +1,6 @@
|
||||
sinclude(../../config/acx.m4)
|
||||
sinclude(../../config/override.m4)
|
||||
sinclude(../transform.m4)
|
||||
m4_include(../../config/acx.m4)
|
||||
m4_include(../../config/override.m4)
|
||||
m4_include(../transform.m4)
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
|
||||
80
gdb/unittests/main-thread-selftests.c
Normal file
80
gdb/unittests/main-thread-selftests.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/* Self tests for run_on_main_thread
|
||||
|
||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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
|
||||
(at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
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 "gdbsupport/selftest.h"
|
||||
#include "gdbsupport/block-signals.h"
|
||||
#include "ser-event.h"
|
||||
#include "event-loop.h"
|
||||
#if CXX_STD_THREAD
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
namespace selftests {
|
||||
namespace main_thread_tests {
|
||||
|
||||
#if CXX_STD_THREAD
|
||||
|
||||
static bool done;
|
||||
|
||||
static void
|
||||
set_done ()
|
||||
{
|
||||
run_on_main_thread ([] ()
|
||||
{
|
||||
done = true;
|
||||
});
|
||||
}
|
||||
|
||||
static void
|
||||
run_tests ()
|
||||
{
|
||||
std::thread thread;
|
||||
|
||||
done = false;
|
||||
|
||||
{
|
||||
gdb::block_signals blocker;
|
||||
|
||||
thread = std::thread (set_done);
|
||||
}
|
||||
|
||||
while (!done && gdb_do_one_event () >= 0)
|
||||
;
|
||||
|
||||
/* Actually the test will just hang, but we want to test
|
||||
something. */
|
||||
SELF_CHECK (done);
|
||||
|
||||
thread.join ();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_main_thread_selftests ()
|
||||
{
|
||||
#if CXX_STD_THREAD
|
||||
selftests::register_test ("main_thread",
|
||||
selftests::main_thread_tests::run_tests);
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user