When I started learning the valgrind (helgrind) tool, I ran into a mysterious problem that I could not handle.
In a simple user-defined stream class, a virtual function is created that will be called by the stream input routine. If so, helgrind will report a possible data race. But after a simple exclusion of a virtual keyword, such errors never appeared. Why it happens? Is there something wrong with my code? Or is there a workaround?
This is further a simple multithreaded application that demonstrates such a problem, including cpp, Makefile, and messages that transmit reports.
#include <memory.h>
#include <pthread.h>
class thread_s {
public:
pthread_t th;
thread_s(void);
~thread_s(void);
virtual void* routine();
void stop(void);
};
static void* routine(void*);
int main(int, const char*[])
{
thread_s s_v;
pthread_create(&s_v.th, 0, routine, &s_v);
return 0;
}
static void* routine(void* arg)
{
thread_s *pV = reinterpret_cast<thread_s*>(arg);
pV->routine();
return 0;
}
void* thread_s::routine(void)
{
return 0;
}
thread_s::thread_s(void)
{
th = 0;
}
thread_s::~thread_s(void)
{
stop();
}
void thread_s::stop(void)
{
void *v = 0;
pthread_join(th, &v);
}
=========================================
/* Makefile */
all: main test_helgrind
main: main.cpp
g++ -o main main.cpp \
-g -Wall -O0 \
-lpthread
test_helgrind:
valgrind \
--tool=helgrind \
./main
clean:
rm -f main
.PHONY: clean
=========================================
g++ -o main main.cpp \
-g -Wall -O0 \
-lpthread
valgrind \
./main
==7477== Helgrind, a thread error detector
==7477== Copyright (C) 2007-2010, and GNU GPL'd, by OpenWorks LLP et al.
==7477== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==7477== Command: ./main
==7477==
==7477== Thread
==7477==
==7477== Thread
==7477== at 0x4259728: clone (clone.S:111)
==7477== by 0x40484B5: pthread_create@@GLIBC_2.1 (createthread.c:256)
==7477== by 0x4026E2D: pthread_create_WRK (hg_intercepts.c:257)
==7477== by 0x4026F8B: pthread_create@* (hg_intercepts.c:288)
==7477== by 0x8048560: main (main.cpp:18)
==7477==
==7477== Possible data race during write of size 4 at 0xbeab24c8 by thread
==7477== at 0x80485C9: thread_s::~thread_s() (main.cpp:35)
==7477== by 0x8048571: main (main.cpp:17)
==7477== This conflicts with a previous read of size 4 by thread
==7477== at 0x804858B: routine(void*) (main.cpp:24)
==7477== by 0x4026F60: mythread_wrapper (hg_intercepts.c:221)
==7477== by 0x4047E98: start_thread (pthread_create.c:304)
==7477== by 0x425973D: clone (clone.S:130)
==7477==
==7477==
==7477== For counts of detected and suppressed errors, rerun with: -v
==7477== Use
==7477== the cost of reduced accuracy of conflicting-access information
==7477== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 1 from 1)