How to unit test race conditions



  • I think the title says it all. Any idea on the table is welcome.

    Background:
    I have a class that is not thread safe and I'm trying to write a bridge between this class API and the rest of the world to make it thread safe so the whole point of the class is to eliminate existing race conditions. How do I test I was successful?



  • Build your code and tests with compile-time instrumentation like ThreadSanitizer, or use run-time instrumentation e.g. Helgrind



  • Thanks, I think that is the best you can do for "unknown unknowns" but there must be something better for "known unknowns".

    Take this simple example (it probably doesn't compile but gives you the idea):

    int gloabalInt=0;
    class ThreadUnsafeClass{
    public:
    int getValue() const {return gloabalInt;}
    void setValue(int val){gloabalInt=val;}
    };
    class ThreadSafeClass{
    ThreadUnsafeClass base;
    static QMutex safeMutex;
    public:
    int getValue() const {QMutexLocker(&safeMutex); return base.getValue();}
    void setValue(int val) {QMutexLocker(&safeMutex); return base.setValue(val);}
    };
    

    I know exactly where the race condition is in ThreadUnsafeClass, can I do something better than -fsanitize=thread to test the same race does not happen in ThreadSafeClass?


  • Qt Champions 2017

    You do realize ThreadSafeClass isn't thread-safe, right?

    can I do something better than -fsanitize=thread to test the same race does not happen in ThreadSafeClass?

    I can't think of anything specific right now. But just for completeness - you usually follow the data when dealing with concurrent access, so if the original data's access is serialized at all times then it's thread safe. If not, then not. If you have a concrete case and can share it, please do.



  • @kshegunov said in How to unit test race conditions:

    You do realize ThreadSafeClass isn't thread-safe, right?

    And for those of us idly following this conversation, that would be because..... ?


  • Qt Champions 2017

    int gloabalInt=0;
    

    It can be modified outside the context of the class, so while @VRonin's mutex does provide serialization to all accesses made through ThreadSafeClass, it does not address the problem in entirety. If the integer was a private field in ThreadUnsafeClass, then all would've been well.



  • @kshegunov
    Ah, OK, a "language" thing. Yes I understood that, I assumed if everything does go through ThreadSafeClass.


  • Qt Champions 2017

    Yeah globals are tricky, if it's not in the class in the first place, one could justifiably assume it's supposed to be used globally, hence protecting the access through a mutex in the class can only do so much. If you make sure you don't touch the global outside the class, then you have no problem of course.


  • Moderators

    I think valgrind actually will catch them by checking on multiple memory accesses. I can't remember for sure if it does or not.

    What I usually do is just thrown stuff at my threads as fast as possible via a test to try to have the race condition pop up.

    AFAIK there is no really easy way to detect them. That's why they are so nasty to deal with.



  • @kshegunov said in How to unit test race conditions:

    It can be modified outside the context of the class

    Good spot but in this small example I was just assuming everything goes through ThreadUnsafeClass

    @ambershark said in How to unit test race conditions:

    just thrown stuff at my threads as fast as possible via a test to try to have the race condition pop up.

    That's what I'm doing at the moment but I felt like I was doing a dumb thing because I didn't know the correct solution

    Thanks everyone. At least I feel a little less unconfortable by not being able to reliably data-test this


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.