I discovered data race issues during one of my audits of the EU project POP2 using Extrae.
The code I used when I ran into those issues was using Intel Thread Building Block (TBB) where threads are sometimes dynamically created.
Looking a bit deeper into Extrae, I noticed that data structures for tracing events are created for each thread which is good. However, the global management data structures that point to those data structures are reallocated when the number of threads changes. This process is not thread-safe.
Reproducer
Attached I also created a small reproducer for the problem.
The reproducer creates a pthread that is then dynamically creating more pthreads whereas the master thread is constantly spaming MPI_IProbes. Thus, there is constant access to tracing data structures conflicting with resizing data structures when the number of threads changes.
With some debugging and analysis, I created a fix for the problem by using read write locks whereas possible to keep performance up but get rid of the data races. Not sure whether I found all places.
At least the proposed changes solved the issues I had with the TBB code and the reproducer.
Further I also implemented some changes to use lock/unlock Extrae internal pthread locks directly. Otherwise these would also be instrumented which creates additional overhead.
Problem Description
I discovered data race issues during one of my audits of the EU project POP2 using Extrae. The code I used when I ran into those issues was using Intel Thread Building Block (TBB) where threads are sometimes dynamically created.
Looking a bit deeper into Extrae, I noticed that data structures for tracing events are created for each thread which is good. However, the global management data structures that point to those data structures are reallocated when the number of threads changes. This process is not thread-safe.
Reproducer
Attached I also created a small reproducer for the problem. The reproducer creates a pthread that is then dynamically creating more pthreads whereas the master thread is constantly spaming MPI_IProbes. Thus, there is constant access to tracing data structures conflicting with resizing data structures when the number of threads changes.
extrae-datarace-reproducer.zip
With the current Extrae version this results in the following seg fault:
Solution
With some debugging and analysis, I created a fix for the problem by using read write locks whereas possible to keep performance up but get rid of the data races. Not sure whether I found all places. At least the proposed changes solved the issues I had with the TBB code and the reproducer.
Further I also implemented some changes to use lock/unlock Extrae internal pthread locks directly. Otherwise these would also be instrumented which creates additional overhead.