Skip to content

Very frequent false negatives in RacerD #2020

@tener1yahoocom-lang

Description

@tener1yahoocom-lang

I write test cases to evaluate RacerD concurrency issues detection rate. 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 start RacerD in following way:

            ProcessBuilder pb = new ProcessBuilder(
                INFER_PATH, "run", 
                "--racerd-only", 
                "--reactive", 
                "--no-filtering",         // Disables noise filters
                "--", "/usr/bin/javac", "-cp", ANNOTATIONS_JAR_PATH, filePath.toString()
            );

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions