[v2,10/10] Add --enable-ubsan

Message ID 20181002044420.17628-11-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey Oct. 2, 2018, 4:44 a.m. UTC
  This adds --enable-ubsan to gdb's configure.  By default it is enabled
in development mode, and disabled otherwise.  This passes both
-fsanitize=undefined and -fno-sanitize-recover=undefined to
compilations, so that undefined behavior violations will be sure to
cause test failures.

gdb/ChangeLog
2018-10-01  Tom Tromey  <tom@tromey.com>

	* README: Mention --enable-ubsan.
	* NEWS: Mention --enable-ubsan.
	* acinclude.m4: Include sanitize.m4.
	* configure: Rebuild.
	* configure.ac: Call AM_GDB_UBSAN.
	* sanitize.m4: New file.

gdb/doc/ChangeLog
2018-10-01  Tom Tromey  <tom@tromey.com>

	* gdb.texinfo (Configure Options): Document --enable-ubsan.
---
 gdb/ChangeLog       |   9 ++++
 gdb/NEWS            |   8 ++++
 gdb/README          |   7 +++
 gdb/acinclude.m4    |   3 ++
 gdb/configure       | 105 ++++++++++++++++++++++++++++++++++++++++++++
 gdb/configure.ac    |   1 +
 gdb/doc/ChangeLog   |   4 ++
 gdb/doc/gdb.texinfo |   7 +++
 gdb/sanitize.m4     |  46 +++++++++++++++++++
 9 files changed, 190 insertions(+)
 create mode 100644 gdb/sanitize.m4
  

Comments

Eli Zaretskii Oct. 2, 2018, 1:52 p.m. UTC | #1
> From: Tom Tromey <tom@tromey.com>
> Cc: Tom Tromey <tom@tromey.com>
> Date: Mon,  1 Oct 2018 22:44:20 -0600
> 
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -103,6 +103,14 @@ CSKY GNU/LINUX			csky*-*-linux
>    ** The gdb.Progspace type has a new 'objfiles' method, which returns the list
>       of objfiles associated to that program space.
>  
> +* Configure changes
> +
> +--enable-ubsan
> +
> +  Enable or disable the undefined behavior sanitizer.  Release
> +  versions of gdb disable this by default, but development versions

"GDB", capitalized, I guess?

> --- a/gdb/README
> +++ b/gdb/README
> @@ -538,6 +538,13 @@ more obscure GDB `configure' options are not listed here.
>       the compiler, which will fail the compilation if the compiler
>       outputs any warning messages.
>  
> +`--enable-ubsan'
> +     Enable the GCC undefined behavior sanitizer.  By default this is
> +     disabled in GDB releases, but enabled when building from git.
> +     The undefined behavior sanitizer checks for C++ undefined
> +     behavior.  It has a performance cost, so if you are looking at
> +     GDB's performance, you should disable it.

Does this require some minimal version of g++?  If so, I think we
should mention that.  And what about testing for this support at
configure time?

> +
> +# 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
>  cat >config.log <<_ACEOF
>  This file contains any messages produced by compilers while
>  running configure, to aid debugging if configure makes a mistake.

Is this hunk related to the issue at hand?

The documentation parts are approved, with the above nits fixed.

Thanks.
  
Tom Tromey Oct. 2, 2018, 9:25 p.m. UTC | #2
>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:

>> +  Enable or disable the undefined behavior sanitizer.  Release
>> +  versions of gdb disable this by default, but development versions

Eli> "GDB", capitalized, I guess?

Done.

