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:
SubTest()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   }
subTest()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:
setUp()42   void setUp() {
43     subTest = new SubTest();
44     setlocale(LC_ALL, "English");
45   }
tearDown()46   void tearDown() {
47     delete subTest; }
func1()48   void func1() {
49     for (size_t i = 0; i < 10000; i++) {
50       subTest->subTest();
51       usleep(1000);
52     }
53   }
func2()54   void func2() {
55     usleep(1000);
56   }
57 };
58 
func1(void * instance)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 
func2(void * instance)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 
main(int argc,char * argv[])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