# TSan: ThreadSanitizer # https://github.com/google/sanitizers/wiki/threadsanitizersuppressions # # This file describes a number of places where TSAN detects problems in CRuby. # Many of these indicate bugs. Others are benign (ex. data races that can be # replaced with relaxed atomic loads) # # Usage: # Configure with: # ./configure cflags='-fsanitize=thread' CC=clang # Build and run with: # TSAN_OPTIONS="suppressions=$(pwd)/misc/tsan_suppressions.txt:die_after_fork=0" # # Other useful TSAN_OPTIONS: # * halt_on_error=1 # * strip_path_prefix=$(pwd)/ # Namespaces race_top:push_subclass_entry_to_list # sub_nounderflow includes non-atomic read, possibly other issue race:objspace_malloc_increase_body # Signals and ubf race:unregister_ubf_list # It's already crashing. We're doing our best signal:rb_vm_bugreport race:check_reserved_signal_ race_top:rb_check_deadlock # vm->ractor.sched.grq_cnt++ race_top:ractor_sched_enq race_top:ractor_sched_deq # Race between vm_remove_ractor writing ractor count and # native_thread_check_and_create_shared reading it during thread creation. # The write happens when a ractor thread exits, the read happens when # checking if new shared threads need to be created. race:vm_remove_ractor # th->sched.finished at end of co_start race_top:rb_thread_sched_mark_zombies # Races against timer thread setting th->sched.waiting_reason.flags race_top:thread_sched_wait_events # At thread start race_top:rb_ractor_set_current_ec_ # TSan reports a lock-order-inversion between thread_sched_lock_ and this lock. # It's unclear if that can cause a deadlock since the lock is on self deadlock:ractor_lock_self # TSan reports a deadlock when reacquiring the this lock after a barrier, but # we know the other threads have been stopped deadlock:rb_ractor_sched_barrier_start # RVALUE_AGE_SET manipulates flag bits on objects which may be accessed in Ractors race_top:RVALUE_AGE_SET # Inline caches and call cache updates # Multiple threads can race when updating shared call caches during method lookups # and argument forwarding. These races involve reading/writing cd->cc fields. race_top:vm_cc_call_set race_top:vm_cc_class_check race_top:vm_search_cc race_top:vm_search_method_slowpath0 race_top:rb_vm_opt_getconstant_path race_top:vm_ic_attr_index_set race:vm_ic_update race:vm_caller_setup_fwd_args # Race in shape_get_next where multiple threads simultaneously access and modify # RCLASS_MAX_IV_COUNT and RCLASS_VARIATION_COUNT fields in class objects. # One thread reads the field while another thread calls RCLASS_SET_MAX_IV_COUNT. # This happens during instance variable shape transitions in multi-threaded code. race:shape_get_next # Non-atomic reads/writes race:gccct_method_search # Ignore exit for now race:rb_ec_finalize race:rb_ec_cleanup # TSan doesn't work well post-fork, this raises errors when creating the new # timer thread race:after_fork_ruby # Sets objspace->flags.dont_incremental while writebarrier may be running race_top:objspace_each_exec race_top:objspace_each_objects_ensure # Non-atomic lazy initialized static variable race_top:rbimpl_intern_const # Setting def->aliased bitfield non-atomically race_top:method_definition_addref # Switching to setting up tracing. Likely other ractors should be stopped for this. race_top:encoded_iseq_trace_instrument race:rb_iseq_trace_set_all race:rb_tracepoint_enable # GC enable/disable flag modifications race with object allocation flag reads race_top:rb_gc_impl_gc_disable race_top:rb_gc_impl_gc_enable