>> +`--enable-ubsan'
>> +     Enable the GCC undefined behavior sanitizer.  By default this is
>> +     disabled in GDB releases, but enabled when building from git.
>> +     The undefined behavior sanitizer checks for C++ undefined
>> +     behavior.  It has a performance cost, so if you are looking at
>> +     GDB's performance, you should disable it.

Eli> Does this require some minimal version of g++?  If so, I think we
Eli> should mention that.  And what about testing for this support at
Eli> configure time?

It was in GCC 4.9.  It is tested at configure time.  I've updated the
text & will send a new patch.

>> +# ac_fn_cxx_try_link LINENO
>> +# -------------------------
[..]

Eli> Is this hunk related to the issue at hand?

Yes, I think it's part of configure expansion of the new test.

Tom
  
Pedro Alves Oct. 3, 2018, 5:54 p.m. UTC | #3
On 10/02/2018 05:44 AM, Tom Tromey wrote:
> This adds --enable-ubsan to gdb's configure.  By default it is enabled
> in development mode, and disabled otherwise.  This passes both
> -fsanitize=undefined and -fno-sanitize-recover=undefined to
> compilations, so that undefined behavior violations will be sure to
> cause test failures.

Thanks much for all the docs additions, and all the preparatory
work that came with it.

> --- /dev/null
> +++ b/gdb/sanitize.m4
> @@ -0,0 +1,46 @@
> +dnl Autoconf configure script for GDB, the GNU debugger.

Nit: I guess this was copied from warning.m4, but, could you
tweak this intro comment, which seems to have been originally
blindly copied from configure.ac into warning.m4?

Otherwise LGTM.

Thanks,
Pedro Alves
  
Tom Tromey Oct. 3, 2018, 9:08 p.m. UTC | #4
>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

>> --- /dev/null
>> +++ b/gdb/sanitize.m4
>> @@ -0,0 +1,46 @@
>> +dnl Autoconf configure script for GDB, the GNU debugger.

Pedro> Nit: I guess this was copied from warning.m4, but, could you
Pedro> tweak this intro comment, which seems to have been originally
Pedro> blindly copied from configure.ac into warning.m4?

I've tweaked it.

Tom
  

Patch

diff --git a/gdb/NEWS b/gdb/NEWS
index 2669fa91a1..17751bb120 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -103,6 +103,14 @@  CSKY GNU/LINUX			csky*-*-linux
   ** The gdb.Progspace type has a new 'objfiles' method, which returns the list
      of objfiles associated to that program space.
 
+* Configure changes
+
+--enable-ubsan
+
+  Enable or disable the undefined behavior sanitizer.  Release
+  versions of gdb disable this by default, but development versions
+  enable it.  Enabling this can cause a performance penalty.
+
 *** Changes in GDB 8.2
 
 * The 'set disassembler-options' command now supports specifying options
diff --git a/gdb/README b/gdb/README
index 5881be23af..69ba0eb8df 100644
--- a/gdb/README
+++ b/gdb/README
@@ -538,6 +538,13 @@  more obscure GDB `configure' options are not listed here.
      the compiler, which will fail the compilation if the compiler
      outputs any warning messages.
 
+`--enable-ubsan'
+     Enable the GCC undefined behavior sanitizer.  By default this is
+     disabled in GDB releases, but enabled when building from git.
+     The undefined behavior sanitizer checks for C++ undefined
+     behavior.  It has a performance cost, so if you are looking at
+     GDB's performance, you should disable it.
+
 `configure' accepts other options, for compatibility with configuring
 other GNU tools recursively.
 
diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4
index 3c2d01015b..52ba3f9ed6 100644
--- a/gdb/acinclude.m4
+++ b/gdb/acinclude.m4
@@ -15,6 +15,9 @@  sinclude(transform.m4)
 # This gets AM_GDB_WARNINGS.
 sinclude(warning.m4)
 
+# AM_GDB_UBSAN
+sinclude(sanitize.m4)
+
 dnl gdb/configure.in uses BFD_NEED_DECLARATION, so get its definition.
 sinclude(../bfd/bfd.m4)
 
diff --git a/gdb/configure b/gdb/configure
index b7c4ff6f29..4436cc970f 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -886,6 +886,7 @@  with_system_gdbinit
 enable_werror
 enable_build_warnings
 enable_gdb_build_warnings
+enable_ubsan
 with_lzma
 with_liblzma_prefix
 with_tcl
@@ -1556,6 +1557,7 @@  Optional Features:
   --enable-gdb-build-warnings
                           enable GDB specific build-time compiler warnings if
                           gcc is used
+  --enable-ubsan          enable undefined behavior sanitizer (auto/yes/no)
   --enable-sim            link gdb with simulator
   --enable-gdbserver      automatically build gdbserver (yes/no/auto, default
                           is auto)
@@ -2448,6 +2450,52 @@  $as_echo "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # 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
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -15561,6 +15609,63 @@  ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
+# Check whether --enable-ubsan was given.
+if test "${enable_ubsan+set}" = set; then :
+  enableval=$enable_ubsan;
+else
+  enable_ubsan=auto
+fi
+
+if test "x$enable_ubsan" = xauto; then
+  if $development; then
+    enable_ubsan=yes
+  fi
+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 "x$enable_ubsan" = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -fsanitize=undefined is accepted" >&5
+$as_echo_n "checking whether -fsanitize=undefined is accepted... " >&6; }
+  saved_CXXFLAGS="$CXXFLAGS"
+  CXXFLAGS="$CXXFLAGS -fsanitize=undefined -fno-sanitize-recover=undefined"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  enable_ubsan=yes
+else
+  enable_ubsan=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  CXXFLAGS="$saved_CXXFLAGS"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_ubsan" >&5
+$as_echo "$enable_ubsan" >&6; }
+  if test "x$enable_ubsan" = xyes; then
+    WARN_CFLAGS="$WARN_CFLAGS -fsanitize=undefined -fno-sanitize-recover=undefined"
+    CONFIG_LDFLAGS="$CONFIG_LDFLAGS -fsanitize=undefined"
+  fi
+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
+
+
+
 # In the Cygwin environment, we need some additional flags.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cygwin" >&5
 $as_echo_n "checking for cygwin... " >&6; }
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 7f6a4033c8..34bfda0907 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1838,6 +1838,7 @@  GDB_AC_WITH_DIR(SYSTEM_GDBINIT, system-gdbinit,
     [])
 
 AM_GDB_WARNINGS
+AM_GDB_UBSAN
 
 # In the Cygwin environment, we need some additional flags.
 AC_CACHE_CHECK([for cygwin], gdb_cv_os_cygwin,
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 49a2cdce9e..913ea21b6e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -35744,6 +35744,13 @@  compiler you are using.
 Treat compiler warnings as werrors.  It adds the @code{-Werror} flag
 to the compiler, which will fail the compilation if the compiler
 outputs any warning messages.
+
+@item --enable-ubsan
+Enable the GCC undefined behavior sanitizer.  By default this is
+disabled in @value{GDBN} releases, but enabled when building from git.
+The undefined behavior sanitizer checks for C@t{++} undefined
+behavior.  It has a performance cost, so if you are looking at
+@value{GDBN}'s performance, you should disable it.
 @end table
 
 @node System-wide configuration
diff --git a/gdb/sanitize.m4 b/gdb/sanitize.m4
new file mode 100644
index 0000000000..3e2207b466
--- /dev/null
+++ b/gdb/sanitize.m4
@@ -0,0 +1,46 @@ 
+dnl Autoconf configure script for GDB, the GNU debugger.
+dnl Copyright (C) 2018 Free Software Foundation, Inc.
+dnl
+dnl This file is part of GDB.
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+AC_DEFUN([AM_GDB_UBSAN],[
+AC_ARG_ENABLE(ubsan,
+  AS_HELP_STRING([--enable-ubsan],
+                 [enable undefined behavior sanitizer (auto/yes/no)]),
+  [],enable_ubsan=auto)
+if test "x$enable_ubsan" = xauto; then
+  if $development; then
+    enable_ubsan=yes
+  fi
+fi
+AC_LANG_PUSH([C++])
+if test "x$enable_ubsan" = xyes; then
+  AC_MSG_CHECKING(whether -fsanitize=undefined is accepted)
+  saved_CXXFLAGS="$CXXFLAGS"
+  CXXFLAGS="$CXXFLAGS -fsanitize=undefined -fno-sanitize-recover=undefined"
+  dnl A link check is required because it is possible to install gcc
+  dnl without libubsan, leading to link failures when compiling with
+  dnl -fsanitize=undefined.
+  AC_TRY_LINK([],[],enable_ubsan=yes,enable_ubsan=no)
+  CXXFLAGS="$saved_CXXFLAGS"
+  AC_MSG_RESULT($enable_ubsan)
+  if test "x$enable_ubsan" = xyes; then
+    WARN_CFLAGS="$WARN_CFLAGS -fsanitize=undefined -fno-sanitize-recover=undefined"
+    CONFIG_LDFLAGS="$CONFIG_LDFLAGS -fsanitize=undefined"
+  fi
+fi
+AC_LANG_POP([C++])
+])