diff mbox

PR58867 ASan and UBSan tests not run for installed testing.

Message ID 542BA8C0.2080509@partner.samsung.com
State New
Headers show

Commit Message

max Oct. 1, 2014, 7:09 a.m. UTC
Hi,

some time ago, Andrew wrote a patch that fixes PR58867 
(http://patchwork.ozlabs.org/patch/286866/), but for some reasons it
wasn't committed to trunk.

This is resurrected Andrew's patch, extended to support Tsan testsuite.

Tested on x86_64-pc-linux-gnu, ok to commit?

-Maxim

Comments

max Oct. 1, 2014, 7:54 a.m. UTC | #1
Adding Joseph S. Myers as bug reporter.

On 10/01/2014 11:09 AM, Maxim Ostapenko wrote:
> Hi,
>
> some time ago, Andrew wrote a patch that fixes PR58867 
> (http://patchwork.ozlabs.org/patch/286866/), but for some reasons it
> wasn't committed to trunk.
>
> This is resurrected Andrew's patch, extended to support Tsan testsuite.
>
> Tested on x86_64-pc-linux-gnu, ok to commit?
>
> -Maxim
Mike Stump Oct. 1, 2014, 12:31 p.m. UTC | #2
> On 10/01/2014 11:09 AM, Maxim Ostapenko wrote:
>> Hi,
>> 
>> some time ago, Andrew wrote a patch that fixes PR58867 (http://patchwork.ozlabs.org/patch/286866/), but for some reasons it
>> wasn't committed to trunk.
>> 
>> This is resurrected Andrew's patch, extended to support Tsan testsuite.
>> 
>> Tested on x86_64-pc-linux-gnu, ok to commit?

So, I’d like to hear from Andrew and/or Jakub if there are any objections…  I glanced through the patch, and it seems reasonable enough.  Let’s give em a chance to respond…  If no objections, Ok.
Jakub Jelinek Oct. 1, 2014, 12:51 p.m. UTC | #3
On Wed, Oct 01, 2014 at 05:31:46AM -0700, Mike Stump wrote:
> 
> > On 10/01/2014 11:09 AM, Maxim Ostapenko wrote:
> >> Hi,
> >> 
> >> some time ago, Andrew wrote a patch that fixes PR58867 (http://patchwork.ozlabs.org/patch/286866/), but for some reasons it
> >> wasn't committed to trunk.
> >> 
> >> This is resurrected Andrew's patch, extended to support Tsan testsuite.
> >> 
> >> Tested on x86_64-pc-linux-gnu, ok to commit?
> 
> So, I’d like to hear from Andrew and/or Jakub if there are any objections…
> I glanced through the patch, and it seems reasonable enough.  Let’s give
> em a chance to respond… If no objections, Ok.

Ok with me.  Seems I've reviewed the patch back in December 2013, but
Andrew has not posted an updated patch with the requested changes,
but apparently Maxim did incorporate those changes.

	Jakub
Marcus Shawcroft Oct. 8, 2014, 9:02 a.m. UTC | #4
On 1 October 2014 08:09, Maxim Ostapenko
<m.ostapenko@partner.samsung.com> wrote:
> Hi,
>
> some time ago, Andrew wrote a patch that fixes PR58867
> (http://patchwork.ozlabs.org/patch/286866/), but for some reasons it
> wasn't committed to trunk.
>
> This is resurrected Andrew's patch, extended to support Tsan testsuite.
>
> Tested on x86_64-pc-linux-gnu, ok to commit?
>
> -Maxim

Hi,

This patch  results in wide spread failures in our bare metal test
runs.  I have not dug into the issue in detail but it appears that the
issue is related to the attempted use of  set_ld_library_path_env_vars
 and restore_ld_library_path_env_vars to save and restore nested
contexts.

Consider ubsan/ubsan.exp:

load_lib gcc-dg.exp
...
dg-init
ubsan_init
...
ubsan_finish

The gcc-dg.exp library load calls set_ld_library_path_env_vars the
first time an initializes GCC_EXEC_PREFIX.
The ubsan_init call makes a further call to
set_ld_library_path_env_vars which has no effect.
The ubsan_finish invokes restore_ld_library_path_env_vars, restoring
the environments as it was prior to the call to dg-init.
Any further test execution has now lost the original initialization of
GCC_EXEC_PREFIX by gcc-dg.exp

It seems to me that either this patch assumes  that the
set/restore_ld_library_path_env foo  is capable of maintaining a stack
of saved contexts... which it is not.

Prior to this patch ubsan_finish did not attempt to call
restore_ld_library_path_env_vars hence the gcc-dg.exp environment
remained in place for subsequent test executions.

Cheers
/Marcus
max Oct. 8, 2014, 10:10 a.m. UTC | #5
Does it work without restore_ld_library_path in {asan, ubsan, tsan}_finish?

I see two opportunities to fix the issue:

1) Implement a stack of saved contexts.

2) Implement new functions, say {asan, ubsan, 
tsan}_restore_ld_library_path, to be able {asan, ubsan, tsan}_finish 
functions restore context correctly.

What solution is preferable?

-Maxim
On 10/08/2014 01:02 PM, Marcus Shawcroft wrote:
> On 1 October 2014 08:09, Maxim Ostapenko
> <m.ostapenko@partner.samsung.com> wrote:
>> Hi,
>>
>> some time ago, Andrew wrote a patch that fixes PR58867
>> (http://patchwork.ozlabs.org/patch/286866/), but for some reasons it
>> wasn't committed to trunk.
>>
>> This is resurrected Andrew's patch, extended to support Tsan testsuite.
>>
>> Tested on x86_64-pc-linux-gnu, ok to commit?
>>
>> -Maxim
> Hi,
>
> This patch  results in wide spread failures in our bare metal test
> runs.  I have not dug into the issue in detail but it appears that the
> issue is related to the attempted use of  set_ld_library_path_env_vars
>   and restore_ld_library_path_env_vars to save and restore nested
> contexts.
>
> Consider ubsan/ubsan.exp:
>
> load_lib gcc-dg.exp
> ...
> dg-init
> ubsan_init
> ...
> ubsan_finish
>
> The gcc-dg.exp library load calls set_ld_library_path_env_vars the
> first time an initializes GCC_EXEC_PREFIX.
> The ubsan_init call makes a further call to
> set_ld_library_path_env_vars which has no effect.
> The ubsan_finish invokes restore_ld_library_path_env_vars, restoring
> the environments as it was prior to the call to dg-init.
> Any further test execution has now lost the original initialization of
> GCC_EXEC_PREFIX by gcc-dg.exp
>
> It seems to me that either this patch assumes  that the
> set/restore_ld_library_path_env foo  is capable of maintaining a stack
> of saved contexts... which it is not.
>
> Prior to this patch ubsan_finish did not attempt to call
> restore_ld_library_path_env_vars hence the gcc-dg.exp environment
> remained in place for subsequent test executions.
>
> Cheers
> /Marcus
>
Marcus Shawcroft Oct. 8, 2014, 11:40 a.m. UTC | #6
On 8 October 2014 11:10, Maxim Ostapenko
<m.ostapenko@partner.samsung.com> wrote:
> Does it work without restore_ld_library_path in {asan, ubsan, tsan}_finish?
>
> I see two opportunities to fix the issue:
>
> 1) Implement a stack of saved contexts.
>
> 2) Implement new functions, say {asan, ubsan, tsan}_restore_ld_library_path,
> to be able {asan, ubsan, tsan}_finish functions restore context correctly.
>
> What solution is preferable?

Option 1 has the advantage that it places all of the context save and
restore in one place rather than spreading it around the
infrastructure.

Please can we revert this patch while a correct implementation is being worked?

Cheers
/Marcus
Eric Botcazou Oct. 24, 2014, 10:43 a.m. UTC | #7
> some time ago, Andrew wrote a patch that fixes PR58867
> (http://patchwork.ozlabs.org/patch/286866/), but for some reasons it
> wasn't committed to trunk.
> 
> This is resurrected Andrew's patch, extended to support Tsan testsuite.

This patch broke --disable-libsanitizer though, i.e. you now get gazillions of 
sanitizer failures in the C and C++ testsuites.
max Oct. 24, 2014, 4:02 p.m. UTC | #8
On 10/24/2014 02:43 PM, Eric Botcazou wrote:
>> some time ago, Andrew wrote a patch that fixes PR58867
>> (http://patchwork.ozlabs.org/patch/286866/), but for some reasons it
>> wasn't committed to trunk.
>>
>> This is resurrected Andrew's patch, extended to support Tsan testsuite.
> This patch broke --disable-libsanitizer though, i.e. you now get gazillions of
> sanitizer failures in the C and C++ testsuites.
>
Hi,

do you have any other (system) version of GCC, configured without 
--disable-libsanitizer? If so, perhaps your GCC links with system 
asan_preinit.o and links dummy int main () { return 0; } in 
check_effective_target_fsanitize_address successfully, but fails to find 
libasan.so in execution tests because LD_LIBRARY_PATH does not contain 
any path to libasan.so.2.

If so, I see two ways to fix this:

1) Add path to system libs in LD_LIBRARY_PATH explicitly.

2) Make check_effective_target_fsanitize_address not only link dummy 
executable, but also run it and verify that exit code equals zero.

-Maxim
Eric Botcazou Oct. 27, 2014, 8:50 a.m. UTC | #9
> do you have any other (system) version of GCC, configured without
> --disable-libsanitizer?

Nope.

> 2) Make check_effective_target_fsanitize_address not only link dummy
> executable, but also run it and verify that exit code equals zero.

Yes, probably something along these lines, or restore the previous logic.
diff mbox

Patch

ChangeLog:

2014-10-01  Andrew Pinski  <apinski@cavium.com>
	    Max Ostapenko  <m.ostapenko@partner.samsung.com>

	* lib/ubsan-dg.exp
	(check_effective_target_fsanitize_address): New function.
	(ubsan_init): Save off ALWAYS_CXXFLAGS.
	(ubsan_finish): Restore ALWAYS_CXXFLAGS correctly.
	* lib/asan-dg.exp
	(check_effective_target_faddress_sanitizer): Rename to ...
	(check_effective_target_fsanitize_address): ... this. Change to creating
	an executable.
	(asan_init): Save off ALWAYS_CXXFLAGS.
	(asan_finish): Restore ALWAYS_CXXFLAGS correctly.
	* lib/tsan-dg.exp
	(check_effective_target_fthread_sanitizer): Rename to ...
	(check_effective_target_fsanitize_thread): ... this. Change to creating
	an executable.
	(tsan_init): Save off ALWAYS_CXXFLAGS.
	(tsan_finish): Restore ALWAYS_CXXFLAGS correctly. Set dg-do-what-default
	to run as a default behaviour.
	* gcc.dg/ubsan/ubsan.exp: Don't check the return value of ubsan_init.
	Check check_effective_target_fsanitize_undefined before running the
	tests.
	* g++.dg/ubsan/ubsan.exp: Likewise.
	* gcc.dg/asan/asan.exp: Don't check the return value of asan_init.
	check_effective_target_fsanitize_address too early.
	Check check_effective_target_fsanitize_address before running the tests.
	* g++.dg/asan/asan.exp: Likewise.
	* gcc.dg/tsan/tsan.exp: Don't check the return value of tsan_init.
	check_effective_target_fsanitize_thread too early.
	Check check_effective_target_fsanitize_thread before running the tests.
	* g++.dg/tsan/tsan.exp: Likewise.

diff --git a/gcc/testsuite/g++.dg/asan/asan.exp b/gcc/testsuite/g++.dg/asan/asan.exp
index 98ff59c..f51f87a 100644
--- a/gcc/testsuite/g++.dg/asan/asan.exp
+++ b/gcc/testsuite/g++.dg/asan/asan.exp
@@ -20,17 +20,13 @@ 
 load_lib g++-dg.exp
 load_lib asan-dg.exp
 
-if ![check_effective_target_faddress_sanitizer] {
-  return
-}
-
 # Initialize `dg'.
 dg-init
-if [asan_init] {
+asan_init
 
 # Main loop.
-gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/asan/*.c]] "" ""
-
+if [check_effective_target_fsanitize_address] {
+  gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/asan/*.c]] "" ""
 }
 
 # All done.
diff --git a/gcc/testsuite/g++.dg/tsan/tsan.exp b/gcc/testsuite/g++.dg/tsan/tsan.exp
index 37caeb9..c7f97f6 100644
--- a/gcc/testsuite/g++.dg/tsan/tsan.exp
+++ b/gcc/testsuite/g++.dg/tsan/tsan.exp
@@ -23,10 +23,6 @@  load_lib g++-dg.exp
 load_lib tsan-dg.exp
 load_lib torture-options.exp
 
-if ![check_effective_target_fthread_sanitizer] {
-  return
-}
-
 # Initialize `dg'.
 dg-init
 torture-init
@@ -34,11 +30,11 @@  set-torture-options [list \
 	{ -O0 } \
 	{ -O2 } ]
 
-if [tsan_init] {
+tsan_init
 
 # Main loop.
-gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/tsan/*.c]] "" ""
-
+if [check_effective_target_fsanitize_thread] {
+  gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/tsan/*.c]] "" ""
 }
 
 # All done.
diff --git a/gcc/testsuite/g++.dg/ubsan/ubsan.exp b/gcc/testsuite/g++.dg/ubsan/ubsan.exp
index 769855e..a835c19 100644
--- a/gcc/testsuite/g++.dg/ubsan/ubsan.exp
+++ b/gcc/testsuite/g++.dg/ubsan/ubsan.exp
@@ -22,11 +22,11 @@  load_lib ubsan-dg.exp
 
 # Initialize `dg'.
 dg-init
-if [ubsan_init] {
+ubsan_init
 
 # Main loop.
-gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/ubsan/*.c]] "" ""
-
+if [check_effective_target_fsanitize_undefined] {
+  gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/ubsan/*.c]] "" ""
 }
 
 # All done.
diff --git a/gcc/testsuite/gcc.dg/asan/asan.exp b/gcc/testsuite/gcc.dg/asan/asan.exp
index 69534c4..2e0d592 100644
--- a/gcc/testsuite/gcc.dg/asan/asan.exp
+++ b/gcc/testsuite/gcc.dg/asan/asan.exp
@@ -22,17 +22,13 @@ 
 load_lib gcc-dg.exp
 load_lib asan-dg.exp
 
-if ![check_effective_target_faddress_sanitizer] {
-  return
-}
-
 # Initialize `dg'.
 dg-init
-if [asan_init] {
+asan_init
 
 # Main loop.
-gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/asan/*.c]] "" ""
-
+if [check_effective_target_fsanitize_address] {
+  gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/asan/*.c]] "" ""
 }
 
 # All done.
diff --git a/gcc/testsuite/gcc.dg/tsan/tsan.exp b/gcc/testsuite/gcc.dg/tsan/tsan.exp
index 8fa29bd..1558c0f 100644
--- a/gcc/testsuite/gcc.dg/tsan/tsan.exp
+++ b/gcc/testsuite/gcc.dg/tsan/tsan.exp
@@ -23,10 +23,6 @@  load_lib gcc-dg.exp
 load_lib tsan-dg.exp
 load_lib torture-options.exp
 
-if ![check_effective_target_fthread_sanitizer] {
-  return
-}
-
 # Initialize `dg'.
 dg-init
 torture-init
@@ -34,11 +30,11 @@  set-torture-options [list \
 	{ -O0 } \
 	{ -O2 } ]
 
-if [tsan_init] {
+tsan_init
 
 # Main loop.
-gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/tsan/*.c]] "" ""
-
+if [check_effective_target_fsanitize_thread] {
+  gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/tsan/*.c]] "" ""
 }
 
 # All done.
diff --git a/gcc/testsuite/gcc.dg/ubsan/ubsan.exp b/gcc/testsuite/gcc.dg/ubsan/ubsan.exp
index 5518d55..9fd102b 100644
--- a/gcc/testsuite/gcc.dg/ubsan/ubsan.exp
+++ b/gcc/testsuite/gcc.dg/ubsan/ubsan.exp
@@ -24,11 +24,11 @@  load_lib ubsan-dg.exp
 
 # Initialize `dg'.
 dg-init
-if [ubsan_init] {
+ubsan_init
 
 # Main loop.
-gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/ubsan/*.c]] "" ""
-
+if [check_effective_target_fsanitize_undefined] {
+  gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/ubsan/*.c]] "" ""
 }
 
 # All done.
diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp
index 7a12160..9769138 100644
--- a/gcc/testsuite/lib/asan-dg.exp
+++ b/gcc/testsuite/lib/asan-dg.exp
@@ -17,9 +17,9 @@ 
 # Return 1 if compilation with -fsanitize=address is error-free for trivial
 # code, 0 otherwise.
 
-proc check_effective_target_faddress_sanitizer {} {
-    return [check_no_compiler_messages faddress_sanitizer object {
-	void foo (void) { }
+proc check_effective_target_fsanitize_address {} {
+    return [check_no_compiler_messages fsanitize_address executable {
+	int main (void) { return 0; }
     } "-fsanitize=address"]
 }
 
@@ -85,6 +85,7 @@  proc asan_init { args } {
     global ALWAYS_CXXFLAGS
     global TOOL_OPTIONS
     global asan_saved_TEST_ALWAYS_FLAGS
+    global asan_saved_ALWAYS_CXXFLAGS
 
     set link_flags ""
     if ![is_remote host] {
@@ -101,6 +102,7 @@  proc asan_init { args } {
 	set asan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS
     }
     if [info exists ALWAYS_CXXFLAGS] {
+	set asan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS
 	set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS]
 	set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=address -g $include_flags}" $ALWAYS_CXXFLAGS]
     } else {
@@ -110,10 +112,6 @@  proc asan_init { args } {
 	    set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=address -g $include_flags"
 	}
     }
-    if { $link_flags != "" } {
-	return 1
-    }
-    return 0
 }
 
 #
@@ -123,12 +121,18 @@  proc asan_init { args } {
 proc asan_finish { args } {
     global TEST_ALWAYS_FLAGS
     global asan_saved_TEST_ALWAYS_FLAGS
+    global asan_saved_ALWAYS_CXXFLAGS
 
-    if [info exists asan_saved_TEST_ALWAYS_FLAGS] {
-	set TEST_ALWAYS_FLAGS $asan_saved_TEST_ALWAYS_FLAGS
+    if [info exists asan_saved_ALWAYS_CXXFLAGS ] {
+	set ALWAYS_CXXFLAGS $asan_saved_ALWAYS_CXXFLAGS
     } else {
-	unset TEST_ALWAYS_FLAGS
+	if [info exists asan_saved_TEST_ALWAYS_FLAGS] {
+	    set TEST_ALWAYS_FLAGS $asan_saved_TEST_ALWAYS_FLAGS
+	} else {
+	    unset TEST_ALWAYS_FLAGS
+	}
     }
+    restore_ld_library_path_env_vars
 }
 
 # Symbolize lines like
diff --git a/gcc/testsuite/lib/tsan-dg.exp b/gcc/testsuite/lib/tsan-dg.exp
index f313123..21b86ea 100644
--- a/gcc/testsuite/lib/tsan-dg.exp
+++ b/gcc/testsuite/lib/tsan-dg.exp
@@ -17,9 +17,9 @@ 
 # Return 1 if compilation with -fsanitize=thread is error-free for trivial
 # code, 0 otherwise.
 
-proc check_effective_target_fthread_sanitizer {} {
-    return [check_no_compiler_messages faddress_sanitizer object {
-	void foo (void) { }
+proc check_effective_target_fsanitize_thread {} {
+    return [check_no_compiler_messages fanitize_thread executable {
+	int main (void) { return 0; }
     } "-fPIE -pie -fsanitize=thread"]
 }
 
@@ -69,6 +69,7 @@  proc tsan_init { args } {
     global ALWAYS_CXXFLAGS
     global TOOL_OPTIONS
     global tsan_saved_TEST_ALWAYS_FLAGS
+    global tsan_saved_ALWAYS_CXXFLAGS
     global dg-do-what-default
     global tsan_saved_dg-do-what-default
 
@@ -88,6 +89,7 @@  proc tsan_init { args } {
 	set tsan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS
     }
     if [info exists ALWAYS_CXXFLAGS] {
+	set tsan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS
 	set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS]
 	set ALWAYS_CXXFLAGS [concat "{additional_flags=-fPIE -pie -fsanitize=thread -g}" $ALWAYS_CXXFLAGS]
     } else {
@@ -97,6 +99,8 @@  proc tsan_init { args } {
 	    set TEST_ALWAYS_FLAGS "$link_flags -fPIE -pie -fsanitize=thread -g"
 	}
     }
+
+    set dg-do-what-default run
     if { $link_flags != "" } {
 	global individual_timeout
 
@@ -110,9 +114,7 @@  proc tsan_init { args } {
 	    set dg-do-what-default compile
 	}
 	unset individual_timeout
-	return 1
     }
-    return 0
 }
 
 #
@@ -122,17 +124,24 @@  proc tsan_init { args } {
 proc tsan_finish { args } {
     global TEST_ALWAYS_FLAGS
     global tsan_saved_TEST_ALWAYS_FLAGS
+    global tsan_saved_ALWAYS_CXXFLAGS
     global dg-do-what-default
     global tsan_saved_dg-do-what-default
 
-    if [info exists tsan_saved_TEST_ALWAYS_FLAGS] {
-	set TEST_ALWAYS_FLAGS $tsan_saved_TEST_ALWAYS_FLAGS
+    if [info exists tsan_saved_ALWAYS_CXXFLAGS ] {
+	set ALWAYS_CXXFLAGS $tsan_saved_ALWAYS_CXXFLAGS
     } else {
-	unset TEST_ALWAYS_FLAGS
+	if [info exists tsan_saved_TEST_ALWAYS_FLAGS] {
+	    set TEST_ALWAYS_FLAGS $tsan_saved_TEST_ALWAYS_FLAGS
+        } else {
+	    unset TEST_ALWAYS_FLAGS
+        }
     }
+
     if [info exists tsan_saved_dg-do-what-default] {
 	set dg-do-what-default ${tsan_saved_dg-do-what-default}
     } else {
 	unset dg-do-what-default
     }
+    restore_ld_library_path_env_vars
 }
diff --git a/gcc/testsuite/lib/ubsan-dg.exp b/gcc/testsuite/lib/ubsan-dg.exp
index fecce7b..5a7a653 100644
--- a/gcc/testsuite/lib/ubsan-dg.exp
+++ b/gcc/testsuite/lib/ubsan-dg.exp
@@ -14,6 +14,15 @@ 
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
+# Return 1 if compilation with -fsanitize=undefined is error-free for trivial
+# code, 0 otherwise.
+
+proc check_effective_target_fsanitize_undefined {} {
+    return [check_no_compiler_messages fsanitize_undefined executable {
+	int main (void) { return 0; }
+    } "-fsanitize=undefined"]
+}
+
 #
 # ubsan_link_flags -- compute library path and flags to find libubsan.
 # (originally from g++.exp)
@@ -61,6 +70,7 @@  proc ubsan_init { args } {
     global ALWAYS_CXXFLAGS
     global TOOL_OPTIONS
     global ubsan_saved_TEST_ALWAYS_FLAGS
+    global ubsan_saved_ALWAYS_CXXFLAGS
 
     set link_flags ""
     if ![is_remote host] {
@@ -75,6 +85,7 @@  proc ubsan_init { args } {
 	set ubsan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS
     }
     if [info exists ALWAYS_CXXFLAGS] {
+	set ubsan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS
 	set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS]
     } else {
 	if [info exists TEST_ALWAYS_FLAGS] {
@@ -83,10 +94,6 @@  proc ubsan_init { args } {
 	    set TEST_ALWAYS_FLAGS "$link_flags"
 	}
     }
-    if { $link_flags != "" } {
-	return 1
-    }
-    return 0
 }
 
 #
@@ -96,10 +103,16 @@  proc ubsan_init { args } {
 proc ubsan_finish { args } {
     global TEST_ALWAYS_FLAGS
     global ubsan_saved_TEST_ALWAYS_FLAGS
+    global ubsan_saved_ALWAYS_CXXFLAGS
 
-    if [info exists ubsan_saved_TEST_ALWAYS_FLAGS] {
-	set TEST_ALWAYS_FLAGS $ubsan_saved_TEST_ALWAYS_FLAGS
+    if [info exists ubsan_saved_ALWAYS_CXXFLAGS ] {
+	set ALWAYS_CXXFLAGS $ubsan_saved_ALWAYS_CXXFLAGS
     } else {
-	unset TEST_ALWAYS_FLAGS
+	if [info exists ubsan_saved_TEST_ALWAYS_FLAGS] {
+	    set TEST_ALWAYS_FLAGS $ubsan_saved_TEST_ALWAYS_FLAGS
+	} else {
+	    unset TEST_ALWAYS_FLAGS
+	}
     }
+    restore_ld_library_path_env_vars
 }