Bug 518750

Summary: Thread creation via class QThread triggers data races
Product: [Fedora] Fedora Reporter: Bart Van Assche <bart.vanassche+redhat>
Component: qtAssignee: Than Ngo <than>
Status: CLOSED WONTFIX QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: 13CC: kevin, ltinkl, rdieter, than
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-06-27 14:21:21 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Bart Van Assche 2009-08-22 10:01:09 UTC
Description of problem:
Creating one or more threads by deriving a class from QThread and by calling QThread::start() and QThread::wait() triggers several data races.


Version-Release number of selected component (if applicable):
$ rpm -q qt
qt-4.5.2-2.fc11.x86_64


How reproducible: 100% with the instructions below.


Steps to Reproduce:
1. Make sure that the qt-devel RPM and the necessary tools are installed:
   yum install qt-devel autoconf automake subversion gcc gcc-c++ gdb
2. Compile and install Valgrind as follows:
   svn co -r10854 svn://svn.valgrind.org/valgrind/trunk valgrind-r10854 && cd valgrind-r10854 && ./autogen.sh && ./configure && make -s && make -s check
3. Run the following command:
   for ((i=0;i<20;i++)); do ./vg-in-place --tool=drd --check-stack-var=yes --read-var-info=yes --show-confl-seg=yes --db-attach=yes drd/tests/qt4_rwlock; done


Actual results: DRD reports a data race, pauses and asks whether gdb should be started.


Expected results: DRD does neither report any data race on the test program nor asks whether gdb should be started.


Additional info:
The call stack of the first reported data race is as follows:
==31048== drd, a thread error detector                                         
==31048== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche.          
==31048== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info    
==31048== Command: drd/tests/qt4_rwlock                                        
==31048==                                                                      
Start of test.                                                                 
==31048== Conflicting store by thread 1 at 0x04c2f608 size 8                   
==31048==    at 0x3B5E153428: QObject::QObject(QObjectPrivate&, QObject*) (in /usr/lib64/libQtCore.so.4.5.2)                                                  
==31048==    by 0x3B5E057A0D: QThread::QThread(QObject*) (in /usr/lib64/libQtCore.so.4.5.2)                                                                   
==31048==    by 0x40126A: IncThread::IncThread() (qt4_rwlock.cpp:32)           
==31048==    by 0x401368: main (qt4_rwlock.cpp:74)                             
==31048== Address 0x4c2f608 is at offset 8 from 0x4c2f600. Allocation context: 
==31048==    at 0x4A08934: operator new(unsigned long) (vg_replace_malloc.c:220)                                                                              
==31048==    by 0x40135D: main (qt4_rwlock.cpp:74)                             
==31048== Other segment start (thread 2)                                       
==31048==    at 0x4A0A90F: pthread_mutex_unlock (drd_pthread_intercepts.c:633) 
==31048==    by 0x3B5405572E: g_slice_alloc (in /lib64/libglib-2.0.so.0.2000.4)
==31048==    by 0x3B5402A832: g_hash_table_new_full (in /lib64/libglib-2.0.so.0.2000.4)
==31048==    by 0x3B5406B7E1: g_get_language_names (in /lib64/libglib-2.0.so.0.2000.4)
==31048==    by 0x3B5E169396: QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(_GMainContext*) (in /usr/lib64/libQtCore.so.4.5.2)
==31048==    by 0x3B5E16956F: QEventDispatcherGlib::QEventDispatcherGlib(QObject*) (in /usr/lib64/libQtCore.so.4.5.2)
==31048==    by 0x3B5E059B4E: ??? (in /usr/lib64/libQtCore.so.4.5.2)
==31048==    by 0x3B5E059CB4: ??? (in /usr/lib64/libQtCore.so.4.5.2)
==31048==    by 0x4A13250: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==31048==    by 0x3B53406869: start_thread (in /lib64/libpthread-2.10.1.so)
==31048==    by 0x3B528DE39C: clone (in /lib64/libc-2.10.1.so)
==31048== Other segment end (thread 2)
==31048==    at 0x4A13CF6: QMutex::unlock() (drd_qtcore_intercepts.c:205)
==31048==    by 0x3B5E169372: QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(_GMainContext*) (in /usr/lib64/libQtCore.so.4.5.2)
==31048==    by 0x3B5E16956F: QEventDispatcherGlib::QEventDispatcherGlib(QObject*) (in /usr/lib64/libQtCore.so.4.5.2)
==31048==    by 0x3B5E059B4E: ??? (in /usr/lib64/libQtCore.so.4.5.2)
==31048==    by 0x3B5E059CB4: ??? (in /usr/lib64/libQtCore.so.4.5.2)
==31048==    by 0x4A13250: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==31048==    by 0x3B53406869: start_thread (in /lib64/libpthread-2.10.1.so)
==31048==    by 0x3B528DE39C: clone (in /lib64/libc-2.10.1.so)
==31048==
==31048==
==31048== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ----

Comment 1 Kevin Kofler 2009-08-22 10:47:56 UTC
There is no qt4 package in Fedora anymore, reassigning to qt.

