* [PATCH] Instrument bit field and unaligned accesses for TSAN @ 2014-12-29 23:13 Bernd Edlinger 2015-01-02 19:01 ` Jakub Jelinek 0 siblings, 1 reply; 32+ messages in thread From: Bernd Edlinger @ 2014-12-29 23:13 UTC (permalink / raw) To: Jakub Jelinek; +Cc: gcc-patches [-- Attachment #1: Type: text/plain, Size: 939 bytes --] Hi, I noticed that currently the tsan pass does not instrument bit fileld accesses or unaligned data. Thus some race conditions are not found by the sanitizer. Furthermore the function __tsan_vptr_update is not called with the correct parameters. This patch uses two already existing interfaces for unaligned or bit field accessses, __tsan_read_range and __tsan_write_range, and fixes the parameters of the __tsan_vptr_update function. As a little surprise, the test case g++.dg/tsan/aligned_vs_unaligned_race.C started to fail at -O2 with this patch, but actually that was due to a combination of invalid C code and inverted logic in the test case. So actually that test was failing all the time, because TSAN cannot find the race condition because __tsan_write8 should only be called with aligned addresses. Boot-strapped and reggession tested on x86_64-linux-gnu. OK for trunk? Thanks Bernd. [-- Attachment #2: changelog-tsan-bitfields.txt --] [-- Type: text/plain, Size: 633 bytes --] gcc/ChangeLog: 2014-12-29 Bernd Edlinger <bernd.edlinger@hotmail.de> Instrument bit field and unaligned accesses for TSAN. * sanitizer.def (BUILT_IN_TSAN_READ_RANGE): New built-in function. (BUILT_IN_TSAN_WRITE_RANGE): New built-in function. * tsan.c (instrument_expr): Handle COMPONENT_REF and BIT_FIELD_REF. Use BUILT_IN_TSAN_READ_RANGE and BUILT_IN_TSAN_WRITE_RANGE for unaligned memory regions. Pass "rhs" to BUILT_IN_TSAN_VPTR_UPDATE. testsuite/ChangeLog: 2014-12-29 Bernd Edlinger <bernd.edlinger@hotmail.de> * c-c++-common/tsan/bitfield_race.c: New testcase. * g++.dg/tsan/aligned_vs_unaligned_race.C: Fixed. [-- Attachment #3: patch-tsan-bitfields.diff --] [-- Type: application/octet-stream, Size: 7027 bytes --] Index: gcc/sanitizer.def =================================================================== --- gcc/sanitizer.def (revision 218963) +++ gcc/sanitizer.def (working copy) @@ -188,6 +188,10 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE8, "__tsa BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE16, "__tsan_write16", BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ_RANGE, "__tsan_read_range", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE_RANGE, "__tsan_write_range", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_ATOMIC8_LOAD, "__tsan_atomic8_load", Index: gcc/tsan.c =================================================================== --- gcc/tsan.c (revision 218963) +++ gcc/tsan.c (working copy) @@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-propagate.h" #include "tsan.h" #include "asan.h" +#include "builtins.h" /* Number of instrumented memory accesses in the current function. */ @@ -121,13 +122,12 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex gimple stmt, g; gimple_seq seq; location_t loc; + unsigned int align; size = int_size_in_bytes (TREE_TYPE (expr)); - if (size == -1) + if (size <= 0) return false; - /* For now just avoid instrumenting bit field acceses. - TODO: handle bit-fields as if touching the whole field. */ HOST_WIDE_INT bitsize, bitpos; tree offset; machine_mode mode; @@ -155,17 +155,71 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex && DECL_HARD_REGISTER (base))) return false; - if (size == 0 - || bitpos % (size * BITS_PER_UNIT) - || bitsize != size * BITS_PER_UNIT) - return false; - stmt = gsi_stmt (gsi); loc = gimple_location (stmt); rhs = is_vptr_store (stmt, expr, is_write); - gcc_checking_assert (rhs != NULL || is_gimple_addressable (expr)); - expr_ptr = build_fold_addr_expr (unshare_expr (expr)); seq = NULL; + + if ((TREE_CODE (expr) == COMPONENT_REF + && DECL_BIT_FIELD_TYPE (TREE_OPERAND (expr, 1))) + || TREE_CODE (expr) == BIT_FIELD_REF) + { + base = TREE_OPERAND (expr, 0); + if (TREE_CODE (expr) == COMPONENT_REF) + { + expr = TREE_OPERAND (expr, 1); + if (is_write && DECL_BIT_FIELD_REPRESENTATIVE (expr)) + expr = DECL_BIT_FIELD_REPRESENTATIVE (expr); + if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (expr)) + || !tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (expr)) + || !tree_fits_uhwi_p (DECL_SIZE (expr))) + return false; + bitpos = tree_to_uhwi (DECL_FIELD_OFFSET (expr)) * BITS_PER_UNIT + + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (expr)); + bitsize = tree_to_uhwi (DECL_SIZE (expr)); + } + else + { + if (!tree_fits_uhwi_p (TREE_OPERAND (expr, 2)) + || !tree_fits_uhwi_p (TREE_OPERAND (expr, 1))) + return false; + bitpos = tree_to_uhwi (TREE_OPERAND (expr, 2)); + bitsize = tree_to_uhwi (TREE_OPERAND (expr, 1)); + } + if (bitpos < 0 || bitsize <= 0) + return false; + size = (bitpos % BITS_PER_UNIT + bitsize + BITS_PER_UNIT - 1) + / BITS_PER_UNIT; + align = get_object_alignment (base); + if (align < BITS_PER_UNIT) + return false; + bitpos = bitpos & ~(BITS_PER_UNIT - 1); + if ((align - 1) & bitpos) + { + align = (align - 1) & bitpos; + align = align & -align; + } + gcc_checking_assert (is_gimple_addressable (base)); + expr = build_fold_addr_expr (unshare_expr (base)); + if (!is_gimple_mem_ref_addr (expr)) + { + g = gimple_build_assign (make_ssa_name (TREE_TYPE (expr)), expr); + expr = gimple_assign_lhs (g); + gimple_set_location (g, loc); + gimple_seq_add_stmt_without_update (&seq, g); + } + expr = build2 (MEM_REF, char_type_node, expr, + build_int_cst (TREE_TYPE (expr), bitpos / BITS_PER_UNIT)); + expr_ptr = build_fold_addr_expr (expr); + } + else + { + align = get_object_alignment (expr); + if (align < BITS_PER_UNIT) + return false; + gcc_checking_assert (is_gimple_addressable (expr)); + expr_ptr = build_fold_addr_expr (unshare_expr (expr)); + } if (!is_gimple_val (expr_ptr)) { g = gimple_build_assign (make_ssa_name (TREE_TYPE (expr_ptr)), expr_ptr); @@ -173,13 +227,21 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex gimple_set_location (g, loc); gimple_seq_add_stmt_without_update (&seq, g); } - if (rhs == NULL) + if ((size & -size) != size || size > 16 + || align < MIN (size, 8) * BITS_PER_UNIT) + { + builtin_decl = builtin_decl_implicit (is_write + ? BUILT_IN_TSAN_WRITE_RANGE + : BUILT_IN_TSAN_READ_RANGE); + g = gimple_build_call (builtin_decl, 2, expr_ptr, size_int (size)); + } + else if (rhs == NULL) g = gimple_build_call (get_memory_access_decl (is_write, size), 1, expr_ptr); else { builtin_decl = builtin_decl_implicit (BUILT_IN_TSAN_VPTR_UPDATE); - g = gimple_build_call (builtin_decl, 1, expr_ptr); + g = gimple_build_call (builtin_decl, 2, expr_ptr, unshare_expr (rhs)); } gimple_set_location (g, loc); gimple_seq_add_stmt_without_update (&seq, g); Index: gcc/testsuite/c-c++-common/tsan/bitfield_race.c =================================================================== --- gcc/testsuite/c-c++-common/tsan/bitfield_race.c (revision 0) +++ gcc/testsuite/c-c++-common/tsan/bitfield_race.c (working copy) @@ -0,0 +1,26 @@ +/* { dg-shouldfail "tsan" } */ + +#include <pthread.h> +#include <unistd.h> + +struct bitfield +{ + int a:10; + int b:10; +} Global; + +void *Thread1(void *x) { + sleep(1); + Global.a = 42; + return x; +} + +int main() { + pthread_t t; + pthread_create(&t, 0, Thread1, 0); + Global.b = 43; + pthread_join(t, 0); + return Global.a; +} + +/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ Index: gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C =================================================================== --- gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C (revision 218963) +++ gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C (working copy) @@ -1,3 +1,4 @@ +/* { dg-shouldfail "tsan" } */ #include <pthread.h> #include <stdio.h> #include <stdint.h> @@ -11,8 +12,9 @@ void *Thread1(void *x) { void *Thread2(void *x) { char *p1 = reinterpret_cast<char *>(&Global[0]); - uint64_t *p4 = reinterpret_cast<uint64_t *>(p1 + 1); - (*p4)++; + struct __attribute__((packed, aligned(1))) u_uint64_t { uint64_t val; }; + u_uint64_t *p4 = reinterpret_cast<u_uint64_t *>(p1 + 1); + (*p4).val++; return NULL; } @@ -23,7 +25,7 @@ int main() { pthread_join(t[0], NULL); pthread_join(t[1], NULL); printf("Pass\n"); - /* { dg-prune-output "ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ + /* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ /* { dg-output "Pass.*" } */ return 0; } ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] Instrument bit field and unaligned accesses for TSAN 2014-12-29 23:13 [PATCH] Instrument bit field and unaligned accesses for TSAN Bernd Edlinger @ 2015-01-02 19:01 ` Jakub Jelinek 2015-01-02 21:06 ` Bernd Edlinger 0 siblings, 1 reply; 32+ messages in thread From: Jakub Jelinek @ 2015-01-02 19:01 UTC (permalink / raw) To: Bernd Edlinger; +Cc: gcc-patches On Mon, Dec 29, 2014 at 09:20:57PM +0100, Bernd Edlinger wrote: > --- gcc/sanitizer.def (revision 218963) > +++ gcc/sanitizer.def (working copy) > @@ -188,6 +188,10 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE8, "__tsa > BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) > DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE16, "__tsan_write16", > BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) > +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ_RANGE, "__tsan_read_range", > + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) > +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE_RANGE, "__tsan_write_range", > + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) > > DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_ATOMIC8_LOAD, > "__tsan_atomic8_load", For the BUILT_IN_VPTR_UPDATE builtin you also need to change the prototype, to BT_FN_VOID_PTR_PTR. Do you have a testcase for the __tsan_vptr_update bug? Can you submit it separately, because it probably is desirable also for the 4.9 and 4.8 branches. > @@ -173,13 +227,21 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex > gimple_set_location (g, loc); > gimple_seq_add_stmt_without_update (&seq, g); > } > - if (rhs == NULL) > + if ((size & -size) != size || size > 16 Isn't (size & (size - 1)) == 0 a better check? Otherwise LGTM. Jakub ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PATCH] Instrument bit field and unaligned accesses for TSAN 2015-01-02 19:01 ` Jakub Jelinek @ 2015-01-02 21:06 ` Bernd Edlinger 2015-01-02 21:29 ` Jakub Jelinek 0 siblings, 1 reply; 32+ messages in thread From: Bernd Edlinger @ 2015-01-02 21:06 UTC (permalink / raw) To: Jakub Jelinek; +Cc: gcc-patches [-- Attachment #1: Type: text/plain, Size: 1886 bytes --] On Fri, 2 Jan 2015 20:01:02, Jakub Jelinke wrote: > > On Mon, Dec 29, 2014 at 09:20:57PM +0100, Bernd Edlinger wrote: > >> --- gcc/sanitizer.def (revision 218963) >> +++ gcc/sanitizer.def (working copy) >> @@ -188,6 +188,10 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE8, "__tsa >> BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) >> DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE16, "__tsan_write16", >> BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) >> +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ_RANGE, "__tsan_read_range", >> + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) >> +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE_RANGE, "__tsan_write_range", >> + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) >> >> DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_ATOMIC8_LOAD, >> "__tsan_atomic8_load", > > For the BUILT_IN_VPTR_UPDATE builtin you also need to change > the prototype, to BT_FN_VOID_PTR_PTR. Do you have a testcase for the > __tsan_vptr_update bug? Can you submit it separately, because it > probably is desirable also for the 4.9 and 4.8 branches. > OK, I will do that. I removed the __tsan_vptr_update stuff from the patch, for now. It will probably be difficult for me to find a test case for this, because I am not really sure what __tsan_vptr_update is actually good for, (i.e. the use case). >> @@ -173,13 +227,21 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex >> gimple_set_location (g, loc); >> gimple_seq_add_stmt_without_update (&seq, g); >> } >> - if (rhs == NULL) >> + if ((size & -size) != size || size> 16 > > Isn't (size & (size - 1)) == 0 a better check? > Yes, that's of course better, Thanks. I think I should also change the function type of BUILT_IN_READ_RANGE and BUILT_IN_WRITE_RANGE to BT_FN_VOID_PTR_SIZE? I attached the updated version of the patch. Is that OK too? Thanks Bernd. > Otherwise LGTM. > > Jakub [-- Attachment #2: changelog-tsan-bitfields.txt --] [-- Type: text/plain, Size: 674 bytes --] gcc/ChangeLog: 2015-01-02 Bernd Edlinger <bernd.edlinger@hotmail.de> Instrument bit field and unaligned accesses for TSAN. * asan.c (initialize_sanitizer_builtins): New function type BT_FN_VOID_PTR_SIZE. * sanitizer.def (BUILT_IN_TSAN_READ_RANGE): New built-in function. (BUILT_IN_TSAN_WRITE_RANGE): New built-in function. * tsan.c (instrument_expr): Handle COMPONENT_REF and BIT_FIELD_REF. Use BUILT_IN_TSAN_READ_RANGE and BUILT_IN_TSAN_WRITE_RANGE for unaligned memory regions. testsuite/ChangeLog: 2015-01-02 Bernd Edlinger <bernd.edlinger@hotmail.de> * c-c++-common/tsan/bitfield_race.c: New testcase. * g++.dg/tsan/aligned_vs_unaligned_race.C: Fixed. [-- Attachment #3: patch-tsan-bitfields.diff --] [-- Type: application/octet-stream, Size: 7376 bytes --] Index: gcc/asan.c =================================================================== --- gcc/asan.c (revision 219135) +++ gcc/asan.c (working copy) @@ -2278,6 +2278,9 @@ initialize_sanitizer_builtins (void) = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); tree BT_FN_VOID_CONST_PTR = build_function_type_list (void_type_node, const_ptr_type_node, NULL_TREE); + tree BT_FN_VOID_PTR_SIZE + = build_function_type_list (void_type_node, ptr_type_node, + size_type_node, NULL_TREE); tree BT_FN_VOID_PTR_PTR = build_function_type_list (void_type_node, ptr_type_node, ptr_type_node, NULL_TREE); Index: gcc/sanitizer.def =================================================================== --- gcc/sanitizer.def (revision 219135) +++ gcc/sanitizer.def (working copy) @@ -188,6 +188,10 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE8, "__tsa BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE16, "__tsan_write16", BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ_RANGE, "__tsan_read_range", + BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE_RANGE, "__tsan_write_range", + BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_ATOMIC8_LOAD, "__tsan_atomic8_load", Index: gcc/tsan.c =================================================================== --- gcc/tsan.c (revision 219135) +++ gcc/tsan.c (working copy) @@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-propagate.h" #include "tsan.h" #include "asan.h" +#include "builtins.h" /* Number of instrumented memory accesses in the current function. */ @@ -121,13 +122,12 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex gimple stmt, g; gimple_seq seq; location_t loc; + unsigned int align; size = int_size_in_bytes (TREE_TYPE (expr)); - if (size == -1) + if (size <= 0) return false; - /* For now just avoid instrumenting bit field acceses. - TODO: handle bit-fields as if touching the whole field. */ HOST_WIDE_INT bitsize, bitpos; tree offset; machine_mode mode; @@ -155,17 +155,71 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex && DECL_HARD_REGISTER (base))) return false; - if (size == 0 - || bitpos % (size * BITS_PER_UNIT) - || bitsize != size * BITS_PER_UNIT) - return false; - stmt = gsi_stmt (gsi); loc = gimple_location (stmt); rhs = is_vptr_store (stmt, expr, is_write); - gcc_checking_assert (rhs != NULL || is_gimple_addressable (expr)); - expr_ptr = build_fold_addr_expr (unshare_expr (expr)); seq = NULL; + + if ((TREE_CODE (expr) == COMPONENT_REF + && DECL_BIT_FIELD_TYPE (TREE_OPERAND (expr, 1))) + || TREE_CODE (expr) == BIT_FIELD_REF) + { + base = TREE_OPERAND (expr, 0); + if (TREE_CODE (expr) == COMPONENT_REF) + { + expr = TREE_OPERAND (expr, 1); + if (is_write && DECL_BIT_FIELD_REPRESENTATIVE (expr)) + expr = DECL_BIT_FIELD_REPRESENTATIVE (expr); + if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (expr)) + || !tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (expr)) + || !tree_fits_uhwi_p (DECL_SIZE (expr))) + return false; + bitpos = tree_to_uhwi (DECL_FIELD_OFFSET (expr)) * BITS_PER_UNIT + + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (expr)); + bitsize = tree_to_uhwi (DECL_SIZE (expr)); + } + else + { + if (!tree_fits_uhwi_p (TREE_OPERAND (expr, 2)) + || !tree_fits_uhwi_p (TREE_OPERAND (expr, 1))) + return false; + bitpos = tree_to_uhwi (TREE_OPERAND (expr, 2)); + bitsize = tree_to_uhwi (TREE_OPERAND (expr, 1)); + } + if (bitpos < 0 || bitsize <= 0) + return false; + size = (bitpos % BITS_PER_UNIT + bitsize + BITS_PER_UNIT - 1) + / BITS_PER_UNIT; + align = get_object_alignment (base); + if (align < BITS_PER_UNIT) + return false; + bitpos = bitpos & ~(BITS_PER_UNIT - 1); + if ((align - 1) & bitpos) + { + align = (align - 1) & bitpos; + align = align & -align; + } + gcc_checking_assert (is_gimple_addressable (base)); + expr = build_fold_addr_expr (unshare_expr (base)); + if (!is_gimple_mem_ref_addr (expr)) + { + g = gimple_build_assign (make_ssa_name (TREE_TYPE (expr)), expr); + expr = gimple_assign_lhs (g); + gimple_set_location (g, loc); + gimple_seq_add_stmt_without_update (&seq, g); + } + expr = build2 (MEM_REF, char_type_node, expr, + build_int_cst (TREE_TYPE (expr), bitpos / BITS_PER_UNIT)); + expr_ptr = build_fold_addr_expr (expr); + } + else + { + align = get_object_alignment (expr); + if (align < BITS_PER_UNIT) + return false; + gcc_checking_assert (is_gimple_addressable (expr)); + expr_ptr = build_fold_addr_expr (unshare_expr (expr)); + } if (!is_gimple_val (expr_ptr)) { g = gimple_build_assign (make_ssa_name (TREE_TYPE (expr_ptr)), expr_ptr); @@ -173,7 +227,15 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex gimple_set_location (g, loc); gimple_seq_add_stmt_without_update (&seq, g); } - if (rhs == NULL) + if ((size & (size - 1)) == 0 || size > 16 + || align < MIN (size, 8) * BITS_PER_UNIT) + { + builtin_decl = builtin_decl_implicit (is_write + ? BUILT_IN_TSAN_WRITE_RANGE + : BUILT_IN_TSAN_READ_RANGE); + g = gimple_build_call (builtin_decl, 2, expr_ptr, size_int (size)); + } + else if (rhs == NULL) g = gimple_build_call (get_memory_access_decl (is_write, size), 1, expr_ptr); else Index: gcc/testsuite/c-c++-common/tsan/bitfield_race.c =================================================================== --- gcc/testsuite/c-c++-common/tsan/bitfield_race.c (revision 0) +++ gcc/testsuite/c-c++-common/tsan/bitfield_race.c (working copy) @@ -0,0 +1,26 @@ +/* { dg-shouldfail "tsan" } */ + +#include <pthread.h> +#include <unistd.h> + +struct bitfield +{ + int a:10; + int b:10; +} Global; + +void *Thread1(void *x) { + sleep(1); + Global.a = 42; + return x; +} + +int main() { + pthread_t t; + pthread_create(&t, 0, Thread1, 0); + Global.b = 43; + pthread_join(t, 0); + return Global.a; +} + +/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ Index: gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C =================================================================== --- gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C (revision 219135) +++ gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C (working copy) @@ -1,3 +1,4 @@ +/* { dg-shouldfail "tsan" } */ #include <pthread.h> #include <stdio.h> #include <stdint.h> @@ -11,8 +12,9 @@ void *Thread1(void *x) { void *Thread2(void *x) { char *p1 = reinterpret_cast<char *>(&Global[0]); - uint64_t *p4 = reinterpret_cast<uint64_t *>(p1 + 1); - (*p4)++; + struct __attribute__((packed, aligned(1))) u_uint64_t { uint64_t val; }; + u_uint64_t *p4 = reinterpret_cast<u_uint64_t *>(p1 + 1); + (*p4).val++; return NULL; } @@ -23,7 +25,7 @@ int main() { pthread_join(t[0], NULL); pthread_join(t[1], NULL); printf("Pass\n"); - /* { dg-prune-output "ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ + /* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ /* { dg-output "Pass.*" } */ return 0; } ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] Instrument bit field and unaligned accesses for TSAN 2015-01-02 21:06 ` Bernd Edlinger @ 2015-01-02 21:29 ` Jakub Jelinek 2015-01-02 22:02 ` Bernd Edlinger 0 siblings, 1 reply; 32+ messages in thread From: Jakub Jelinek @ 2015-01-02 21:29 UTC (permalink / raw) To: Bernd Edlinger, Dmitry Vyukov; +Cc: gcc-patches On Fri, Jan 02, 2015 at 10:06:29PM +0100, Bernd Edlinger wrote: > OK, I will do that. > I removed the __tsan_vptr_update stuff from the patch, for now. Guess we should ask Dmitry about that. > It will probably be difficult for me to find a test case for this, > because I am not really sure what __tsan_vptr_update is actually good for, > (i.e. the use case). > I think I should also change the function type of BUILT_IN_READ_RANGE > and BUILT_IN_WRITE_RANGE to BT_FN_VOID_PTR_SIZE? You should use BT_FN_VOID_PTR_PTRMODE for those instead, and you don't need to initialize it in asan.c - it is already initialized there. size_t might be a different integer type from uptr. Jakub ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PATCH] Instrument bit field and unaligned accesses for TSAN 2015-01-02 21:29 ` Jakub Jelinek @ 2015-01-02 22:02 ` Bernd Edlinger 2015-01-02 22:11 ` Jakub Jelinek 2015-01-04 13:55 ` [PATCH] Fix parameters of __tsan_vptr_update Bernd Edlinger 0 siblings, 2 replies; 32+ messages in thread From: Bernd Edlinger @ 2015-01-02 22:02 UTC (permalink / raw) To: Jakub Jelinek, Dmitry Vyukov; +Cc: gcc-patches [-- Attachment #1: Type: text/plain, Size: 1362 bytes --] Hi, On Fri, 2 Jan 2015 22:29:01, Jakub Jelinek wrote: > > On Fri, Jan 02, 2015 at 10:06:29PM +0100, Bernd Edlinger wrote: >> OK, I will do that. >> I removed the __tsan_vptr_update stuff from the patch, for now. > > Guess we should ask Dmitry about that. > >> It will probably be difficult for me to find a test case for this, >> because I am not really sure what __tsan_vptr_update is actually good for, >> (i.e. the use case). > >> I think I should also change the function type of BUILT_IN_READ_RANGE >> and BUILT_IN_WRITE_RANGE to BT_FN_VOID_PTR_SIZE? > > You should use BT_FN_VOID_PTR_PTRMODE for those instead, and you don't need to > initialize it in asan.c - it is already initialized there. > size_t might be a different integer type from uptr. > > Jakub Dmitry, while I wrote this patch, I became aware of a minor flaw in GCC's instrumentation of __tsan_vptr_update. That is, currently we pass only the address of the vptr that is about to be written to this function, but the second parameter, the value that will be written, is always garbage. Jakub asked for a test case, but I am not sure about what is the use case, where this would make a difference. Can you shed some light on this? Thanks. Jakub, I changed the function type to BT_FN_VOID_PTR_PTRMODE, is the patch OK now? Thanks Bernd. [-- Attachment #2: changelog-tsan-bitfields.txt --] [-- Type: text/plain, Size: 591 bytes --] gcc/ChangeLog: 2015-01-02 Bernd Edlinger <bernd.edlinger@hotmail.de> Instrument bit field and unaligned accesses for TSAN. * sanitizer.def (BUILT_IN_TSAN_READ_RANGE): New built-in function. (BUILT_IN_TSAN_WRITE_RANGE): New built-in function. * tsan.c (instrument_expr): Handle COMPONENT_REF and BIT_FIELD_REF. Use BUILT_IN_TSAN_READ_RANGE and BUILT_IN_TSAN_WRITE_RANGE for unaligned memory regions. testsuite/ChangeLog: 2015-01-02 Bernd Edlinger <bernd.edlinger@hotmail.de> * c-c++-common/tsan/bitfield_race.c: New testcase. * g++.dg/tsan/aligned_vs_unaligned_race.C: Fixed. [-- Attachment #3: patch-tsan-bitfields.diff --] [-- Type: application/octet-stream, Size: 6739 bytes --] Index: gcc/sanitizer.def =================================================================== --- gcc/sanitizer.def (revision 219148) +++ gcc/sanitizer.def (working copy) @@ -188,6 +188,10 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE8, "__tsa BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE16, "__tsan_write16", BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ_RANGE, "__tsan_read_range", + BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE_RANGE, "__tsan_write_range", + BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_ATOMIC8_LOAD, "__tsan_atomic8_load", Index: gcc/tsan.c =================================================================== --- gcc/tsan.c (revision 219148) +++ gcc/tsan.c (working copy) @@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-propagate.h" #include "tsan.h" #include "asan.h" +#include "builtins.h" /* Number of instrumented memory accesses in the current function. */ @@ -121,13 +122,12 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex gimple stmt, g; gimple_seq seq; location_t loc; + unsigned int align; size = int_size_in_bytes (TREE_TYPE (expr)); - if (size == -1) + if (size <= 0) return false; - /* For now just avoid instrumenting bit field acceses. - TODO: handle bit-fields as if touching the whole field. */ HOST_WIDE_INT bitsize, bitpos; tree offset; machine_mode mode; @@ -155,17 +155,71 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex && DECL_HARD_REGISTER (base))) return false; - if (size == 0 - || bitpos % (size * BITS_PER_UNIT) - || bitsize != size * BITS_PER_UNIT) - return false; - stmt = gsi_stmt (gsi); loc = gimple_location (stmt); rhs = is_vptr_store (stmt, expr, is_write); - gcc_checking_assert (rhs != NULL || is_gimple_addressable (expr)); - expr_ptr = build_fold_addr_expr (unshare_expr (expr)); seq = NULL; + + if ((TREE_CODE (expr) == COMPONENT_REF + && DECL_BIT_FIELD_TYPE (TREE_OPERAND (expr, 1))) + || TREE_CODE (expr) == BIT_FIELD_REF) + { + base = TREE_OPERAND (expr, 0); + if (TREE_CODE (expr) == COMPONENT_REF) + { + expr = TREE_OPERAND (expr, 1); + if (is_write && DECL_BIT_FIELD_REPRESENTATIVE (expr)) + expr = DECL_BIT_FIELD_REPRESENTATIVE (expr); + if (!tree_fits_uhwi_p (DECL_FIELD_OFFSET (expr)) + || !tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (expr)) + || !tree_fits_uhwi_p (DECL_SIZE (expr))) + return false; + bitpos = tree_to_uhwi (DECL_FIELD_OFFSET (expr)) * BITS_PER_UNIT + + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (expr)); + bitsize = tree_to_uhwi (DECL_SIZE (expr)); + } + else + { + if (!tree_fits_uhwi_p (TREE_OPERAND (expr, 2)) + || !tree_fits_uhwi_p (TREE_OPERAND (expr, 1))) + return false; + bitpos = tree_to_uhwi (TREE_OPERAND (expr, 2)); + bitsize = tree_to_uhwi (TREE_OPERAND (expr, 1)); + } + if (bitpos < 0 || bitsize <= 0) + return false; + size = (bitpos % BITS_PER_UNIT + bitsize + BITS_PER_UNIT - 1) + / BITS_PER_UNIT; + align = get_object_alignment (base); + if (align < BITS_PER_UNIT) + return false; + bitpos = bitpos & ~(BITS_PER_UNIT - 1); + if ((align - 1) & bitpos) + { + align = (align - 1) & bitpos; + align = align & -align; + } + gcc_checking_assert (is_gimple_addressable (base)); + expr = build_fold_addr_expr (unshare_expr (base)); + if (!is_gimple_mem_ref_addr (expr)) + { + g = gimple_build_assign (make_ssa_name (TREE_TYPE (expr)), expr); + expr = gimple_assign_lhs (g); + gimple_set_location (g, loc); + gimple_seq_add_stmt_without_update (&seq, g); + } + expr = build2 (MEM_REF, char_type_node, expr, + build_int_cst (TREE_TYPE (expr), bitpos / BITS_PER_UNIT)); + expr_ptr = build_fold_addr_expr (expr); + } + else + { + align = get_object_alignment (expr); + if (align < BITS_PER_UNIT) + return false; + gcc_checking_assert (is_gimple_addressable (expr)); + expr_ptr = build_fold_addr_expr (unshare_expr (expr)); + } if (!is_gimple_val (expr_ptr)) { g = gimple_build_assign (make_ssa_name (TREE_TYPE (expr_ptr)), expr_ptr); @@ -173,7 +227,15 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex gimple_set_location (g, loc); gimple_seq_add_stmt_without_update (&seq, g); } - if (rhs == NULL) + if ((size & (size - 1)) == 0 || size > 16 + || align < MIN (size, 8) * BITS_PER_UNIT) + { + builtin_decl = builtin_decl_implicit (is_write + ? BUILT_IN_TSAN_WRITE_RANGE + : BUILT_IN_TSAN_READ_RANGE); + g = gimple_build_call (builtin_decl, 2, expr_ptr, size_int (size)); + } + else if (rhs == NULL) g = gimple_build_call (get_memory_access_decl (is_write, size), 1, expr_ptr); else Index: gcc/testsuite/c-c++-common/tsan/bitfield_race.c =================================================================== --- gcc/testsuite/c-c++-common/tsan/bitfield_race.c (revision 0) +++ gcc/testsuite/c-c++-common/tsan/bitfield_race.c (working copy) @@ -0,0 +1,26 @@ +/* { dg-shouldfail "tsan" } */ + +#include <pthread.h> +#include <unistd.h> + +struct bitfield +{ + int a:10; + int b:10; +} Global; + +void *Thread1(void *x) { + sleep(1); + Global.a = 42; + return x; +} + +int main() { + pthread_t t; + pthread_create(&t, 0, Thread1, 0); + Global.b = 43; + pthread_join(t, 0); + return Global.a; +} + +/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ Index: gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C =================================================================== --- gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C (revision 219148) +++ gcc/testsuite/g++.dg/tsan/aligned_vs_unaligned_race.C (working copy) @@ -1,3 +1,4 @@ +/* { dg-shouldfail "tsan" } */ #include <pthread.h> #include <stdio.h> #include <stdint.h> @@ -11,8 +12,9 @@ void *Thread1(void *x) { void *Thread2(void *x) { char *p1 = reinterpret_cast<char *>(&Global[0]); - uint64_t *p4 = reinterpret_cast<uint64_t *>(p1 + 1); - (*p4)++; + struct __attribute__((packed, aligned(1))) u_uint64_t { uint64_t val; }; + u_uint64_t *p4 = reinterpret_cast<u_uint64_t *>(p1 + 1); + (*p4).val++; return NULL; } @@ -23,7 +25,7 @@ int main() { pthread_join(t[0], NULL); pthread_join(t[1], NULL); printf("Pass\n"); - /* { dg-prune-output "ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ + /* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ /* { dg-output "Pass.*" } */ return 0; } ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] Instrument bit field and unaligned accesses for TSAN 2015-01-02 22:02 ` Bernd Edlinger @ 2015-01-02 22:11 ` Jakub Jelinek 2015-01-14 16:58 ` Dmitry Vyukov 2015-01-04 13:55 ` [PATCH] Fix parameters of __tsan_vptr_update Bernd Edlinger 1 sibling, 1 reply; 32+ messages in thread From: Jakub Jelinek @ 2015-01-02 22:11 UTC (permalink / raw) To: Bernd Edlinger; +Cc: Dmitry Vyukov, gcc-patches On Fri, Jan 02, 2015 at 11:01:56PM +0100, Bernd Edlinger wrote: > gcc/ChangeLog: > 2015-01-02 Bernd Edlinger <bernd.edlinger@hotmail.de> > > Instrument bit field and unaligned accesses for TSAN. > * sanitizer.def (BUILT_IN_TSAN_READ_RANGE): New built-in function. > (BUILT_IN_TSAN_WRITE_RANGE): New built-in function. > * tsan.c (instrument_expr): Handle COMPONENT_REF and BIT_FIELD_REF. > Use BUILT_IN_TSAN_READ_RANGE and BUILT_IN_TSAN_WRITE_RANGE for > unaligned memory regions. > > testsuite/ChangeLog: > 2015-01-02 Bernd Edlinger <bernd.edlinger@hotmail.de> > > * c-c++-common/tsan/bitfield_race.c: New testcase. > * g++.dg/tsan/aligned_vs_unaligned_race.C: Fixed. Ok for trunk. Jakub ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] Instrument bit field and unaligned accesses for TSAN 2015-01-02 22:11 ` Jakub Jelinek @ 2015-01-14 16:58 ` Dmitry Vyukov 0 siblings, 0 replies; 32+ messages in thread From: Dmitry Vyukov @ 2015-01-14 16:58 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Bernd Edlinger, gcc-patches Cool! Thanks. Gcc is again ahead of clang :) On Sat, Jan 3, 2015 at 1:11 AM, Jakub Jelinek <jakub@redhat.com> wrote: > On Fri, Jan 02, 2015 at 11:01:56PM +0100, Bernd Edlinger wrote: >> gcc/ChangeLog: >> 2015-01-02 Bernd Edlinger <bernd.edlinger@hotmail.de> >> >> Instrument bit field and unaligned accesses for TSAN. >> * sanitizer.def (BUILT_IN_TSAN_READ_RANGE): New built-in function. >> (BUILT_IN_TSAN_WRITE_RANGE): New built-in function. >> * tsan.c (instrument_expr): Handle COMPONENT_REF and BIT_FIELD_REF. >> Use BUILT_IN_TSAN_READ_RANGE and BUILT_IN_TSAN_WRITE_RANGE for >> unaligned memory regions. >> >> testsuite/ChangeLog: >> 2015-01-02 Bernd Edlinger <bernd.edlinger@hotmail.de> >> >> * c-c++-common/tsan/bitfield_race.c: New testcase. >> * g++.dg/tsan/aligned_vs_unaligned_race.C: Fixed. > > Ok for trunk. > > Jakub ^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH] Fix parameters of __tsan_vptr_update 2015-01-02 22:02 ` Bernd Edlinger 2015-01-02 22:11 ` Jakub Jelinek @ 2015-01-04 13:55 ` Bernd Edlinger 2015-01-11 13:38 ` Bernd Edlinger 1 sibling, 1 reply; 32+ messages in thread From: Bernd Edlinger @ 2015-01-04 13:55 UTC (permalink / raw) To: Jakub Jelinek, Dmitry Vyukov; +Cc: gcc-patches [-- Attachment #1: Type: text/plain, Size: 819 bytes --] Hi Jakub, I think I have found a reasonable test case, see the attached patch file. The use case is: a class that destroys an owned thread in the destructor. The destructor sets the vptr again to thread::vptr but this should _not_ trigger a diagnostic message, when the vptr does not really change. Jakub, this is another test case where the TREE_READONLY prevents the tsan instrumentation. So I had first to install your patch: https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01432.html ... to see the test case fail without my patch. The patch installs cleanly on 4.9 and 4.8, however the 4.8 branch has no tsan tests, so I would leave the test case away for 4.8. Boot-strapped and regression-tested on x86_64-linux-gnu OK for trunk and 4.9 + 4.8 branches? Thanks Bernd. [-- Attachment #2: changelog-tsan-vptr.txt --] [-- Type: text/plain, Size: 330 bytes --] gcc/ChangeLog: 2015-01-04 Bernd Edlinger <bernd.edlinger@hotmail.de> * sanititer.c (BUILT_IN_TSAN_VPTR_UPDATE): Fixed parameters. * tsan.c (instrument_expr): Fixed parameters of __tsan_vptr_update. gcc/testsuite/ChangeLog 2015-01-04 Bernd Edlinger <bernd.edlinger@hotmail.de> * g++.dg/tsan/vptr_update.C: New testcase. [-- Attachment #3: patch-tsan-vptr.diff --] [-- Type: application/octet-stream, Size: 1936 bytes --] Index: gcc/sanitizer.def =================================================================== --- gcc/sanitizer.def (revision 219160) +++ gcc/sanitizer.def (working copy) @@ -167,7 +167,7 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_FUNC_ENTRY, "_ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_FUNC_EXIT, "__tsan_func_exit", BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VPTR_UPDATE, "__tsan_vptr_update", - BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) + BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ1, "__tsan_read1", BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ2, "__tsan_read2", Index: gcc/tsan.c =================================================================== --- gcc/tsan.c (revision 219160) +++ gcc/tsan.c (working copy) @@ -241,7 +241,7 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex else { builtin_decl = builtin_decl_implicit (BUILT_IN_TSAN_VPTR_UPDATE); - g = gimple_build_call (builtin_decl, 1, expr_ptr); + g = gimple_build_call (builtin_decl, 2, expr_ptr, unshare_expr (rhs)); } gimple_set_location (g, loc); gimple_seq_add_stmt_without_update (&seq, g); Index: gcc/testsuite/g++.dg/tsan/vptr_update.C =================================================================== --- gcc/testsuite/g++.dg/tsan/vptr_update.C (revision 0) +++ gcc/testsuite/g++.dg/tsan/vptr_update.C (working copy) @@ -0,0 +1,39 @@ +#include <pthread.h> + +class thread +{ +public: + thread () + { + count = 0; + pthread_create (&th, 0, tf, this); + } + + virtual ~thread () + { + pthread_join (th, 0); + } + + virtual void tick () + { + count++; + } + +private: + pthread_t th; + int count; + + static void* tf(void* arg) + { + thread* t = (thread*) arg; + t->tick(); + return 0; + } +}; + +int +main () +{ + thread *t = new thread; + delete t; +} ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PATCH] Fix parameters of __tsan_vptr_update 2015-01-04 13:55 ` [PATCH] Fix parameters of __tsan_vptr_update Bernd Edlinger @ 2015-01-11 13:38 ` Bernd Edlinger 2015-01-14 15:09 ` Dmitry Vyukov 2015-01-16 8:34 ` [PING] " Bernd Edlinger 0 siblings, 2 replies; 32+ messages in thread From: Bernd Edlinger @ 2015-01-11 13:38 UTC (permalink / raw) To: Jakub Jelinek, Dmitry Vyukov, Richard Biener; +Cc: gcc-patches [-- Attachment #1: Type: text/plain, Size: 1421 bytes --] Hi, On Sun, 4 Jan 2015 14:54:56, Bernd Edlinger wrote: > > Hi Jakub, > > > I think I have found a reasonable test case, see the attached patch file. > The use case is: a class that destroys an owned thread in the destructor. > The destructor sets the vptr again to thread::vptr but this should > _not_ trigger a diagnostic message, when the vptr does not really change. > > Jakub, this is another test case where the TREE_READONLY prevents > the tsan instrumentation. So I had first to install your patch: > > https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01432.html > > ... to see the test case fail without my patch. > that has been installed in the meantime. > The patch installs cleanly on 4.9 and 4.8, however the 4.8 branch > has no tsan tests, so I would leave the test case away for 4.8. > I found, 4.8 does not have BT_FN_VOID_PTR_PTR, and no tsan tests at all, so it is probably not worth the effort. > Boot-strapped and regression-tested on x86_64-linux-gnu > OK for trunk and 4.9 + 4.8 branches? > > > Thanks > Bernd. > > I found some test cases in the clang tree, about the __tsan_vptr_update. So I thought I should use these instead of inventing new ones. Attached you'll find an updated patch with one positive and one negative test for vptr races. Tested with x86_64-linux-gnu. OK for trunk and 4.9 after a while? Thanks Bernd. [-- Attachment #2: changelog-tsan-vptr.txt --] [-- Type: text/plain, Size: 385 bytes --] gcc/ChangeLog: 2015-01-11 Bernd Edlinger <bernd.edlinger@hotmail.de> * sanititer.c (BUILT_IN_TSAN_VPTR_UPDATE): Fixed parameters. * tsan.c (instrument_expr): Fixed parameters of __tsan_vptr_update. gcc/testsuite/ChangeLog 2015-01-11 Bernd Edlinger <bernd.edlinger@hotmail.de> * g++.dg/tsan/vptr_benign_race.C: New testcase. * g++.dg/tsan/vptr_harmful_race.C: New testcase. [-- Attachment #3: patch-tsan-vptr.diff --] [-- Type: application/octet-stream, Size: 3562 bytes --] Index: gcc/sanitizer.def =================================================================== --- gcc/sanitizer.def (revision 219160) +++ gcc/sanitizer.def (working copy) @@ -167,7 +167,7 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_FUNC_ENTRY, "_ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_FUNC_EXIT, "__tsan_func_exit", BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VPTR_UPDATE, "__tsan_vptr_update", - BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) + BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ1, "__tsan_read1", BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ2, "__tsan_read2", Index: gcc/tsan.c =================================================================== --- gcc/tsan.c (revision 219160) +++ gcc/tsan.c (working copy) @@ -241,7 +241,7 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex else { builtin_decl = builtin_decl_implicit (BUILT_IN_TSAN_VPTR_UPDATE); - g = gimple_build_call (builtin_decl, 1, expr_ptr); + g = gimple_build_call (builtin_decl, 2, expr_ptr, unshare_expr (rhs)); } gimple_set_location (g, loc); gimple_seq_add_stmt_without_update (&seq, g); Index: gcc/testsuite/g++.dg/tsan/vptr_benign_race.C =================================================================== --- gcc/testsuite/g++.dg/tsan/vptr_benign_race.C (revision 0) +++ gcc/testsuite/g++.dg/tsan/vptr_benign_race.C (working copy) @@ -0,0 +1,49 @@ +#include <pthread.h> +#include <semaphore.h> +#include <stdio.h> + +struct A { + A() { + sem_init(&sem_, 0, 0); + } + virtual void F() { + } + void Done() { + sem_post(&sem_); + } + virtual ~A() { + } + sem_t sem_; +}; + +struct B : A { + virtual void F() { + } + virtual ~B() { + sem_wait(&sem_); + sem_destroy(&sem_); + } +}; + +static A *obj = new B; + +void *Thread1(void *x) { + obj->F(); + obj->Done(); + return NULL; +} + +void *Thread2(void *x) { + delete obj; + return NULL; +} + +int main() { + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + fprintf(stderr, "PASS\n"); +} +/* { dg-output "PASS.*" } */ Index: gcc/testsuite/g++.dg/tsan/vptr_harmful_race.C =================================================================== --- gcc/testsuite/g++.dg/tsan/vptr_harmful_race.C (revision 0) +++ gcc/testsuite/g++.dg/tsan/vptr_harmful_race.C (working copy) @@ -0,0 +1,58 @@ +/* { dg-shouldfail "tsan" } */ +/* { dg-additional-options "-ldl" } */ + +#include <pthread.h> +#include <semaphore.h> +#include <stdio.h> +#include <unistd.h> +#include "tsan_barrier.h" + +static pthread_barrier_t barrier; + +struct A { + A() { + sem_init(&sem_, 0, 0); + } + virtual void F() { + } + void Done() { + sem_post(&sem_); + } + virtual ~A() { + sem_wait(&sem_); + sem_destroy(&sem_); + } + sem_t sem_; +}; + +struct B : A { + virtual void F() { + } + virtual ~B() { } +}; + +static A *obj = new B; + +void *Thread1(void *x) { + obj->F(); + obj->Done(); + barrier_wait(&barrier); + return NULL; +} + +void *Thread2(void *x) { + barrier_wait(&barrier); + delete obj; + return NULL; +} + +int main() { + barrier_init(&barrier, 2); + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); +} + +/* { dg-output "WARNING: ThreadSanitizer: data race on vptr.*(\n|\r\n|\r)" } */ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH] Fix parameters of __tsan_vptr_update 2015-01-11 13:38 ` Bernd Edlinger @ 2015-01-14 15:09 ` Dmitry Vyukov 2015-01-16 8:34 ` [PING] " Bernd Edlinger 1 sibling, 0 replies; 32+ messages in thread From: Dmitry Vyukov @ 2015-01-14 15:09 UTC (permalink / raw) To: Bernd Edlinger; +Cc: Jakub Jelinek, Richard Biener, gcc-patches Hi, Sorry for the delay, I was on a vacation. Is here anything to do/review for me? On Sun, Jan 11, 2015 at 4:15 PM, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote: > Hi, > > > > On Sun, 4 Jan 2015 14:54:56, Bernd Edlinger wrote: >> >> Hi Jakub, >> >> >> I think I have found a reasonable test case, see the attached patch file. >> The use case is: a class that destroys an owned thread in the destructor. >> The destructor sets the vptr again to thread::vptr but this should >> _not_ trigger a diagnostic message, when the vptr does not really change. >> >> Jakub, this is another test case where the TREE_READONLY prevents >> the tsan instrumentation. So I had first to install your patch: >> >> https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01432.html >> >> ... to see the test case fail without my patch. >> > > that has been installed in the meantime. > >> The patch installs cleanly on 4.9 and 4.8, however the 4.8 branch >> has no tsan tests, so I would leave the test case away for 4.8. >> > > I found, 4.8 does not have BT_FN_VOID_PTR_PTR, and no tsan tests > at all, so it is probably not worth the effort. > >> Boot-strapped and regression-tested on x86_64-linux-gnu >> OK for trunk and 4.9 + 4.8 branches? >> >> >> Thanks >> Bernd. >> >> > > I found some test cases in the clang tree, about the __tsan_vptr_update. > So I thought I should use these instead of inventing new ones. > > Attached you'll find an updated patch with one positive and one negative > test for vptr races. > > Tested with x86_64-linux-gnu. > OK for trunk and 4.9 after a while? > > > Thanks > Bernd. > ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-11 13:38 ` Bernd Edlinger 2015-01-14 15:09 ` Dmitry Vyukov @ 2015-01-16 8:34 ` Bernd Edlinger 2015-01-16 17:20 ` Jeff Law 2015-01-16 17:32 ` Dmitry Vyukov 1 sibling, 2 replies; 32+ messages in thread From: Bernd Edlinger @ 2015-01-16 8:34 UTC (permalink / raw) To: Jakub Jelinek, Dmitry Vyukov, Richard Biener; +Cc: gcc-patches Hi, I think I should ping for this patch now: https://gcc.gnu.org/ml/gcc-patches/2015-01/msg00599.html note that by mistake the change log referenced sanitizer.c instead of sanitizer.def, consider that fixed on my local copy. Thanks Bernd. > Date: Sun, 11 Jan 2015 14:15:54 +0100 > > Hi, > > > > On Sun, 4 Jan 2015 14:54:56, Bernd Edlinger wrote: >> >> Hi Jakub, >> >> >> I think I have found a reasonable test case, see the attached patch file. >> The use case is: a class that destroys an owned thread in the destructor. >> The destructor sets the vptr again to thread::vptr but this should >> _not_ trigger a diagnostic message, when the vptr does not really change. >> >> Jakub, this is another test case where the TREE_READONLY prevents >> the tsan instrumentation. So I had first to install your patch: >> >> https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01432.html >> >> ... to see the test case fail without my patch. >> > > that has been installed in the meantime. > >> The patch installs cleanly on 4.9 and 4.8, however the 4.8 branch >> has no tsan tests, so I would leave the test case away for 4.8. >> > > I found, 4.8 does not have BT_FN_VOID_PTR_PTR, and no tsan tests > at all, so it is probably not worth the effort. > >> Boot-strapped and regression-tested on x86_64-linux-gnu >> OK for trunk and 4.9 + 4.8 branches? >> >> >> Thanks >> Bernd. >> >> > > I found some test cases in the clang tree, about the __tsan_vptr_update. > So I thought I should use these instead of inventing new ones. > > Attached you'll find an updated patch with one positive and one negative > test for vptr races. > > Tested with x86_64-linux-gnu. > OK for trunk and 4.9 after a while? > > > Thanks > Bernd. > ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-16 8:34 ` [PING] " Bernd Edlinger @ 2015-01-16 17:20 ` Jeff Law 2015-01-16 17:32 ` Dmitry Vyukov 1 sibling, 0 replies; 32+ messages in thread From: Jeff Law @ 2015-01-16 17:20 UTC (permalink / raw) To: Bernd Edlinger, Jakub Jelinek, Dmitry Vyukov, Richard Biener; +Cc: gcc-patches On 01/16/15 00:17, Bernd Edlinger wrote: > Hi, > > > I think I should ping for this patch now: > https://gcc.gnu.org/ml/gcc-patches/2015-01/msg00599.html > > note that by mistake the change log referenced sanitizer.c instead of > sanitizer.def, consider that fixed on my local copy. That patch is fine. Thanks for pinging. jeff ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-16 8:34 ` [PING] " Bernd Edlinger 2015-01-16 17:20 ` Jeff Law @ 2015-01-16 17:32 ` Dmitry Vyukov 2015-01-16 17:52 ` Bernd Edlinger 1 sibling, 1 reply; 32+ messages in thread From: Dmitry Vyukov @ 2015-01-16 17:32 UTC (permalink / raw) To: Bernd Edlinger; +Cc: Jakub Jelinek, Richard Biener, gcc-patches This is just a copy from llvm repo, right? Looks good to me. On Fri, Jan 16, 2015 at 10:17 AM, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote: > Hi, > > > I think I should ping for this patch now: > https://gcc.gnu.org/ml/gcc-patches/2015-01/msg00599.html > > note that by mistake the change log referenced sanitizer.c instead of > sanitizer.def, consider that fixed on my local copy. > > > Thanks > Bernd. > > >> Date: Sun, 11 Jan 2015 14:15:54 +0100 >> >> Hi, >> >> >> >> On Sun, 4 Jan 2015 14:54:56, Bernd Edlinger wrote: >>> >>> Hi Jakub, >>> >>> >>> I think I have found a reasonable test case, see the attached patch file. >>> The use case is: a class that destroys an owned thread in the destructor. >>> The destructor sets the vptr again to thread::vptr but this should >>> _not_ trigger a diagnostic message, when the vptr does not really change. >>> >>> Jakub, this is another test case where the TREE_READONLY prevents >>> the tsan instrumentation. So I had first to install your patch: >>> >>> https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01432.html >>> >>> ... to see the test case fail without my patch. >>> >> >> that has been installed in the meantime. >> >>> The patch installs cleanly on 4.9 and 4.8, however the 4.8 branch >>> has no tsan tests, so I would leave the test case away for 4.8. >>> >> >> I found, 4.8 does not have BT_FN_VOID_PTR_PTR, and no tsan tests >> at all, so it is probably not worth the effort. >> >>> Boot-strapped and regression-tested on x86_64-linux-gnu >>> OK for trunk and 4.9 + 4.8 branches? >>> >>> >>> Thanks >>> Bernd. >>> >>> >> >> I found some test cases in the clang tree, about the __tsan_vptr_update. >> So I thought I should use these instead of inventing new ones. >> >> Attached you'll find an updated patch with one positive and one negative >> test for vptr races. >> >> Tested with x86_64-linux-gnu. >> OK for trunk and 4.9 after a while? >> >> >> Thanks >> Bernd. >> > ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-16 17:32 ` Dmitry Vyukov @ 2015-01-16 17:52 ` Bernd Edlinger 2015-01-19 8:50 ` Dmitry Vyukov 0 siblings, 1 reply; 32+ messages in thread From: Bernd Edlinger @ 2015-01-16 17:52 UTC (permalink / raw) To: Dmitry Vyukov; +Cc: Jakub Jelinek, Richard Biener, gcc-patches Hi, On Fri, 16 Jan 2015 21:25:42, Dmitry Vyukov wrote: > > This is just a copy from llvm repo, right? > Looks good to me. > Thanks. Yes I found these test case in the llvm tree, and just adapted them to work in the gcc test suite. However, here is a small tweak in the positive test: That is we now use a tsan-invisible barrier_wait function instead of the not very reliable sleep(1). barrier_wait is bypassing the tsan interceptor, because it is accessed with dlsym (dlopen ("libpthread.so.0", RTLD_LAZY), "pthread_barrier_wait"). Bernd. > On Fri, Jan 16, 2015 at 10:17 AM, Bernd Edlinger > <bernd.edlinger@hotmail.de> wrote: >> Hi, >> >> >> I think I should ping for this patch now: >> https://gcc.gnu.org/ml/gcc-patches/2015-01/msg00599.html >> >> note that by mistake the change log referenced sanitizer.c instead of >> sanitizer.def, consider that fixed on my local copy. >> >> >> Thanks >> Bernd. >> >> >>> Date: Sun, 11 Jan 2015 14:15:54 +0100 >>> >>> Hi, >>> >>> >>> >>> On Sun, 4 Jan 2015 14:54:56, Bernd Edlinger wrote: >>>> >>>> Hi Jakub, >>>> >>>> >>>> I think I have found a reasonable test case, see the attached patch file. >>>> The use case is: a class that destroys an owned thread in the destructor. >>>> The destructor sets the vptr again to thread::vptr but this should >>>> _not_ trigger a diagnostic message, when the vptr does not really change. >>>> >>>> Jakub, this is another test case where the TREE_READONLY prevents >>>> the tsan instrumentation. So I had first to install your patch: >>>> >>>> https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01432.html >>>> >>>> ... to see the test case fail without my patch. >>>> >>> >>> that has been installed in the meantime. >>> >>>> The patch installs cleanly on 4.9 and 4.8, however the 4.8 branch >>>> has no tsan tests, so I would leave the test case away for 4.8. >>>> >>> >>> I found, 4.8 does not have BT_FN_VOID_PTR_PTR, and no tsan tests >>> at all, so it is probably not worth the effort. >>> >>>> Boot-strapped and regression-tested on x86_64-linux-gnu >>>> OK for trunk and 4.9 + 4.8 branches? >>>> >>>> >>>> Thanks >>>> Bernd. >>>> >>>> >>> >>> I found some test cases in the clang tree, about the __tsan_vptr_update. >>> So I thought I should use these instead of inventing new ones. >>> >>> Attached you'll find an updated patch with one positive and one negative >>> test for vptr races. >>> >>> Tested with x86_64-linux-gnu. >>> OK for trunk and 4.9 after a while? >>> >>> >>> Thanks >>> Bernd. >>> >> ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-16 17:52 ` Bernd Edlinger @ 2015-01-19 8:50 ` Dmitry Vyukov 2015-01-19 9:51 ` Jakub Jelinek 2015-01-19 15:46 ` Mike Stump 0 siblings, 2 replies; 32+ messages in thread From: Dmitry Vyukov @ 2015-01-19 8:50 UTC (permalink / raw) To: Bernd Edlinger, Kostya Serebryany Cc: Jakub Jelinek, Richard Biener, gcc-patches On Fri, Jan 16, 2015 at 8:42 PM, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote: > Hi, > > On Fri, 16 Jan 2015 21:25:42, Dmitry Vyukov wrote: >> >> This is just a copy from llvm repo, right? >> Looks good to me. >> > > Thanks. > > Yes I found these test case in the llvm tree, and just adapted them > to work in the gcc test suite. > > However, here is a small tweak in the positive test: > That is we now use a tsan-invisible barrier_wait function > instead of the not very reliable sleep(1). > > barrier_wait is bypassing the tsan interceptor, because > it is accessed with dlsym (dlopen ("libpthread.so.0", RTLD_LAZY), > "pthread_barrier_wait"). +Kostya Hi Bernd, Yes, that email is marked in my inbox. Sorry for not answering earlier. I can't really make my mind on this. I would mildly prefer sleep's (if they work reliably!). Kostya, please chime in. This is equivalent to StealthNotification that we used in old data-race-test test suite: https://code.google.com/p/data-race-test/source/browse/trunk/unittest/test_utils.h#134 Kostya, you had experience with both approaches. What are you thoughts on this? StealthNotification definitely makes tests faster and more reliable. I can't really come up with any objective downsides. >> On Fri, Jan 16, 2015 at 10:17 AM, Bernd Edlinger >> <bernd.edlinger@hotmail.de> wrote: >>> Hi, >>> >>> >>> I think I should ping for this patch now: >>> https://gcc.gnu.org/ml/gcc-patches/2015-01/msg00599.html >>> >>> note that by mistake the change log referenced sanitizer.c instead of >>> sanitizer.def, consider that fixed on my local copy. >>> >>> >>> Thanks >>> Bernd. >>> >>> >>>> Date: Sun, 11 Jan 2015 14:15:54 +0100 >>>> >>>> Hi, >>>> >>>> >>>> >>>> On Sun, 4 Jan 2015 14:54:56, Bernd Edlinger wrote: >>>>> >>>>> Hi Jakub, >>>>> >>>>> >>>>> I think I have found a reasonable test case, see the attached patch file. >>>>> The use case is: a class that destroys an owned thread in the destructor. >>>>> The destructor sets the vptr again to thread::vptr but this should >>>>> _not_ trigger a diagnostic message, when the vptr does not really change. >>>>> >>>>> Jakub, this is another test case where the TREE_READONLY prevents >>>>> the tsan instrumentation. So I had first to install your patch: >>>>> >>>>> https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01432.html >>>>> >>>>> ... to see the test case fail without my patch. >>>>> >>>> >>>> that has been installed in the meantime. >>>> >>>>> The patch installs cleanly on 4.9 and 4.8, however the 4.8 branch >>>>> has no tsan tests, so I would leave the test case away for 4.8. >>>>> >>>> >>>> I found, 4.8 does not have BT_FN_VOID_PTR_PTR, and no tsan tests >>>> at all, so it is probably not worth the effort. >>>> >>>>> Boot-strapped and regression-tested on x86_64-linux-gnu >>>>> OK for trunk and 4.9 + 4.8 branches? >>>>> >>>>> >>>>> Thanks >>>>> Bernd. >>>>> >>>>> >>>> >>>> I found some test cases in the clang tree, about the __tsan_vptr_update. >>>> So I thought I should use these instead of inventing new ones. >>>> >>>> Attached you'll find an updated patch with one positive and one negative >>>> test for vptr races. >>>> >>>> Tested with x86_64-linux-gnu. >>>> OK for trunk and 4.9 after a while? >>>> >>>> >>>> Thanks >>>> Bernd. >>>> >>> > ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-19 8:50 ` Dmitry Vyukov @ 2015-01-19 9:51 ` Jakub Jelinek 2015-01-19 15:46 ` Mike Stump 1 sibling, 0 replies; 32+ messages in thread From: Jakub Jelinek @ 2015-01-19 9:51 UTC (permalink / raw) To: Dmitry Vyukov Cc: Bernd Edlinger, Kostya Serebryany, Richard Biener, gcc-patches On Mon, Jan 19, 2015 at 12:43:39PM +0400, Dmitry Vyukov wrote: > Hi Bernd, > > Yes, that email is marked in my inbox. Sorry for not answering earlier. > > I can't really make my mind on this. I would mildly prefer sleep's (if > they work reliably!). Sleeps by definition should not be reliable, not to mention that they waste testing time. > Kostya, please chime in. This is equivalent to StealthNotification > that we used in old data-race-test test suite: > https://code.google.com/p/data-race-test/source/browse/trunk/unittest/test_utils.h#134 > Kostya, you had experience with both approaches. What are you thoughts on this? > StealthNotification definitely makes tests faster and more reliable. I > can't really come up with any objective downsides. Jakub ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-19 8:50 ` Dmitry Vyukov 2015-01-19 9:51 ` Jakub Jelinek @ 2015-01-19 15:46 ` Mike Stump 2015-01-20 4:03 ` Konstantin Serebryany 1 sibling, 1 reply; 32+ messages in thread From: Mike Stump @ 2015-01-19 15:46 UTC (permalink / raw) To: Dmitry Vyukov Cc: Bernd Edlinger, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches On Jan 19, 2015, at 12:43 AM, Dmitry Vyukov <dvyukov@google.com> wrote: > I can't really make my mind on this. I would mildly prefer sleep's (if > they work reliably!). Let me state it more forcefully. sleeps are not now, nor in the history of computing ever been a synchronization primitive, except for hard real time systems. If they were, you would be able to cite a paper that uses them. If I am wrong, I’d welcome a cite. Any failure of sleep to work is a indication that that system is not a real time system, and the entirety of the gcc test suite is non-real time code (unless someone snuck some in while I wasn’t watching). Only a synchronization primitive can make the test cases deterministic, therefore, sleep can never be used as a syntonization primitive in the gcc test suite. > Kostya, you had experience with both approaches. What are you thoughts on this? > StealthNotification definitely makes tests faster and more reliable. To me, reliability isn’t a continuum for the gcc test suite. It is binary. It is, or, is not reliable and deterministic. The standard for the gcc test suite is to be realible and deterministic. > can't really come up with any objective downsides. Nor I. ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-19 15:46 ` Mike Stump @ 2015-01-20 4:03 ` Konstantin Serebryany 2015-01-20 7:18 ` Bernd Edlinger 0 siblings, 1 reply; 32+ messages in thread From: Konstantin Serebryany @ 2015-01-20 4:03 UTC (permalink / raw) To: Mike Stump Cc: Dmitry Vyukov, Bernd Edlinger, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches [text-only] On Mon, Jan 19, 2015 at 7:42 AM, Mike Stump <mikestump@comcast.net> wrote: > On Jan 19, 2015, at 12:43 AM, Dmitry Vyukov <dvyukov@google.com> wrote: >> I can't really make my mind on this. I would mildly prefer sleep's (if >> they work reliably!). > > Let me state it more forcefully. You don't have to convince us here. I'd love to get rid of sleep calls in the tsan test suite -- they are a minor but a constant annoyance. But I also want to keep the tests *very simple*, i.e. 1. Single file w/o any non-system includes, no linking of extra libraries/objects 2. Not too much extra code. (ideally, 1 line for init, 1 line for "signal", 1 line for "wait") 3. Strictly posix or c++11 (unless we are testing something specific) Your idea with barrier_wait/dlsym sounds interesting, but I can't see the code in this mail thread. What do I miss? > sleeps are not now, nor in the history of computing ever been a synchronization primitive, except for hard real time systems. If they were, you would be able to cite a paper that uses them. If I am wrong, I’d welcome a cite. Any failure of sleep to work is a indication that that system is not a real time system, and the entirety of the gcc test suite is non-real time code (unless someone snuck some in while I wasn’t watching). Only a synchronization primitive can make the test cases deterministic, therefore, sleep can never be used as a syntonization primitive in the gcc test suite. > >> Kostya, you had experience with both approaches. What are you thoughts on this? >> StealthNotification definitely makes tests faster and more reliable. Yep. > > To me, reliability isn’t a continuum for the gcc test suite. It is binary. It is, or, is not reliable and deterministic. The standard for the gcc test suite is to be realible and deterministic. > >> can't really come up with any objective downsides. he downside is more code in tests. If we can satisfy my definition of *very simple* (above) -- let's do it. >> not to mention that they waste testing time. We discussed this. With a parallel test runner this is not a problem. I don't say the sleeps are good, I just say that testing time is not an argument against them. Flakiness is. --kcc > > Nor I. ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-20 4:03 ` Konstantin Serebryany @ 2015-01-20 7:18 ` Bernd Edlinger 2015-01-21 6:15 ` Konstantin Serebryany 2015-01-21 9:09 ` Dmitry Vyukov 0 siblings, 2 replies; 32+ messages in thread From: Bernd Edlinger @ 2015-01-20 7:18 UTC (permalink / raw) To: Konstantin Serebryany, Mike Stump Cc: Dmitry Vyukov, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches Hi, On Mon, 19 Jan 2015 18:49:21, Konstantin Serebryany wrote: > > [text-only] > > On Mon, Jan 19, 2015 at 7:42 AM, Mike Stump <mikestump@comcast.net> wrote: >> On Jan 19, 2015, at 12:43 AM, Dmitry Vyukov <dvyukov@google.com> wrote: >>> I can't really make my mind on this. I would mildly prefer sleep's (if >>> they work reliably!). >> >> Let me state it more forcefully. > You don't have to convince us here. > I'd love to get rid of sleep calls in the tsan test suite -- they are > a minor but a constant annoyance. > But I also want to keep the tests *very simple*, i.e. > 1. Single file w/o any non-system includes, no linking of extra > libraries/objects > 2. Not too much extra code. (ideally, 1 line for init, 1 line for > "signal", 1 line for "wait") > 3. Strictly posix or c++11 (unless we are testing something specific) > > Your idea with barrier_wait/dlsym sounds interesting, but I can't see > the code in this mail thread. > What do I miss? > We discussed two alternatives to sleep: 1. step function, optionally with sched_yield to make it somewhat less busy waiting: __attribute__((no_sanitize_thread)) void step (int i) { while (__atomic_load_n (&serial, __ATOMIC_ACQUIRE) != i - 1) sched_yield(); __atomic_store_n (&serial, i, __ATOMIC_RELEASE); } 2. tsan-invisible barriers: cat tsan_barrier.h /* TSAN-invisible barriers. Link with -ldl. */ #include <pthread.h> #include <dlfcn.h> static __typeof(pthread_barrier_wait) *barrier_wait; static void barrier_init (pthread_barrier_t *barrier, unsigned count) { void *h = dlopen ("libpthread.so.0", RTLD_LAZY); barrier_wait = (__typeof (pthread_barrier_wait) *) dlsym (h, "pthread_barrier_wait"); pthread_barrier_init (barrier, NULL, count); } We preferred the second alternative, because it does not do busy waiting. We include this header file in every positive test case and link with -ldl. Bernd. ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-20 7:18 ` Bernd Edlinger @ 2015-01-21 6:15 ` Konstantin Serebryany 2015-01-21 8:34 ` Bernd Edlinger 2015-01-21 9:09 ` Dmitry Vyukov 1 sibling, 1 reply; 32+ messages in thread From: Konstantin Serebryany @ 2015-01-21 6:15 UTC (permalink / raw) To: Bernd Edlinger Cc: Mike Stump, Dmitry Vyukov, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches On Mon, Jan 19, 2015 at 11:09 PM, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote: > > Hi, > > On Mon, 19 Jan 2015 18:49:21, Konstantin Serebryany wrote: >> >> [text-only] >> >> On Mon, Jan 19, 2015 at 7:42 AM, Mike Stump <mikestump@comcast.net> wrote: >>> On Jan 19, 2015, at 12:43 AM, Dmitry Vyukov <dvyukov@google.com> wrote: >>>> I can't really make my mind on this. I would mildly prefer sleep's (if >>>> they work reliably!). >>> >>> Let me state it more forcefully. >> You don't have to convince us here. >> I'd love to get rid of sleep calls in the tsan test suite -- they are >> a minor but a constant annoyance. >> But I also want to keep the tests *very simple*, i.e. >> 1. Single file w/o any non-system includes, no linking of extra >> libraries/objects >> 2. Not too much extra code. (ideally, 1 line for init, 1 line for >> "signal", 1 line for "wait") >> 3. Strictly posix or c++11 (unless we are testing something specific) >> >> Your idea with barrier_wait/dlsym sounds interesting, but I can't see >> the code in this mail thread. >> What do I miss? >> > > We discussed two alternatives to sleep: > > 1. step function, optionally with sched_yield to make it somewhat less busy waiting: > __attribute__((no_sanitize_thread)) > void step (int i) > { > while (__atomic_load_n (&serial, __ATOMIC_ACQUIRE) != i - 1) > sched_yield(); > __atomic_store_n (&serial, i, __ATOMIC_RELEASE); > } This will not work: tsan will still instrument atomics in a function with __attribute__((no_sanitize_thread)) (This applies to both clang and gcc variants) > 2. tsan-invisible barriers: > > cat tsan_barrier.h > /* TSAN-invisible barriers. Link with -ldl. */ > #include <pthread.h> > #include <dlfcn.h> > > static __typeof(pthread_barrier_wait) *barrier_wait; > > static > void barrier_init (pthread_barrier_t *barrier, unsigned count) > { > void *h = dlopen ("libpthread.so.0", RTLD_LAZY); > barrier_wait = (__typeof (pthread_barrier_wait) *) > dlsym (h, "pthread_barrier_wait"); > pthread_barrier_init (barrier, NULL, count); > } So, we will have a single extra header file, but no extra .c files. This sounds tolerable. I am not sure how portable that is, but today's tsan works only on modern Linux anyway. If you want to contribute the code, please send a patch to upstream LLVM: we may not be able to take the code from gcc source tree to LLVM, the other direction is easy. Or please give us some time to fix the tests in upstream ourselves and than port them to the gcc test suite. Dmitry, wdyt? > > > We preferred the second alternative, because it does not do busy waiting. > We include this header file in every positive test case and link with -ldl. -ldl is not required, since -fsanitize=thread already adds that. --kcc > > Bernd. > > ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-21 6:15 ` Konstantin Serebryany @ 2015-01-21 8:34 ` Bernd Edlinger 0 siblings, 0 replies; 32+ messages in thread From: Bernd Edlinger @ 2015-01-21 8:34 UTC (permalink / raw) To: Konstantin Serebryany Cc: Mike Stump, Dmitry Vyukov, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches Hi, On Tue, 20 Jan 2015 17:47:29, Konstantin Serebryany wrote: >> >> We discussed two alternatives to sleep: >> >> 1. step function, optionally with sched_yield to make it somewhat less busy waiting: >> __attribute__((no_sanitize_thread)) >> void step (int i) >> { >> while (__atomic_load_n (&serial, __ATOMIC_ACQUIRE) != i - 1) >> sched_yield(); >> __atomic_store_n (&serial, i, __ATOMIC_RELEASE); >> } > > This will not work: tsan will still instrument atomics in a function > with __attribute__((no_sanitize_thread)) > (This applies to both clang and gcc variants) > >> 2. tsan-invisible barriers: >> >> cat tsan_barrier.h >> /* TSAN-invisible barriers. Link with -ldl. */ >> #include <pthread.h> >> #include <dlfcn.h> >> >> static __typeof(pthread_barrier_wait) *barrier_wait; >> >> static >> void barrier_init (pthread_barrier_t *barrier, unsigned count) >> { >> void *h = dlopen ("libpthread.so.0", RTLD_LAZY); >> barrier_wait = (__typeof (pthread_barrier_wait) *) >> dlsym (h, "pthread_barrier_wait"); >> pthread_barrier_init (barrier, NULL, count); >> } > > So, we will have a single extra header file, but no extra .c files. > This sounds tolerable. > I am not sure how portable that is, but today's tsan works only on > modern Linux anyway. > > If you want to contribute the code, please send a patch to upstream LLVM: > we may not be able to take the code from gcc source tree to LLVM, the > other direction is easy. > Or please give us some time to fix the tests in upstream ourselves and > than port them to the gcc test suite. > That's fine, LLVM is out of my reach so I can't do that myself, but I will always help if I can. > Dmitry, wdyt? > > >> >> >> We preferred the second alternative, because it does not do busy waiting. >> We include this header file in every positive test case and link with -ldl. > > -ldl is not required, since -fsanitize=thread already adds that. > Maybe that is a driver issue or just a linker oddity. Clang will probably use a different linker. In our case however, if I do not add -ldl to the application, the linker complains about the missing DSO in the command line. Also if I use -fsanititze=thread I do in most cases not need -pthread on the command line, but if I happen to use a non-intercepted pthread function for instance pthread_yield() I get an error: cat test.c #define _GNU_SOURCE #include <pthread.h> int main() { pthread_yield(); return 0; } gcc test.c -fsanitize=thread /home/ed/gnu/install/lib/gcc/x86_64-unknown-linux-gnu/5.0.0/../../../../x86_64-unknown-linux-gnu/bin/ld: /tmp/ccGGRrgy.o: undefined reference to symbol 'pthread_yield@@GLIBC_2.2.5' /lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status gcc test.c -fsanitize=thread -pthread => OK Bernd. ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-20 7:18 ` Bernd Edlinger 2015-01-21 6:15 ` Konstantin Serebryany @ 2015-01-21 9:09 ` Dmitry Vyukov 2015-01-21 10:50 ` Bernd Edlinger ` (2 more replies) 1 sibling, 3 replies; 32+ messages in thread From: Dmitry Vyukov @ 2015-01-21 9:09 UTC (permalink / raw) To: Bernd Edlinger Cc: Konstantin Serebryany, Mike Stump, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches On Tue, Jan 20, 2015 at 10:09 AM, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote: > > Hi, > > On Mon, 19 Jan 2015 18:49:21, Konstantin Serebryany wrote: >> >> [text-only] >> >> On Mon, Jan 19, 2015 at 7:42 AM, Mike Stump <mikestump@comcast.net> wrote: >>> On Jan 19, 2015, at 12:43 AM, Dmitry Vyukov <dvyukov@google.com> wrote: >>>> I can't really make my mind on this. I would mildly prefer sleep's (if >>>> they work reliably!). >>> >>> Let me state it more forcefully. >> You don't have to convince us here. >> I'd love to get rid of sleep calls in the tsan test suite -- they are >> a minor but a constant annoyance. >> But I also want to keep the tests *very simple*, i.e. >> 1. Single file w/o any non-system includes, no linking of extra >> libraries/objects >> 2. Not too much extra code. (ideally, 1 line for init, 1 line for >> "signal", 1 line for "wait") >> 3. Strictly posix or c++11 (unless we are testing something specific) >> >> Your idea with barrier_wait/dlsym sounds interesting, but I can't see >> the code in this mail thread. >> What do I miss? >> > > We discussed two alternatives to sleep: > > 1. step function, optionally with sched_yield to make it somewhat less busy waiting: > __attribute__((no_sanitize_thread)) > void step (int i) > { > while (__atomic_load_n (&serial, __ATOMIC_ACQUIRE) != i - 1) > sched_yield(); > __atomic_store_n (&serial, i, __ATOMIC_RELEASE); > } > 2. tsan-invisible barriers: > > cat tsan_barrier.h > /* TSAN-invisible barriers. Link with -ldl. */ > #include <pthread.h> > #include <dlfcn.h> > > static __typeof(pthread_barrier_wait) *barrier_wait; > > static > void barrier_init (pthread_barrier_t *barrier, unsigned count) > { > void *h = dlopen ("libpthread.so.0", RTLD_LAZY); > barrier_wait = (__typeof (pthread_barrier_wait) *) > dlsym (h, "pthread_barrier_wait"); > pthread_barrier_init (barrier, NULL, count); > } > > > We preferred the second alternative, because it does not do busy waiting. > We include this header file in every positive test case and link with -ldl. The step approach looks better to me at first sight. Busy waiting looks like a weak argument in this context. It's absolutely non performance-critical and a yield or usleep(10) will solve it more than sufficiently. I will check how complex to make its implementation invisible to tsan (I suspect that clang does not ignore atomic operations when no_sanitize_thread attribute is given) and whether it actually makes more complex tests simpler to write (as compared to the barrier approach). ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-21 9:09 ` Dmitry Vyukov @ 2015-01-21 10:50 ` Bernd Edlinger 2015-01-21 11:33 ` Bernd Edlinger 2015-01-21 10:50 ` Dmitry Vyukov 2015-01-21 14:42 ` Dmitry Vyukov 2 siblings, 1 reply; 32+ messages in thread From: Bernd Edlinger @ 2015-01-21 10:50 UTC (permalink / raw) To: Dmitry Vyukov Cc: Konstantin Serebryany, Mike Stump, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches Hi, On Wed, 21 Jan 2015 12:58:27, Dmitry Vyukov wrote: > > > The step approach looks better to me at first sight. > > Busy waiting looks like a weak argument in this context. It's > absolutely non performance-critical and a yield or usleep(10) will > solve it more than sufficiently. > > I will check how complex to make its implementation invisible to tsan > (I suspect that clang does not ignore atomic operations when > no_sanitize_thread attribute is given) and whether it actually makes > more complex tests simpler to write (as compared to the barrier > approach). Yes, for Gcc this is a pretty new feature, so I dont think we should use it now. It _should_ suppress the instrumentation of atomics, but it can not be used to avoid intercepted calls like usleep, and using sched_yield is safe, but usleep is intercepted, and may change the printed diagnostics. But unfortunately it is not really stable at the time: cat test.c volatile int serial=0; __attribute__((no_sanitize_thread)) void step (int i) { while (__atomic_load_n (&serial, __ATOMIC_ACQUIRE) != i - 1) sched_yield(); __atomic_store_n (&serial, i, __ATOMIC_RELEASE); } gcc -S -fsanitize=thread test.c test.c: In function 'step': test.c:6:6: warning: implicit declaration of function 'sched_yield' [-Wimplicit-function-declaration] sched_yield(); ^ test.c:3:6: internal compiler error: in expand_TSAN_FUNC_EXIT, at internal-fn.c:243 void step (int i) ^ 0x966b17 expand_TSAN_FUNC_EXIT ../../gcc-5-20150118/gcc/internal-fn.c:243 0x75438f expand_call_stmt ../../gcc-5-20150118/gcc/cfgexpand.c:2311 0x75438f expand_gimple_stmt_1 ../../gcc-5-20150118/gcc/cfgexpand.c:3327 0x75438f expand_gimple_stmt ../../gcc-5-20150118/gcc/cfgexpand.c:3481 0x75a862 expand_gimple_basic_block ../../gcc-5-20150118/gcc/cfgexpand.c:5394 0x75c087 execute ../../gcc-5-20150118/gcc/cfgexpand.c:6003 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. Bernd. ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-21 10:50 ` Bernd Edlinger @ 2015-01-21 11:33 ` Bernd Edlinger 2015-01-21 11:51 ` Jakub Jelinek 2015-01-21 18:47 ` Mike Stump 0 siblings, 2 replies; 32+ messages in thread From: Bernd Edlinger @ 2015-01-21 11:33 UTC (permalink / raw) To: Mike Stump, Jakub Jelinek Cc: Konstantin Serebryany, Kostya Serebryany, Richard Biener, gcc-patches, Dmitry Vyukov [-- Attachment #1: Type: text/plain, Size: 308 bytes --] Hi Jakub & Mike, > test.c:3:6: internal compiler error: in expand_TSAN_FUNC_EXIT, at internal-fn.c:243 > void step (int i) It looks like your patches shot each other down.. How about this, maybe with a compile-time test of the step function in c-c++common/tsan? Thanks Bernd. [-- Attachment #2: patch-tsan-attribute.diff --] [-- Type: application/octet-stream, Size: 518 bytes --] --- gcc/gimplify.c.jj 2015-01-15 21:11:12.000000000 +0100 +++ gcc/gimplify.c 2015-01-21 11:49:38.214588504 +0100 @@ -9250,7 +9250,8 @@ gimplify_function_tree (tree fndecl) bind = new_bind; } - if (flag_sanitize & SANITIZE_THREAD) + if ((flag_sanitize & SANITIZE_THREAD) != 0 + && !lookup_attribute ("no_sanitize_thread", DECL_ATTRIBUTES (fndecl))) { gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0); gimple tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY); ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-21 11:33 ` Bernd Edlinger @ 2015-01-21 11:51 ` Jakub Jelinek 2015-01-21 12:55 ` Bernd Edlinger 2015-01-21 18:47 ` Mike Stump 1 sibling, 1 reply; 32+ messages in thread From: Jakub Jelinek @ 2015-01-21 11:51 UTC (permalink / raw) To: Bernd Edlinger Cc: Mike Stump, Konstantin Serebryany, Kostya Serebryany, Richard Biener, gcc-patches, Dmitry Vyukov On Wed, Jan 21, 2015 at 12:17:51PM +0100, Bernd Edlinger wrote: > > test.c:3:6: internal compiler error: in expand_TSAN_FUNC_EXIT, at internal-fn.c:243 > > void step (int i) > > > It looks like your patches shot each other down.. > > How about this, maybe with a compile-time test of the step function in c-c++common/tsan? If you add a testcase for it, sure. It can be just compile time testcase, perhaps with some assembler match that no __tsan_ calls are made. Jakub ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-21 11:51 ` Jakub Jelinek @ 2015-01-21 12:55 ` Bernd Edlinger 0 siblings, 0 replies; 32+ messages in thread From: Bernd Edlinger @ 2015-01-21 12:55 UTC (permalink / raw) To: Jakub Jelinek Cc: Mike Stump, Konstantin Serebryany, Kostya Serebryany, Richard Biener, gcc-patches, Dmitry Vyukov On Wed, 21 Jan 2015 12:31:57, Jakub Jelinek wrote: > > On Wed, Jan 21, 2015 at 12:17:51PM +0100, Bernd Edlinger wrote: >>> test.c:3:6: internal compiler error: in expand_TSAN_FUNC_EXIT, at internal-fn.c:243 >>> void step (int i) >> >> >> It looks like your patches shot each other down.. >> >> How about this, maybe with a compile-time test of the step function in c-c++common/tsan? > > If you add a testcase for it, sure. It can be just compile time testcase, > perhaps with some assembler match that no __tsan_ calls are made. > yes, that's what I had in mind. Bernd. ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-21 11:33 ` Bernd Edlinger 2015-01-21 11:51 ` Jakub Jelinek @ 2015-01-21 18:47 ` Mike Stump 1 sibling, 0 replies; 32+ messages in thread From: Mike Stump @ 2015-01-21 18:47 UTC (permalink / raw) To: Bernd Edlinger Cc: Jakub Jelinek, Konstantin Serebryany, Kostya Serebryany, Richard Biener, gcc-patches, Dmitry Vyukov On Jan 21, 2015, at 3:17 AM, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote: > Hi Jakub & Mike, > >> test.c:3:6: internal compiler error: in expand_TSAN_FUNC_EXIT, at internal-fn.c:243 >> void step (int i) > > It looks like your patches shot each other down.. Ah, I’d use the phrase one-step forward. Yeah, looks not as useful without the second step forward as well. > How about this, maybe with a compile-time test of the step function in c-c++common/tsan? I’m fine with it (assuming it passes a regtest), seems like it should be reviewed by the normal tsan people. They might be able to spot other places that might need updating. ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-21 9:09 ` Dmitry Vyukov 2015-01-21 10:50 ` Bernd Edlinger @ 2015-01-21 10:50 ` Dmitry Vyukov 2015-01-21 14:42 ` Dmitry Vyukov 2 siblings, 0 replies; 32+ messages in thread From: Dmitry Vyukov @ 2015-01-21 10:50 UTC (permalink / raw) To: Bernd Edlinger Cc: Konstantin Serebryany, Mike Stump, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches Well, OK, it is actually not easier to write tests with step function as compared to barrier. On Wed, Jan 21, 2015 at 11:58 AM, Dmitry Vyukov <dvyukov@google.com> wrote: > On Tue, Jan 20, 2015 at 10:09 AM, Bernd Edlinger > <bernd.edlinger@hotmail.de> wrote: >> >> Hi, >> >> On Mon, 19 Jan 2015 18:49:21, Konstantin Serebryany wrote: >>> >>> [text-only] >>> >>> On Mon, Jan 19, 2015 at 7:42 AM, Mike Stump <mikestump@comcast.net> wrote: >>>> On Jan 19, 2015, at 12:43 AM, Dmitry Vyukov <dvyukov@google.com> wrote: >>>>> I can't really make my mind on this. I would mildly prefer sleep's (if >>>>> they work reliably!). >>>> >>>> Let me state it more forcefully. >>> You don't have to convince us here. >>> I'd love to get rid of sleep calls in the tsan test suite -- they are >>> a minor but a constant annoyance. >>> But I also want to keep the tests *very simple*, i.e. >>> 1. Single file w/o any non-system includes, no linking of extra >>> libraries/objects >>> 2. Not too much extra code. (ideally, 1 line for init, 1 line for >>> "signal", 1 line for "wait") >>> 3. Strictly posix or c++11 (unless we are testing something specific) >>> >>> Your idea with barrier_wait/dlsym sounds interesting, but I can't see >>> the code in this mail thread. >>> What do I miss? >>> >> >> We discussed two alternatives to sleep: >> >> 1. step function, optionally with sched_yield to make it somewhat less busy waiting: >> __attribute__((no_sanitize_thread)) >> void step (int i) >> { >> while (__atomic_load_n (&serial, __ATOMIC_ACQUIRE) != i - 1) >> sched_yield(); >> __atomic_store_n (&serial, i, __ATOMIC_RELEASE); >> } >> 2. tsan-invisible barriers: >> >> cat tsan_barrier.h >> /* TSAN-invisible barriers. Link with -ldl. */ >> #include <pthread.h> >> #include <dlfcn.h> >> >> static __typeof(pthread_barrier_wait) *barrier_wait; >> >> static >> void barrier_init (pthread_barrier_t *barrier, unsigned count) >> { >> void *h = dlopen ("libpthread.so.0", RTLD_LAZY); >> barrier_wait = (__typeof (pthread_barrier_wait) *) >> dlsym (h, "pthread_barrier_wait"); >> pthread_barrier_init (barrier, NULL, count); >> } >> >> >> We preferred the second alternative, because it does not do busy waiting. >> We include this header file in every positive test case and link with -ldl. > > > The step approach looks better to me at first sight. > > Busy waiting looks like a weak argument in this context. It's > absolutely non performance-critical and a yield or usleep(10) will > solve it more than sufficiently. > > I will check how complex to make its implementation invisible to tsan > (I suspect that clang does not ignore atomic operations when > no_sanitize_thread attribute is given) and whether it actually makes > more complex tests simpler to write (as compared to the barrier > approach). ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-21 9:09 ` Dmitry Vyukov 2015-01-21 10:50 ` Bernd Edlinger 2015-01-21 10:50 ` Dmitry Vyukov @ 2015-01-21 14:42 ` Dmitry Vyukov 2015-01-21 16:15 ` Bernd Edlinger 2 siblings, 1 reply; 32+ messages in thread From: Dmitry Vyukov @ 2015-01-21 14:42 UTC (permalink / raw) To: Bernd Edlinger Cc: Konstantin Serebryany, Mike Stump, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches Refactored tests in clang to use barrier_init/wait: http://llvm.org/viewvc/llvm-project?view=revision&revision=226659 There are still few sleep call, like when we need to wait for a thread to exit (there is really no point to insert barrier_wait); or when we need to wait for a thread to _block_ inside of pthread_cond_wait; or when a thread needs to process signals. But all remaining uses of sleep are commented. On Wed, Jan 21, 2015 at 11:58 AM, Dmitry Vyukov <dvyukov@google.com> wrote: > On Tue, Jan 20, 2015 at 10:09 AM, Bernd Edlinger > <bernd.edlinger@hotmail.de> wrote: >> >> Hi, >> >> On Mon, 19 Jan 2015 18:49:21, Konstantin Serebryany wrote: >>> >>> [text-only] >>> >>> On Mon, Jan 19, 2015 at 7:42 AM, Mike Stump <mikestump@comcast.net> wrote: >>>> On Jan 19, 2015, at 12:43 AM, Dmitry Vyukov <dvyukov@google.com> wrote: >>>>> I can't really make my mind on this. I would mildly prefer sleep's (if >>>>> they work reliably!). >>>> >>>> Let me state it more forcefully. >>> You don't have to convince us here. >>> I'd love to get rid of sleep calls in the tsan test suite -- they are >>> a minor but a constant annoyance. >>> But I also want to keep the tests *very simple*, i.e. >>> 1. Single file w/o any non-system includes, no linking of extra >>> libraries/objects >>> 2. Not too much extra code. (ideally, 1 line for init, 1 line for >>> "signal", 1 line for "wait") >>> 3. Strictly posix or c++11 (unless we are testing something specific) >>> >>> Your idea with barrier_wait/dlsym sounds interesting, but I can't see >>> the code in this mail thread. >>> What do I miss? >>> >> >> We discussed two alternatives to sleep: >> >> 1. step function, optionally with sched_yield to make it somewhat less busy waiting: >> __attribute__((no_sanitize_thread)) >> void step (int i) >> { >> while (__atomic_load_n (&serial, __ATOMIC_ACQUIRE) != i - 1) >> sched_yield(); >> __atomic_store_n (&serial, i, __ATOMIC_RELEASE); >> } >> 2. tsan-invisible barriers: >> >> cat tsan_barrier.h >> /* TSAN-invisible barriers. Link with -ldl. */ >> #include <pthread.h> >> #include <dlfcn.h> >> >> static __typeof(pthread_barrier_wait) *barrier_wait; >> >> static >> void barrier_init (pthread_barrier_t *barrier, unsigned count) >> { >> void *h = dlopen ("libpthread.so.0", RTLD_LAZY); >> barrier_wait = (__typeof (pthread_barrier_wait) *) >> dlsym (h, "pthread_barrier_wait"); >> pthread_barrier_init (barrier, NULL, count); >> } >> >> >> We preferred the second alternative, because it does not do busy waiting. >> We include this header file in every positive test case and link with -ldl. > > > The step approach looks better to me at first sight. > > Busy waiting looks like a weak argument in this context. It's > absolutely non performance-critical and a yield or usleep(10) will > solve it more than sufficiently. > > I will check how complex to make its implementation invisible to tsan > (I suspect that clang does not ignore atomic operations when > no_sanitize_thread attribute is given) and whether it actually makes > more complex tests simpler to write (as compared to the barrier > approach). ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-21 14:42 ` Dmitry Vyukov @ 2015-01-21 16:15 ` Bernd Edlinger 2015-01-21 16:17 ` Dmitry Vyukov 0 siblings, 1 reply; 32+ messages in thread From: Bernd Edlinger @ 2015-01-21 16:15 UTC (permalink / raw) To: Dmitry Vyukov Cc: Konstantin Serebryany, Mike Stump, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches Hi, On 21 Jan 2015 17:57:10, Dmitry Vyukov wrote: > Subject: Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update > To: bernd.edlinger@hotmail.de > CC: konstantin.s.serebryany@gmail.com; mikestump@comcast.net; kcc@google.com; jakub@redhat.com; richard.guenther@gmail.com; gcc-patches@gcc.gnu.org > > Refactored tests in clang to use barrier_init/wait: > http://llvm.org/viewvc/llvm-project?view=revision&revision=226659 > > There are still few sleep call, like when we need to wait for a thread > to exit (there is really no point to insert barrier_wait); or when we > need to wait for a thread to _block_ inside of pthread_cond_wait; or > when a thread needs to process signals. But all remaining uses of > sleep are commented. > Wow. That was quick! You should no longer need the %deflake thing now, right? Thanks, Bernd. ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-21 16:15 ` Bernd Edlinger @ 2015-01-21 16:17 ` Dmitry Vyukov 2015-01-21 19:01 ` Mike Stump 0 siblings, 1 reply; 32+ messages in thread From: Dmitry Vyukov @ 2015-01-21 16:17 UTC (permalink / raw) To: Bernd Edlinger Cc: Konstantin Serebryany, Mike Stump, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches On Wed, Jan 21, 2015 at 5:38 PM, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote: > Hi, > > On 21 Jan 2015 17:57:10, Dmitry Vyukov wrote: >> Subject: Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update >> To: bernd.edlinger@hotmail.de >> CC: konstantin.s.serebryany@gmail.com; mikestump@comcast.net; kcc@google.com; jakub@redhat.com; richard.guenther@gmail.com; gcc-patches@gcc.gnu.org >> >> Refactored tests in clang to use barrier_init/wait: >> http://llvm.org/viewvc/llvm-project?view=revision&revision=226659 >> >> There are still few sleep call, like when we need to wait for a thread >> to exit (there is really no point to insert barrier_wait); or when we >> need to wait for a thread to _block_ inside of pthread_cond_wait; or >> when a thread needs to process signals. But all remaining uses of >> sleep are commented. >> > > Wow. That was quick! > You should no longer need the %deflake thing now, right? You are right. But I am somewhat tired of editing hundreds of files for today. Why did I write so many tests, stupid!? ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PING] [PATCH] Fix parameters of __tsan_vptr_update 2015-01-21 16:17 ` Dmitry Vyukov @ 2015-01-21 19:01 ` Mike Stump 0 siblings, 0 replies; 32+ messages in thread From: Mike Stump @ 2015-01-21 19:01 UTC (permalink / raw) To: Dmitry Vyukov Cc: Bernd Edlinger, Konstantin Serebryany, Kostya Serebryany, Jakub Jelinek, Richard Biener, gcc-patches On Jan 21, 2015, at 6:41 AM, Dmitry Vyukov <dvyukov@google.com> wrote: > But I am somewhat tired of editing hundreds of files for today. Why > did I write so many tests, stupid!? :-) We appreciate all your efforts and all your tests. ^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2015-01-21 18:05 UTC | newest] Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-12-29 23:13 [PATCH] Instrument bit field and unaligned accesses for TSAN Bernd Edlinger 2015-01-02 19:01 ` Jakub Jelinek 2015-01-02 21:06 ` Bernd Edlinger 2015-01-02 21:29 ` Jakub Jelinek 2015-01-02 22:02 ` Bernd Edlinger 2015-01-02 22:11 ` Jakub Jelinek 2015-01-14 16:58 ` Dmitry Vyukov 2015-01-04 13:55 ` [PATCH] Fix parameters of __tsan_vptr_update Bernd Edlinger 2015-01-11 13:38 ` Bernd Edlinger 2015-01-14 15:09 ` Dmitry Vyukov 2015-01-16 8:34 ` [PING] " Bernd Edlinger 2015-01-16 17:20 ` Jeff Law 2015-01-16 17:32 ` Dmitry Vyukov 2015-01-16 17:52 ` Bernd Edlinger 2015-01-19 8:50 ` Dmitry Vyukov 2015-01-19 9:51 ` Jakub Jelinek 2015-01-19 15:46 ` Mike Stump 2015-01-20 4:03 ` Konstantin Serebryany 2015-01-20 7:18 ` Bernd Edlinger 2015-01-21 6:15 ` Konstantin Serebryany 2015-01-21 8:34 ` Bernd Edlinger 2015-01-21 9:09 ` Dmitry Vyukov 2015-01-21 10:50 ` Bernd Edlinger 2015-01-21 11:33 ` Bernd Edlinger 2015-01-21 11:51 ` Jakub Jelinek 2015-01-21 12:55 ` Bernd Edlinger 2015-01-21 18:47 ` Mike Stump 2015-01-21 10:50 ` Dmitry Vyukov 2015-01-21 14:42 ` Dmitry Vyukov 2015-01-21 16:15 ` Bernd Edlinger 2015-01-21 16:17 ` Dmitry Vyukov 2015-01-21 19:01 ` Mike Stump
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).