[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #39 from Dmitry Vyukov dvyukov at google dot com 2013-02-01 20:00:22 UTC --- Sorry, I was busy previous weeks. Thanks for fixing this.
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #37 from Jakub Jelinek jakub at gcc dot gnu.org 2013-01-31 14:29:27 UTC --- As discussed elsewhere, __atomic_load_n actually should work on all targets, if the backend doesn't have special support for that, it is emitted as normal load for loads with sizes = wordsize, plus perhaps some barrier (if target has any). Can you please post the patch to gcc-patches?
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #38 from Jakub Jelinek jakub at gcc dot gnu.org 2013-01-31 16:57:15 UTC --- Author: jakub Date: Thu Jan 31 16:57:09 2013 New Revision: 195618 URL: http://gcc.gnu.org/viewcvs?root=gccview=revrev=195618 Log: PR libgomp/55561 * config/linux/wait.h (do_spin): Use atomic load for addr. * config/linux/ptrlock.c (gomp_ptrlock_get_slow): Use atomic for intptr and ptrlock. * config/linux/ptrlock.h (gomp_ptrlock_get): Use atomic load for ptrlock. Modified: trunk/libgomp/ChangeLog trunk/libgomp/config/linux/ptrlock.c trunk/libgomp/config/linux/ptrlock.h trunk/libgomp/config/linux/wait.h
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 Alan Modra amodra at gmail dot com changed: What|Removed |Added CC||amodra at gmail dot com --- Comment #36 from Alan Modra amodra at gmail dot com 2013-01-31 07:42:52 UTC --- *** Bug 56159 has been marked as a duplicate of this bug. ***
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #34 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2013-01-10 11:26:23 UTC --- (In reply to comment #33) Can you sent it to review? You can also mention that it fixes issue 40362. I had a closer look at PR40362. Actually, I don't think this patch fixes PR40362, as it only addresses the config/linux/ variant and not the config/posix/ (which is what the --disable-linux-futex choice in PR40362 follows). I would be happy if you could sent the patch, I wouldn't be able to explain the rationale for the changes, I just followed your instructions in comment #26. You'll notice that the changelog I prepared also puts your name, I think this is appropriate.
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #35 from Jakub Jelinek jakub at gcc dot gnu.org 2013-01-10 11:37:08 UTC --- For config/posix it is not that easy, because you can't assume that atomics are available. You'd need to guard it with #ifdef HAVE_SYNC_BUILTINS and do something else (nothing?) otherwise. Those targets don't support tsan anyway...
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #33 from Dmitry Vyukov dvyukov at google dot com 2013-01-08 09:17:31 UTC --- (In reply to comment #32) (In reply to comment #30) The formatting in the patch is wrong (multiple issues). I've tried to fix them in the version below. It would be really cool to have -fopenmp -fsanitize=thread to work out-of-the-box with gcc. Agree. Can you sent it to review? You can also mention that it fixes issue 40362.
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #32 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2013-01-07 21:35:25 UTC --- (In reply to comment #30) The formatting in the patch is wrong (multiple issues). I've tried to fix them in the version below. It would be really cool to have -fopenmp -fsanitize=thread to work out-of-the-box with gcc. 2012-12-30 Dmitry Vyukov dvyu...@gcc.gnu.org PR libgomp/55561 PR libgomp/40362 * config/linux/wait.h (do_spin): Use atomic load for addr. * config/linux/ptrlock.c (gomp_ptrlock_get_slow): Use atomic for intptr and ptrlock. * onfig/linux/ptrlock.h (gomp_ptrlock_get): Use atomic load for ptrlock. Index: libgomp/config/linux/wait.h === --- libgomp/config/linux/wait.h (revision 194730) +++ libgomp/config/linux/wait.h (working copy) @@ -51,7 +51,7 @@ static inline int do_spin (int *addr, in if (__builtin_expect (gomp_managed_threads gomp_available_cpus, 0)) count = gomp_throttled_spin_count_var; for (i = 0; i count; i++) -if (__builtin_expect (*addr != val, 0)) +if (__builtin_expect (__atomic_load_n (addr, MEMMODEL_RELAXED) != val, 0)) return 0; else cpu_relax (); Index: libgomp/config/linux/ptrlock.c === --- libgomp/config/linux/ptrlock.c (revision 194730) +++ libgomp/config/linux/ptrlock.c (working copy) @@ -50,9 +50,9 @@ gomp_ptrlock_get_slow (gomp_ptrlock_t *p #endif do do_wait (intptr, 2); - while (*intptr == 2); + while (__atomic_load_n (intptr, MEMMODEL_RELAXED) == 2); __asm volatile ( : : : memory); - return *ptrlock; + return (void *) __atomic_load_n (ptrlock, MEMMODEL_ACQUIRE); } void Index: libgomp/config/linux/ptrlock.h === --- libgomp/config/linux/ptrlock.h (revision 194730) +++ libgomp/config/linux/ptrlock.h (working copy) @@ -48,8 +48,9 @@ static inline void *gomp_ptrlock_get (go { uintptr_t oldval; - if ((uintptr_t) *ptrlock 2) -return *ptrlock; + uintptr_t v = (uintptr_t) __atomic_load_n (ptrlock, MEMMODEL_ACQUIRE); + if (v 2) +return (void *) v; oldval = 0; if (__atomic_compare_exchange_n (ptrlock, oldval, 1, false,
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #29 from Dmitry Vyukov dvyukov at google dot com 2013-01-02 09:09:11 UTC --- (In reply to comment #28) (In reply to comment #26) For config/linux/ptrlock the changes are: [...] Following your suggestions, I applied the following patch (mistakes are mine), which allows me to run without warnings from libgomp: Index: config/linux/wait.h === --- config/linux/wait.h (revision 194730) +++ config/linux/wait.h (working copy) @@ -51,7 +51,7 @@ if (__builtin_expect (gomp_managed_threads gomp_available_cpus, 0)) count = gomp_throttled_spin_count_var; for (i = 0; i count; i++) -if (__builtin_expect (*addr != val, 0)) +if (__builtin_expect (__atomic_load_n(addr,MEMMODEL_RELAXED) != val, 0)) return 0; else cpu_relax (); Index: config/linux/ptrlock.c === --- config/linux/ptrlock.c (revision 194730) +++ config/linux/ptrlock.c (working copy) @@ -50,9 +50,9 @@ #endif do do_wait (intptr, 2); - while (*intptr == 2); + while (__atomic_load_n(intptr, MEMMODEL_RELAXED) == 2); __asm volatile ( : : : memory); - return *ptrlock; + return (void*)__atomic_load_n(ptrlock, MEMMODEL_ACQUIRE); } void Index: config/linux/ptrlock.h === --- config/linux/ptrlock.h (revision 194730) +++ config/linux/ptrlock.h (working copy) @@ -48,8 +48,9 @@ { uintptr_t oldval; - if ((uintptr_t) *ptrlock 2) -return *ptrlock; + uintptr_t v = (uintptr_t)__atomic_load_n(ptrlock, MEMMODEL_ACQUIRE); + if (v 2) +return (void*)v; oldval = 0; if (__atomic_compare_exchange_n (ptrlock, oldval, 1, false, Great! Please post the patch to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40362 I believe it is the correct fix for the bug.
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #30 from Jakub Jelinek jakub at gcc dot gnu.org 2013-01-02 09:43:29 UTC --- The formatting in the patch is wrong (multiple issues). I don't see a point in the __atomic_load_n (addr, MEMMODEL_RELAXED), for aligned ints or pointers the loads are atomic on all architectures libgomp is supported on, after all kernel is also using just a normal load in the futex syscall, not __atomic_load_n (which expands to the normal load only anyway).
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #31 from Dmitry Vyukov dvyukov at google dot com 2013-01-02 10:28:00 UTC --- (In reply to comment #30) The formatting in the patch is wrong (multiple issues). I don't see a point in the __atomic_load_n (addr, MEMMODEL_RELAXED), for aligned ints or pointers the loads are atomic on all architectures libgomp is supported on, after all kernel is also using just a normal load in the futex syscall, not __atomic_load_n (which expands to the normal load only anyway). Do you agree about MEMMODEL_ACQUIRE? Regarding MEMMODEL_RELAXED, there are 2 reasons to use it correctness aside. First, it greatly contributes to code readability and self-documentation, and allows readers to easily distinguish between plain loads and inter-thread synchronization shared loads which are hideously different things. Seconds, it allows tools like tsan to work properly on such code and point to more serious issues (like that MEMMODEL_ACQUIRE above). As for correctness, below is an example that I usually provide (and there is also How to miscompile programs with benign data races paper by Boehm with other good examples): - Consider that you have an atomic (which is not actually marked as atomic for compiler) store and some code w/o sync operations around it (potentially from inlined functions): ... *p = x; ... C++ compiler assumes absence of data races. So if it sees a store to p, then it is allowed to use it as a scratch storage for any garbage in the same synchronization region. I.e. it can do: ... *p = foo; ... *p = x; ... Note that it can't affect any correct race-free program. This way, other threads will read random garbage from p. Now imagine that foo is a function pointer: ... *p = foo; // spill from register ... foo = *p; // restore to register if (bar) foo(); // and execute ... *p = x; ... Now imagine that this thread spills ReadFile to p, and another thread spills LaunchNuclearMissle to p in between (but was not intended to execute it due to bar==0). Ooops, this benign race just caused accidental launch of nuclear missiles.
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #28 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2013-01-01 17:13:39 UTC --- (In reply to comment #26) For config/linux/ptrlock the changes are: [...] Following your suggestions, I applied the following patch (mistakes are mine), which allows me to run without warnings from libgomp: Index: config/linux/wait.h === --- config/linux/wait.h (revision 194730) +++ config/linux/wait.h (working copy) @@ -51,7 +51,7 @@ if (__builtin_expect (gomp_managed_threads gomp_available_cpus, 0)) count = gomp_throttled_spin_count_var; for (i = 0; i count; i++) -if (__builtin_expect (*addr != val, 0)) +if (__builtin_expect (__atomic_load_n(addr,MEMMODEL_RELAXED) != val, 0)) return 0; else cpu_relax (); Index: config/linux/ptrlock.c === --- config/linux/ptrlock.c (revision 194730) +++ config/linux/ptrlock.c (working copy) @@ -50,9 +50,9 @@ #endif do do_wait (intptr, 2); - while (*intptr == 2); + while (__atomic_load_n(intptr, MEMMODEL_RELAXED) == 2); __asm volatile ( : : : memory); - return *ptrlock; + return (void*)__atomic_load_n(ptrlock, MEMMODEL_ACQUIRE); } void Index: config/linux/ptrlock.h === --- config/linux/ptrlock.h (revision 194730) +++ config/linux/ptrlock.h (working copy) @@ -48,8 +48,9 @@ { uintptr_t oldval; - if ((uintptr_t) *ptrlock 2) -return *ptrlock; + uintptr_t v = (uintptr_t)__atomic_load_n(ptrlock, MEMMODEL_ACQUIRE); + if (v 2) +return (void*)v; oldval = 0; if (__atomic_compare_exchange_n (ptrlock, oldval, 1, false,
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #22 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2012-12-30 09:03:15 UTC --- (In reply to comment #18) The obvious solution to this seems to be that also the OMP runtime (libgomp) must be compiled with '-fsanitize=thread. If I do that, it appears to work. That's cool, I will try to do some more testing. Good idea! I did do some more testing, and the combination '-fsanitize=thread -fopenmp' was really very useful. Apart from the libgomp-related warning discussed here and PR40362, everything worked well, and I was able to find a couple of correctly identified OMP bugs in our code that would have been (in part) very difficult to find without the tool. I'll also allow us to start an automatic regression tester for our OMP code, which is something we didn't manage so far. I would be great to get this combination to work out-of-the-box.
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #23 from Dmitry Vyukov dvyukov at google dot com 2012-12-30 09:57:44 UTC --- (In reply to comment #22) I did do some more testing, and the combination '-fsanitize=thread -fopenmp' was really very useful. Apart from the libgomp-related warning discussed here and PR40362, everything worked well, and I was able to find a couple of correctly identified OMP bugs in our code that would have been (in part) very difficult to find without the tool. I'll also allow us to start an automatic regression tester for our OMP code, which is something we didn't manage so far. I would be great to get this combination to work out-of-the-box. Wow! Great news! I am not really a gcc hacker. Perhaps Jakub or Dodji can help. It would be interesting to run some OpenMP test suite with tsan to test libgomp better (various schedules and clause types -- section, task, single, etc). Later we may want to instrument libgomp in one way or another to provide better detection and reporting.
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #24 from Dmitry Vyukov dvyukov at google dot com 2012-12-30 10:11:27 UTC --- For testing you can comment out first 2 lines of gomp_ptrlock_get(). That should fix the race in libgomp. It's not a good fix form performance pov, but should be OK for testing.
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #25 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2012-12-30 14:52:51 UTC --- (In reply to comment #24) For testing you can comment out first 2 lines of gomp_ptrlock_get(). That should fix the race in libgomp. It's not a good fix form performance pov, but should be OK for testing. Thanks.. it turns out that gomp_ptrlock_get is actually used from gcc/libgomp/config/linux/ptrlock.h:74 on linux... is it still sufficient to comment the first if condition only and keep the atomic_compare_exchange, or should one directly have the 'return gomp_ptrlock_get_slow' ?
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #26 from Dmitry Vyukov dvyukov at google dot com 2012-12-30 17:07:01 UTC --- (In reply to comment #25) (In reply to comment #24) For testing you can comment out first 2 lines of gomp_ptrlock_get(). That should fix the race in libgomp. It's not a good fix form performance pov, but should be OK for testing. Thanks.. it turns out that gomp_ptrlock_get is actually used from gcc/libgomp/config/linux/ptrlock.h:74 on linux... is it still sufficient to comment the first if condition only and keep the atomic_compare_exchange, or should one directly have the 'return gomp_ptrlock_get_slow' ? Ah, I was looking at config/posix/ptrlock. For config/linux/ptrlock the changes are: if ((uintptr_t) *ptrlock 2) return *ptrlock; \/\/\/\/\/\/\/\/\/\/\/\/ uintptr_t v = (uintptr_t)__atomic_load(ptrlock, MEMMODEL_ACQUIRE); if (v 2) return v; return *ptrlock; \/\/\/\/\/\/\/\/\/\/\/\/ return __atomic_load(ptrlock, MEMMODEL_ACQUIRE); Also loads of intptr needs to be done with __atomic_load(MEMMODEL_RELAXED). and do_spin() needs to load *addr with __atomic_load(MEMMODEL_RELAXED) as well.
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #27 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2012-12-30 19:57:24 UTC --- (In reply to comment #24) For testing you can comment out first 2 lines of gomp_ptrlock_get(). That should fix the race in libgomp. It's not a good fix form performance pov, but should be OK for testing. I found that the routines in config/posix can be used instead of the config/linux by configuring gcc with '--disable-linux-futex' . With your suggestion above, I still get warnings (absent in the linux case) from the following testcase: [vjoost@nanosim-s03 bugs]$ cat test_23.f90 INTEGER :: i,j,OMP_GET_THREAD_NUM !$OMP PARALLEL PRIVATE(i,j) j=OMP_GET_THREAD_NUM() !$OMP DO DO i=1,10 !$OMP CRITICAL(xxx) !$OMP END CRITICAL(xxx) ! !$OMP CRITICAL(yyy) ! !$OMP END CRITICAL(yyy) END DO !$OMP END PARALLEL END [vjoost@nanosim-s03 bugs]$ gfortran -fsanitize=thread -fopenmp -gdwarf-3 -O1 -fPIE -pie test_23.f90 [vjoost@nanosim-s03 bugs]$ export OMP_NUM_THREADS=4 ; ./a.out == WARNING: ThreadSanitizer: data race (pid=29039) Read of size 1 at 0x7d020003d050 by thread 1: #0 pthread_mutex_lock ??:0 (libtsan.so.0+0x0001a863) #1 GOMP_critical_name_start /data/vjoost/gnu/gcc_exp/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/config/posix/mutex.h:44 (libgomp.so.1+0x5e5d) #2 MAIN__._omp_fn.0 /data/vjoost/gnu/bugs/test_23.f90:6 (exe+0x0dcc) #3 gomp_thread_start /data/vjoost/gnu/gcc_exp/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:116 (libgomp.so.1+0xc6b2) Previous write of size 8 at 0x7d020003d050 by main thread: #0 gomp_barrier_wait_end /data/vjoost/gnu/gcc_exp/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/config/posix/bar.c:93 (libgomp.so.1+0xe691) #1 gomp_malloc /data/vjoost/gnu/gcc_exp/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/alloc.c:36 (libgomp.so.1+0x5cba) #2 GOMP_critical_name_start /data/vjoost/gnu/gcc_exp/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/critical.c:71 (libgomp.so.1+0x5e79) #3 MAIN__._omp_fn.0 /data/vjoost/gnu/bugs/test_23.f90:6 (exe+0x0dcc) #4 MAIN__ /data/vjoost/gnu/bugs/test_23.f90:2 (exe+0x0e43) #5 __libc_start_main ??:0 (libc.so.6+0x0037a121ecdc) Location is heap block of size 40 at 0x7d020003d050 allocated by main thread: #0 malloc ??:0 (libtsan.so.0+0x0001839e) #1 gomp_malloc /data/vjoost/gnu/gcc_exp/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/alloc.c:36 (libgomp.so.1+0x5cba) #2 GOMP_critical_name_start /data/vjoost/gnu/gcc_exp/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/critical.c:71 (libgomp.so.1+0x5e79) #3 MAIN__._omp_fn.0 /data/vjoost/gnu/bugs/test_23.f90:6 (exe+0x0dcc) #4 MAIN__ /data/vjoost/gnu/bugs/test_23.f90:2 (exe+0x0e43) #5 __libc_start_main ??:0 (libc.so.6+0x0037a121ecdc) Thread 1 (tid=29040, running) created at: #0 pthread_create ??:0 (libtsan.so.0+0x0001a298) #1 gomp_team_start /data/vjoost/gnu/gcc_exp/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:440 (libgomp.so.1+0xd000) #2 GOMP_parallel_start /data/vjoost/gnu/gcc_exp/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/parallel.c:108 (libgomp.so.1+0xabb7) #3 MAIN__ /data/vjoost/gnu/bugs/test_23.f90:2 (exe+0x0e39) #4 __libc_start_main ??:0 (libc.so.6+0x0037a121ecdc) == ThreadSanitizer: reported 1 warnings
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #18 from Dmitry Vyukov dvyukov at google dot com 2012-12-29 09:32:53 UTC --- On Tue, Dec 25, 2012 at 11:30 PM, Joost.VandeVondele at mat dot ethz.ch gcc-bugzi...@gcc.gnu.org wrote: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #15 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2012-12-25 19:30:15 UTC --- (In reply to comment #13) (In reply to comment #12) That's great that gcc tsan works for Fortran/OpenMP out of the box! I'm afraid it yields false positives. The obvious solution to this seems to be that also the OMP runtime (libgomp) must be compiled with -fsanitize=thread. If I do that, it appears to work. That's cool, I will try to do some more testing. Good idea! It should do for now. It should eliminate all false positives since tsan must understand synchronization in libgomp (pthread, __sync). It can have false negatives, though. E.g. all gomp_iter_dynamic_next() synchronize with each other. A reasonable approach could be to build two versions of libgomp. One standard one, and one sanitized one (libgomp_tsan ?). -fsanitize=thread -fopenmp could link the second version automatically. Just for those trying this out... I used the following to buildinstall a sanitized libgomp (based on Jakub's comments in PR55374 and a hack of mine (-L...)) after an initial normal build cd /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/ make clean make CFLAGS=-std=gnu99 -g -O2 -fsanitize=thread FCFLAGS=-g -O2 -fsanitize=thread LDFLAGS=-L/data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libsanitizer/tsan/.libs/ -B/data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libsanitizer/tsan/.libs/ -Wl,-rpath,/data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libsanitizer/tsan/.libs/ -fsanitize=thread cd /data/vjoost/gnu/gcc_trunk/obj/ make install compilation as gfortran -fopenmp -fsanitize=thread -pie -fPIC test.f90 -- Configure bugmail: http://gcc.gnu.org/bugzilla/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are on the CC list for the bug.
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #19 from Dmitry Vyukov dvyukov at google dot com 2012-12-29 09:38:13 UTC --- On Wed, Dec 26, 2012 at 12:23 AM, Joost.VandeVondele at mat dot ethz.ch gcc-bugzi...@gcc.gnu.org wrote: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #16 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2012-12-25 20:23:07 UTC --- many things appear to work fine, but seemingly parallel do loops with a dynamic schedule generate warnings in libgomp. I also seem to observe that they are not strictly deterministic, sometimes these warnings happen, sometimes not. Testcase: !$OMP PARALLEL PRIVATE(j) j=OMP_GET_THREAD_NUM() ! no warnings without the dynamic schedule !$OMP DO SCHEDULE(DYNAMIC,2) DO i=1,10 ENDDO !$OMP END PARALLEL END Result: vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out == WARNING: ThreadSanitizer: data race (pid=35190) Read of size 8 at 0x7d327290 by main thread: #0 gomp_iter_dynamic_next /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/iter.c:190 (libgomp.so.1+0x6678) #1 GOMP_loop_dynamic_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/loop.c:128 (libgomp.so.1+0x7a03) #2 MAIN__._omp_fn.0 test.f90:0 (exe+0x0d7d) #3 MAIN__ test.f90:0 (exe+0x0ccb) #4 main ??:0 (exe+0x0d1a) Previous write of size 8 at 0x7d327290 by thread 1: #0 gomp_loop_init /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/loop.c:41 (libgomp.so.1+0x7a96) #1 MAIN__._omp_fn.0 test.f90:0 (exe+0x0d7d) #2 gomp_thread_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:116 (libgomp.so.1+0xd012) Location is heap block of size 1568 at 0x7d327100 allocated by main thread: #0 malloc ??:0 (libtsan.so.0+0x0001896e) #1 gomp_malloc /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/alloc.c:36 (libgomp.so.1+0x417a) #2 gomp_new_team /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:145 (libgomp.so.1+0xd27a) #3 GOMP_parallel_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/parallel.c:108 (libgomp.so.1+0xafc7) #4 MAIN__ test.f90:0 (exe+0x0cc1) #5 main ??:0 (exe+0x0d1a) Thread 1 (tid=35191, running) created at: #0 pthread_create ??:0 (libtsan.so.0+0x0001a868) #1 gomp_team_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:440 (libgomp.so.1+0xd908) #2 GOMP_parallel_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/parallel.c:108 (libgomp.so.1+0xafd7) #3 MAIN__ test.f90:0 (exe+0x0cc1) #4 main ??:0 (exe+0x0d1a) Looks like unsafe publication of gomp_work_share data. Can you show disassembly of #2 MAIN__._omp_fn.0 test.f90:0 (exe+0x0d7d) ? How does it choose between calling gomp_loop_init() and GOMP_loop_dynamic_start()? Humm... do omp generated functions (like MAIN__._omp_fn.0) pass through tsan pass? Perhaps it contains some atomic op that tsan does not see.
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #20 from Dmitry Vyukov dvyukov at google dot com 2012-12-29 10:13:00 UTC --- (In reply to comment #19) On Wed, Dec 26, 2012 at 12:23 AM, Joost.VandeVondele at mat dot ethz.ch gcc-bugzi...@gcc.gnu.org wrote: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #16 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2012-12-25 20:23:07 UTC --- many things appear to work fine, but seemingly parallel do loops with a dynamic schedule generate warnings in libgomp. I also seem to observe that they are not strictly deterministic, sometimes these warnings happen, sometimes not. Testcase: !$OMP PARALLEL PRIVATE(j) j=OMP_GET_THREAD_NUM() ! no warnings without the dynamic schedule !$OMP DO SCHEDULE(DYNAMIC,2) DO i=1,10 ENDDO !$OMP END PARALLEL END Result: vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out == WARNING: ThreadSanitizer: data race (pid=35190) Read of size 8 at 0x7d327290 by main thread: #0 gomp_iter_dynamic_next /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/iter.c:190 (libgomp.so.1+0x6678) #1 GOMP_loop_dynamic_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/loop.c:128 (libgomp.so.1+0x7a03) #2 MAIN__._omp_fn.0 test.f90:0 (exe+0x0d7d) #3 MAIN__ test.f90:0 (exe+0x0ccb) #4 main ??:0 (exe+0x0d1a) Previous write of size 8 at 0x7d327290 by thread 1: #0 gomp_loop_init /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/loop.c:41 (libgomp.so.1+0x7a96) #1 MAIN__._omp_fn.0 test.f90:0 (exe+0x0d7d) #2 gomp_thread_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:116 (libgomp.so.1+0xd012) Location is heap block of size 1568 at 0x7d327100 allocated by main thread: #0 malloc ??:0 (libtsan.so.0+0x0001896e) #1 gomp_malloc /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/alloc.c:36 (libgomp.so.1+0x417a) #2 gomp_new_team /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:145 (libgomp.so.1+0xd27a) #3 GOMP_parallel_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/parallel.c:108 (libgomp.so.1+0xafc7) #4 MAIN__ test.f90:0 (exe+0x0cc1) #5 main ??:0 (exe+0x0d1a) Thread 1 (tid=35191, running) created at: #0 pthread_create ??:0 (libtsan.so.0+0x0001a868) #1 gomp_team_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:440 (libgomp.so.1+0xd908) #2 GOMP_parallel_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/parallel.c:108 (libgomp.so.1+0xafd7) #3 MAIN__ test.f90:0 (exe+0x0cc1) #4 main ??:0 (exe+0x0d1a) Looks like unsafe publication of gomp_work_share data. Can you show disassembly of #2 MAIN__._omp_fn.0 test.f90:0 (exe+0x0d7d) ? How does it choose between calling gomp_loop_init() and GOMP_loop_dynamic_start()? Humm... do omp generated functions (like MAIN__._omp_fn.0) pass through tsan pass? Perhaps it contains some atomic op that tsan does not see. Congratulations! We've found racy unsafe publication in libgomp with ThreadSanitizer: gomp_loop_dynamic_start() uses the following functions to synchronize with each other. As you can see gomp_ptrlock_get() contains fast-and-dead unsafe fast-path. libgomp/config/posix/ptrlock.h static inline void *gomp_ptrlock_get (gomp_ptrlock_t *ptrlock) { if (ptrlock-ptr != NULL) return ptrlock-ptr; gomp_mutex_lock (ptrlock-lock); if (ptrlock-ptr != NULL) { gomp_mutex_unlock (ptrlock-lock); return ptrlock-ptr; } return NULL; } static inline void gomp_ptrlock_set (gomp_ptrlock_t *ptrlock, void *ptr) { ptrlock-ptr = ptr; gomp_mutex_unlock (ptrlock-lock); }
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #21 from Dmitry Vyukov dvyukov at google dot com 2012-12-29 10:21:06 UTC --- It is a known issue http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40362#c7 and Jakub said it's safe. I am not that sure. On Sat, Dec 29, 2012 at 2:13 PM, dvyukov at google dot com gcc-bugzi...@gcc.gnu.org wrote: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #20 from Dmitry Vyukov dvyukov at google dot com 2012-12-29 10:13:00 UTC --- (In reply to comment #19) On Wed, Dec 26, 2012 at 12:23 AM, Joost.VandeVondele at mat dot ethz.ch gcc-bugzi...@gcc.gnu.org wrote: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #16 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2012-12-25 20:23:07 UTC --- many things appear to work fine, but seemingly parallel do loops with a dynamic schedule generate warnings in libgomp. I also seem to observe that they are not strictly deterministic, sometimes these warnings happen, sometimes not. Testcase: !$OMP PARALLEL PRIVATE(j) j=OMP_GET_THREAD_NUM() ! no warnings without the dynamic schedule !$OMP DO SCHEDULE(DYNAMIC,2) DO i=1,10 ENDDO !$OMP END PARALLEL END Result: vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out == WARNING: ThreadSanitizer: data race (pid=35190) Read of size 8 at 0x7d327290 by main thread: #0 gomp_iter_dynamic_next /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/iter.c:190 (libgomp.so.1+0x6678) #1 GOMP_loop_dynamic_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/loop.c:128 (libgomp.so.1+0x7a03) #2 MAIN__._omp_fn.0 test.f90:0 (exe+0x0d7d) #3 MAIN__ test.f90:0 (exe+0x0ccb) #4 main ??:0 (exe+0x0d1a) Previous write of size 8 at 0x7d327290 by thread 1: #0 gomp_loop_init /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/loop.c:41 (libgomp.so.1+0x7a96) #1 MAIN__._omp_fn.0 test.f90:0 (exe+0x0d7d) #2 gomp_thread_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:116 (libgomp.so.1+0xd012) Location is heap block of size 1568 at 0x7d327100 allocated by main thread: #0 malloc ??:0 (libtsan.so.0+0x0001896e) #1 gomp_malloc /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/alloc.c:36 (libgomp.so.1+0x417a) #2 gomp_new_team /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:145 (libgomp.so.1+0xd27a) #3 GOMP_parallel_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/parallel.c:108 (libgomp.so.1+0xafc7) #4 MAIN__ test.f90:0 (exe+0x0cc1) #5 main ??:0 (exe+0x0d1a) Thread 1 (tid=35191, running) created at: #0 pthread_create ??:0 (libtsan.so.0+0x0001a868) #1 gomp_team_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:440 (libgomp.so.1+0xd908) #2 GOMP_parallel_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/parallel.c:108 (libgomp.so.1+0xafd7) #3 MAIN__ test.f90:0 (exe+0x0cc1) #4 main ??:0 (exe+0x0d1a) Looks like unsafe publication of gomp_work_share data. Can you show disassembly of #2 MAIN__._omp_fn.0 test.f90:0 (exe+0x0d7d) ? How does it choose between calling gomp_loop_init() and GOMP_loop_dynamic_start()? Humm... do omp generated functions (like MAIN__._omp_fn.0) pass through tsan pass? Perhaps it contains some atomic op that tsan does not see. Congratulations! We've found racy unsafe publication in libgomp with ThreadSanitizer: gomp_loop_dynamic_start() uses the following functions to synchronize with each other. As you can see gomp_ptrlock_get() contains fast-and-dead unsafe fast-path. libgomp/config/posix/ptrlock.h static inline void *gomp_ptrlock_get (gomp_ptrlock_t *ptrlock) { if (ptrlock-ptr != NULL) return ptrlock-ptr; gomp_mutex_lock (ptrlock-lock); if (ptrlock-ptr != NULL) { gomp_mutex_unlock (ptrlock-lock); return ptrlock-ptr; } return NULL; } static inline void gomp_ptrlock_set (gomp_ptrlock_t *ptrlock, void *ptr) { ptrlock-ptr = ptr; gomp_mutex_unlock (ptrlock-lock); }
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #17 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2012-12-26 19:34:29 UTC --- Another testcase that yields warnings with a sanitized libgomp: !$omp parallel default(none) private(i,j,k) !$omp do collapse(3) DO k = 1,10 DO j = 1,10 DO i = 1,10 ENDDO ENDDO ENDDO !$omp end parallel END WARNING: ThreadSanitizer: data race (pid=16133) Read of size 8 at 0x7d3272c8 by main thread: #0 gomp_iter_static_next /data/vjoost/gnu/gcc_exp/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/iter.c:71 (libgomp.so.1+0x623d) #1 GOMP_loop_static_start /data/vjoost/gnu/gcc_exp/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/loop.c:110 (libgomp.so.1+0x78ac) #2 MAIN__._omp_fn.0 /data/vjoost/clean/cp2k/test.f90:2 (exe+0x0c64)
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #15 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2012-12-25 19:30:15 UTC --- (In reply to comment #13) (In reply to comment #12) That's great that gcc tsan works for Fortran/OpenMP out of the box! I'm afraid it yields false positives. The obvious solution to this seems to be that also the OMP runtime (libgomp) must be compiled with -fsanitize=thread. If I do that, it appears to work. That's cool, I will try to do some more testing. A reasonable approach could be to build two versions of libgomp. One standard one, and one sanitized one (libgomp_tsan ?). -fsanitize=thread -fopenmp could link the second version automatically. Just for those trying this out... I used the following to buildinstall a sanitized libgomp (based on Jakub's comments in PR55374 and a hack of mine (-L...)) after an initial normal build cd /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/ make clean make CFLAGS=-std=gnu99 -g -O2 -fsanitize=thread FCFLAGS=-g -O2 -fsanitize=thread LDFLAGS=-L/data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libsanitizer/tsan/.libs/ -B/data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libsanitizer/tsan/.libs/ -Wl,-rpath,/data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libsanitizer/tsan/.libs/ -fsanitize=thread cd /data/vjoost/gnu/gcc_trunk/obj/ make install compilation as gfortran -fopenmp -fsanitize=thread -pie -fPIC test.f90
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 --- Comment #16 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2012-12-25 20:23:07 UTC --- many things appear to work fine, but seemingly parallel do loops with a dynamic schedule generate warnings in libgomp. I also seem to observe that they are not strictly deterministic, sometimes these warnings happen, sometimes not. Testcase: !$OMP PARALLEL PRIVATE(j) j=OMP_GET_THREAD_NUM() ! no warnings without the dynamic schedule !$OMP DO SCHEDULE(DYNAMIC,2) DO i=1,10 ENDDO !$OMP END PARALLEL END Result: vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src ./a.out == WARNING: ThreadSanitizer: data race (pid=35190) Read of size 8 at 0x7d327290 by main thread: #0 gomp_iter_dynamic_next /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/iter.c:190 (libgomp.so.1+0x6678) #1 GOMP_loop_dynamic_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/loop.c:128 (libgomp.so.1+0x7a03) #2 MAIN__._omp_fn.0 test.f90:0 (exe+0x0d7d) #3 MAIN__ test.f90:0 (exe+0x0ccb) #4 main ??:0 (exe+0x0d1a) Previous write of size 8 at 0x7d327290 by thread 1: #0 gomp_loop_init /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/loop.c:41 (libgomp.so.1+0x7a96) #1 MAIN__._omp_fn.0 test.f90:0 (exe+0x0d7d) #2 gomp_thread_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:116 (libgomp.so.1+0xd012) Location is heap block of size 1568 at 0x7d327100 allocated by main thread: #0 malloc ??:0 (libtsan.so.0+0x0001896e) #1 gomp_malloc /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/alloc.c:36 (libgomp.so.1+0x417a) #2 gomp_new_team /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:145 (libgomp.so.1+0xd27a) #3 GOMP_parallel_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/parallel.c:108 (libgomp.so.1+0xafc7) #4 MAIN__ test.f90:0 (exe+0x0cc1) #5 main ??:0 (exe+0x0d1a) Thread 1 (tid=35191, running) created at: #0 pthread_create ??:0 (libtsan.so.0+0x0001a868) #1 gomp_team_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:440 (libgomp.so.1+0xd908) #2 GOMP_parallel_start /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/parallel.c:108 (libgomp.so.1+0xafd7) #3 MAIN__ test.f90:0 (exe+0x0cc1) #4 main ??:0 (exe+0x0d1a) ==
[Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561 Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch changed: What|Removed |Added Summary|TSAN crashes for Fortran|TSAN: Fortran/OMP yields ||false positives --- Comment #14 from Joost VandeVondele Joost.VandeVondele at mat dot ethz.ch 2012-12-11 09:47:43 UTC --- Adjusting the subject, as the crashes have gone (checked also building CP2K with -fsanitize=thread) but the false positives remain.