ITADN

Very frequent false negatives in RacerD

#2020Opentener1yahoocom-lang 创建于 2026-03-13
I write test cases to evaluate RacerD concurrency issues detector. I have created several tests, but majority of them are false negative. Examples: Example 1 (if I would replace HashSet with HashMap, then RacerD can detect issues, but for HashSet no chance; I tried to add @ThreadSafe, tried to call from another class which starts two threads and calls addData/getData etc. None of the combinations detect the race. public class UnsafeSetWithSynchronized1_FALSE_NEGATIVE { private final Set<String> data = new HashSet<>(); public synchronized void addData(String value) { data.add(value); } public boolean contains(String value) { return data.contains(value); } public Set<String> getData() { return data; } } Example 2: public class UnsafeObjectConditionWithSynchronized1_FALSE_NEGATIVE { private boolean flag; public void set(boolean flag) { this.flag = flag; } public synchronized int get() { if (flag) { return 0; } else { return 1; } } } Example 3: public class UnsafeListInParallelStreamWithSynchronized_FALSE_NEGATIVE { private final List<String> data = new ArrayList<>(); public synchronized void processData(List<String> ids) { // multiple threads will try to add to the list simultaneously ids.parallelStream().forEach(id -> { data.add(id); }); } public List<String> get() { return data; } } Example 4: @ThreadSafe public class UnsafeSetWithThreadsSynchronizedAndThreadSafeAnnotation_FALSE_NEGATIVE { private final Set<String> data = new HashSet<>(); public synchronized void addData(String value) { data.add(value); } public boolean contains(String value) { return data.contains(value); } public Set<String> getData() { return data; } public static UnsafeSetWithThreadsSynchronizedAndThreadSafeAnnotation_FALSE_NEGATIVE createAndStartNew() { UnsafeSetWithThreadsSynchronizedAndThreadSafeAnnotation_FALSE_NEGATIVE instance = new UnsafeSetWithThreadsSynchronizedAndThreadSafeAnnotation_FALSE_NEGATIVE(); Thread t = new Thread(() -> { instance.addData("Auto-generated data"); }); t.start(); return instance; } public static Thread useAndStartExisting1(UnsafeSetWithThreadsSynchronizedAndThreadSafeAnnotation_FALSE_NEGATIVE existing) { Thread t = new Thread(() -> { existing.contains("Some value"); }); return t; } public static Thread useAndStartExisting2(UnsafeSetWithThreadsSynchronizedAndThreadSafeAnnotation_FALSE_NEGATIVE existing) { Thread t = new Thread(() -> { existing.addData("Some value"); }); return t; } public static Set<String> useAndStartExisting3(UnsafeSetWithThreadsSynchronizedAndThreadSafeAnnotation_FALSE_NEGATIVE existing) throws InterruptedException { Set<String> result = new HashSet<>(); Thread t = new Thread(() -> { result.addAll(existing.getData()); }); t.start(); t.join(); return result; } } And lots of other examples ... only in limited number of cases RacerD could discover some data race. I started RacerD like this ProcessBuilder pb = new ProcessBuilder( INFER_PATH, "run", "--racerd-only", "--reactive", "--no-filtering", // Disables noise filters "--", "/usr/bin/javac", "-cp", ANNOTATIONS_JAR_PATH, filePath.toString() );
0 条评论