I have a bit of code with a race condition in it... I know that it is a race condition because it does not happen consistently, and it seems to happen more often on dual core machines.
It never happens when I'm tracing. Although, there is a possibility that it could be a deadlock as well. By analyzing stages of completion of logs where this does and does not occur, I've been able to pinpoint this bug to a single function. However, I do not know where in the scope of the function this is happening. It's not at the top level.
Adding log statements or breakpoints is going to change the timing if it is a race condition, and prevent this from happening.
Is there any technique that I can use aside from getting a race condition analyzer that will allow me to pinpoint where this is happening?
This is in visual studio 9, with C++ (of the nonmanaged variety).
Programmers use dynamic and static analysis tools to identify race conditions. Static testing tools scan a program without running it. However, they produce many false reports. Dynamic analysis tools have fewer false reports, but they may not catch race conditions that aren't executed directly within the program.
To avoid race conditions, any operation on a shared resource – that is, on a resource that can be shared between threads – must be executed atomically. One way to achieve atomicity is by using critical sections — mutually exclusive parts of the program.
RacerX This flow-sensitive static analysis tool is used for detecting races and deadlocks.
A Race condition is a scenario that occurs in a multithreaded environment due to multiple threads sharing the same resource or executing the same piece of code. If not handled properly, this can lead to an undesirable situation, where the output state is dependent on the order of execution of the threads.
There is a tool included in CLang and gcc 4.8+ called ThreadSanitizer.
You compile your code using the -fsanitize=thread
flag
Example:
$ cat simple_race.cc
#include <pthread.h>
#include <stdio.h>
int Global;
void *Thread1(void *x) {
Global++;
return NULL;
}
void *Thread2(void *x) {
Global--;
return NULL;
}
int main() {
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
pthread_join(t[0], NULL);
pthread_join(t[1], NULL);
}
And the output
$ clang++ simple_race.cc -fsanitize=thread -fPIE -pie -g
$ ./a.out
==================
WARNING: ThreadSanitizer: data race (pid=26327)
Write of size 4 at 0x7f89554701d0 by thread T1:
#0 Thread1(void*) simple_race.cc:8 (exe+0x000000006e66)
Previous write of size 4 at 0x7f89554701d0 by thread T2:
#0 Thread2(void*) simple_race.cc:13 (exe+0x000000006ed6)
Thread T1 (tid=26328, running) created at:
#0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b)
#1 main simple_race.cc:19 (exe+0x000000006f39)
Thread T2 (tid=26329, running) created at:
#0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b)
#1 main simple_race.cc:20 (exe+0x000000006f63)
==================
ThreadSanitizer: reported 1 warnings
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With