Comment 2 Bart Van Assche 2009-08-23 07:39:04 UTC
Source code of the test program:

$ svn cat -r10854 svn://svn.valgrind.org/valgrind/trunk/drd/tests/qt4_mutex.cpp                                           
/// Qt4 mutex test.                                                            

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif             

#include "config.h"
#include <QMutex>         // class QMutex
#include <QThread>        // class QThread
#include <cassert>                        
#include <cstdio>         // fprintf()    
#include <cstdlib>        // atoi()       
#include <new>                            
#include <pthread.h>      // pthread_barrier_t
#include <vector>                             


static pthread_barrier_t s_barrier;
static QMutex* s_pMutex;           
static int s_iterations;           
static int s_counter;              


class IncThread: public QThread
{                              
  virtual void run();          
};                             

void IncThread::run()
{                    
  int i;             

  pthread_barrier_wait(&s_barrier);
  for (i = s_iterations; i > 0; i--)
  {                                 
    s_pMutex->lock();               
    s_counter++;                    
    s_pMutex->unlock();             
  }                                 
}                                   

int main(int argc, char** argv)
{                              
  int i;                       
  const int n_threads = 10;    
  std::vector<QThread*> tid(n_threads);

  s_iterations = argc > 1 ? atoi(argv[1]) : 1000;

  fprintf(stderr, "Start of test.\n");

  {
    // Stack-allocated mutex.
    QMutex M(QMutex::Recursive);
    M.lock();                   
    assert(M.tryLock());        
    M.unlock();                 
    M.unlock();                 
  }                             
#if defined(HAVE_QTCORE_QMUTEX_TRYLOCK_INT)
  {                                        
    QMutex M(QMutex::NonRecursive);        
    assert(M.tryLock(1));                  
    assert(! M.tryLock(1));                
    M.unlock();                            
  }                                        
#endif

  pthread_barrier_init(&s_barrier, 0, n_threads);
  s_pMutex = new QMutex();
  for (i = 0; i < n_threads; i++)
  {
    tid[i] = new IncThread;
    tid[i]->start();
  }
  for (i = 0; i < n_threads; i++)
  {
    tid[i]->wait();
    delete tid[i];
  }
  delete s_pMutex;
  s_pMutex = 0;
  pthread_barrier_destroy(&s_barrier);

  if (s_counter == n_threads * s_iterations)
    fprintf(stderr, "Test successful.\n");
  else
    fprintf(stderr, "Test failed: counter = %d, should be %d\n",
            s_counter, n_threads * s_iterations);

  return 0;
}

Comment 3 Rex Dieter 2010-03-23 12:57:02 UTC
I'd suggest upstreaming this to nokia , esp since there's a test-case.

(after confirming it's still a problem with qt-4.6.x).

Comment 4 Bart Van Assche 2010-03-23 17:26:28 UTC
A related upstream bug report can be found here: http://bugreports.qt.nokia.com/browse/QTBUG-5655. This bug report has already been acknowledged by Nokia.

Comment 5 Bug Zapper 2010-04-28 09:53:37 UTC
This message is a reminder that Fedora 11 is nearing its end of life.
Approximately 30 (thirty) days from now Fedora will stop maintaining
and issuing updates for Fedora 11.  It is Fedora's policy to close all
bug reports from releases that are no longer maintained.  At that time
this bug will be closed as WONTFIX if it remains open with a Fedora 
'version' of '11'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version prior to Fedora 11's end of life.

Bug Reporter: Thank you for reporting this issue and we are sorry that 
we may not be able to fix it before Fedora 11 is end of life.  If you 
would still like to see this bug fixed and are able to reproduce it 
against a later version of Fedora please change the 'version' of this 
bug to the applicable version.  If you are unable to change the version, 
please add a comment here and someone will do it for you.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events.  Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

The process we are following is described here: 
http://fedoraproject.org/wiki/BugZappers/HouseKeeping

Comment 6 Bug Zapper 2011-06-02 17:48:57 UTC
This message is a reminder that Fedora 13 is nearing its end of life.
Approximately 30 (thirty) days from now Fedora will stop maintaining
and issuing updates for Fedora 13.  It is Fedora's policy to close all
bug reports from releases that are no longer maintained.  At that time
this bug will be closed as WONTFIX if it remains open with a Fedora 
'version' of '13'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version prior to Fedora 13's end of life.

Bug Reporter: Thank you for reporting this issue and we are sorry that 
we may not be able to fix it before Fedora 13 is end of life.  If you 
would still like to see this bug fixed and are able to reproduce it 
against a later version of Fedora please change the 'version' of this 
bug to the applicable version.  If you are unable to change the version, 
please add a comment here and someone will do it for you.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events.  Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

The process we are following is described here: 
http://fedoraproject.org/wiki/BugZappers/HouseKeeping

Comment 7 Bug Zapper 2011-06-27 14:21:21 UTC
Fedora 13 changed to end-of-life (EOL) status on 2011-06-25. Fedora 13 is 
no longer maintained, which means that it will not receive any further 
security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of 
Fedora please feel free to reopen this bug against that version.

Thank you for reporting this bug and we are sorry it could not be fixed.