Race conditions are inherently a result of non-determinism. If you cannot ensure that the calling sequence is secure, then introduce a number of run-time checks that verify the protocol invariants are honoured. Then, at least you will have evidence of a fault whenever they occur.
While this won't solve your problem, it at least gives you a tool to quantify the extent of the problem.
If any of the races are triggered from events outside the scope of the application, then any static analysis would require this to also be modeled to be able to detect the conditions.