Home | History | Annotate | Download | only in tests
      1 /*
      2  * Test program that triggers strcpy() from one thread and a memory allocation
      3  * immediately after the region read by strcpy() from another thread. Without
      4  * strcpy() intercept there is about 50% chance that this test program triggers
      5  * a false positive race report on Ubuntu 12.10 amd64.
      6  *
      7  * See also https://bugs.kde.org/show_bug.cgi?id=326436.
      8  */
      9 
     10 #include <locale.h>
     11 #include <stdlib.h>
     12 #include <unistd.h>
     13 #include <pthread.h>
     14 #include <string.h>
     15 #include <string>
     16 #include <sstream>
     17 #include <list>
     18 
     19 using namespace std;
     20 
     21 class SubTest {
     22 public:
     23   SubTest() {
     24     list<int *> ffList;
     25     ffList.push_back((int *) NULL);
     26     for (list<int*>::iterator ff = ffList.begin(); ff != ffList.end(); ff++) {
     27       usleep(1000);
     28     }
     29   }
     30   void subTest() {
     31     list<int *> ffList;
     32     ffList.push_back((int *) NULL);
     33     for (list<int*>::const_iterator ff = ffList.begin(); ff != ffList.end(); ff++) {
     34       usleep(1000);
     35     }
     36   }
     37 };
     38 
     39 class Test {
     40   SubTest *subTest;
     41 public:
     42   void setUp() {
     43     subTest = new SubTest();
     44     setlocale(LC_ALL, "English");
     45   }
     46   void tearDown() {
     47     delete subTest; }
     48   void func1() {
     49     for (size_t i = 0; i < 10000; i++) {
     50       subTest->subTest();
     51       usleep(1000);
     52     }
     53   }
     54   void func2() {
     55     usleep(1000);
     56   }
     57 };
     58 
     59 void *func1(void *instance)
     60 {
     61   Test *casted = reinterpret_cast<Test*>(instance);
     62   casted->setUp();
     63   casted->func1();
     64   casted->tearDown();
     65   return NULL;
     66 }
     67 
     68 void *func2(void *instance)
     69 {
     70   Test *casted = reinterpret_cast<Test*>(instance);
     71   casted->setUp();
     72   casted->func2();
     73   casted->tearDown();
     74   return NULL;
     75 }
     76 
     77 int main(int argc, char* argv[])
     78 {
     79   int err;
     80   pthread_t thread1;
     81   pthread_t thread2;
     82   Test instance1;
     83   Test instance2;
     84 
     85   // create
     86   err = pthread_create(&thread1, NULL, &func1, &instance1);
     87   if (err != 0)
     88     throw string("failed to create a thread.");
     89   err = pthread_create(&thread2, NULL, &func2, &instance2);
     90   if (err != 0)
     91     throw string("failed to create a thread.");
     92   // join
     93   err = pthread_join(thread1, NULL);
     94   if (err != 0)
     95     throw string("Thread::join(): failed to join.");
     96   err = pthread_join(thread2, NULL);
     97   if (err != 0)
     98     throw string("Thread::join(): failed to join.");
     99 }
    100