  Error invariants are assertions that over-approximate the reachable program
states at a given position in an error trace while only capturing states that
will still lead to failure if execution of the trace is continued from that
position. Such assertions reflect the effect of statements that are involved in
the root cause of an error and its propagation, enabling slicing of statements
that do not contribute to the error. Previous work on error invariants focused
on sequential programs. We generalize error invariants to concurrent traces by
augmenting them with additional information about hazards such as
write-after-write events, which are often involved in race conditions and
atomicity violations. By providing the option to include varying levels of
details in error invariants-such as hazards and branching information-our
approach allows the programmer to systematically analyze individual aspects of
an error trace.We have implemented a hazard-sensitive slicing tool for
concurrent traces based on error invariants and evaluated it on benchmarks
covering a broad range of real-world concurrency bugs. Hazard-sensitive slicing
significantly reduced the length of the considered traces and still maintained
the root causes of the concurrency bugs.
