• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <gtest/gtest.h>
2 #include <pthread.h>
3 #include <signal.h>
4 #include <stdlib.h>
5 #include <sys/mman.h>
6 #include <sys/prctl.h>
7 #include <unistd.h>
8 
9 using namespace testing::ext;
10 
11 class ThreadPthrdTest : public testing::Test {
SetUp()12     void SetUp() override {}
TearDown()13     void TearDown() override {}
14 };
15 
16 class ThreadPthrdDeathTest : public testing::Test {
SetUp()17     void SetUp() override {}
TearDown()18     void TearDown() override {}
19 };
20 
21 constexpr size_t BUF_LEN = 16;
22 constexpr size_t NAME_SIZE = 32;
23 constexpr size_t NAME_LONG_SIZE = 64;
24 
25 static std::string g_dtorOutput;
26 
27 static bool g_controlFlag = true;
28 
CancelLoop()29 static void CancelLoop()
30 {
31     g_controlFlag = false;
32 }
33 
BeginLoop(void *)34 static void* BeginLoop(void*)
35 {
36     while (g_controlFlag) {
37     }
38     return nullptr;
39 }
40 
PthreadNameNp(void * arg)41 static void* PthreadNameNp(void* arg)
42 {
43     EXPECT_EQ(0, pthread_setname_np(pthread_self(), "shortname"));
44     char name[NAME_SIZE];
45     EXPECT_EQ(0, pthread_getname_np(pthread_self(), name, sizeof(name)));
46     EXPECT_STREQ("shortname", name);
47 
48     EXPECT_EQ(0, pthread_setname_np(pthread_self(), "uselongnametest"));
49     EXPECT_EQ(0, pthread_getname_np(pthread_self(), name, sizeof(name)));
50     EXPECT_STREQ("uselongnametest", name);
51 
52     EXPECT_EQ(ERANGE, pthread_setname_np(pthread_self(), "namecannotoversixth"));
53 
54     EXPECT_EQ(0, pthread_getname_np(pthread_self(), name, BUF_LEN));
55     EXPECT_EQ(ERANGE, pthread_getname_np(pthread_self(), name, BUF_LEN - 1));
56     return nullptr;
57 }
58 
ReturnFunc(void * arg)59 static void* ReturnFunc(void* arg)
60 {
61     return arg;
62 }
63 
64 /**
65  * @tc.name: pthread_setname_np_001
66  * @tc.desc: 1. Set a unique name with a char type size of 32, and determine if it is the same after obtaining it.
67  *           2. Failed to set a name smaller than 16 bytes for the thread, with a minimum of 16 bytes
68  * @tc.type: FUNC
69  * */
70 HWTEST_F(ThreadPthrdTest, pthread_setname_np_001, TestSize.Level1)
71 {
72     void* arg = nullptr;
73     PthreadNameNp(arg);
74 }
75 
76 /**
77  * @tc.name: pthread_setname_np_002
78  * @tc.desc: In a multithreaded environment, setting flags to control the operation of a thread ensures that the logic
79  *           of setting a name for the thread can be used normally during multithreaded operation.
80  * @tc.type: FUNC
81  * */
82 HWTEST_F(ThreadPthrdTest, pthread_setname_np_002, TestSize.Level1)
83 {
84     pthread_t thread;
85     EXPECT_EQ(0, pthread_create(&thread, nullptr, PthreadNameNp, nullptr));
86     EXPECT_EQ(0, pthread_join(thread, nullptr));
87 }
88 
89 /**
90  * @tc.name: pthread_setname_np_003
91  * @tc.desc: Set a dead process and set a unique name for the dead process for death testing, returning 'Death'
92  * @tc.type: FUNC
93  * */
94 HWTEST_F(ThreadPthrdDeathTest, pthread_setname_np_003, TestSize.Level1)
95 {
96     pthread_t deadThread;
97     pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
98     pthread_join(deadThread, nullptr);
99 
100     EXPECT_DEATH(pthread_setname_np(deadThread, "short name"), ".*");
101 }
102 
103 /**
104  * @tc.name: pthread_setname_np_004
105  * @tc.desc: Set a null process and set a unique name for the dead process for death testing, returning 'Death'
106  * @tc.type: FUNC
107  * */
108 HWTEST_F(ThreadPthrdDeathTest, pthread_setname_np_004, TestSize.Level1)
109 {
110     pthread_t nullThread = 0;
111     EXPECT_DEATH(pthread_setname_np(nullThread, "short name"), ".*");
112 }
113 
114 /**
115  * @tc.name: pthread_getname_np_001
116  * @tc.desc: Set a dead process and set a unique name for the dead process for death testing, returning 'Death'
117  * @tc.type: FUNC
118  * */
119 HWTEST_F(ThreadPthrdDeathTest, pthread_getname_np_001, TestSize.Level1)
120 {
121     pthread_t deadThread;
122     pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
123     pthread_join(deadThread, nullptr);
124     char name[NAME_LONG_SIZE];
125     EXPECT_DEATH(pthread_getname_np(deadThread, name, sizeof(name)), ".*");
126 }
127 
128 /**
129  * @tc.name: pthread_getname_np_002
130  * @tc.desc: Set a null process and set a unique name for the dead process for death testing, returning 'Death'
131  * @tc.type: FUNC
132  * */
133 HWTEST_F(ThreadPthrdDeathTest, pthread_getname_np_002, TestSize.Level1)
134 {
135     pthread_t nullThread = 0;
136     char name[NAME_LONG_SIZE];
137     EXPECT_DEATH(pthread_getname_np(nullThread, name, sizeof(name)), ".*");
138 }
139 
140 /**
141  * @tc.name: pthread_sigmask_001
142  * @tc.desc: Modify the status of the SIGUSR1 signal and verify that the results are correct.
143  * @tc.type: FUNC
144  * */
145 HWTEST_F(ThreadPthrdTest, pthread_sigmask_001, TestSize.Level1)
146 {
147     sigset_t originalPthreadSignal;
148     sigset_t loadPthreadSignal;
149     sigset_t finalPthreadSignal;
150 
151     sigemptyset(&originalPthreadSignal);
152     EXPECT_EQ(0, pthread_sigmask(SIG_BLOCK, nullptr, &originalPthreadSignal));
153     EXPECT_FALSE(sigismember(&originalPthreadSignal, SIGUSR1));
154     sigemptyset(&loadPthreadSignal);
155     sigaddset(&loadPthreadSignal, SIGUSR1);
156     EXPECT_EQ(0, pthread_sigmask(SIG_BLOCK, &loadPthreadSignal, nullptr));
157     sigemptyset(&finalPthreadSignal);
158     EXPECT_EQ(0, pthread_sigmask(SIG_BLOCK, nullptr, &finalPthreadSignal));
159     EXPECT_TRUE(sigismember(&finalPthreadSignal, SIGUSR1));
160 }
161 
WaitSignalHandler(void * arg)162 static void* WaitSignalHandler(void* arg)
163 {
164     sigset_t waitSetBegin;
165     sigfillset(&waitSetBegin);
166     return reinterpret_cast<void*>(sigwait(&waitSetBegin, reinterpret_cast<int*>(arg)));
167 }
168 
169 /**
170  * @tc.name: pthread_sigmask_002
171  * @tc.desc: Create a new thread, wait for the SIGUSR1 signal to be received, and verify that the received signal
172  *           is correct
173  * @tc.type: FUNC
174  * */
175 HWTEST_F(ThreadPthrdTest, pthread_sigmask_002, TestSize.Level1)
176 {
177     sigset_t originalPthreadSignal;
178     pthread_t signalThread;
179     int receivedPthreadSignal;
180 
181     sigemptyset(&originalPthreadSignal);
182     EXPECT_EQ(0, pthread_sigmask(SIG_BLOCK, &originalPthreadSignal, nullptr));
183     EXPECT_FALSE(sigismember(&originalPthreadSignal, SIGUSR1));
184     EXPECT_EQ(0, pthread_create(&signalThread, nullptr, WaitSignalHandler, &receivedPthreadSignal));
185     pthread_kill(signalThread, SIGUSR1);
186     pthread_join(signalThread, nullptr);
187     EXPECT_EQ(SIGUSR1, receivedPthreadSignal);
188 }
189 
190 /**
191  * @tc.name: pthread_create_001
192  * @tc.desc: The normal function creation was successfully set, and the thread returned the same result as the initial
193  *           creation
194  * @tc.type: FUNC
195  * */
196 HWTEST_F(ThreadPthrdTest, pthread_create_001, TestSize.Level1)
197 {
198     void* getRes = reinterpret_cast<void*>(666);
199 
200     pthread_t thread;
201     EXPECT_EQ(0, pthread_create(&thread, nullptr, ReturnFunc, getRes));
202 
203     void* realRes;
204     EXPECT_EQ(0, pthread_join(thread, &realRes));
205     EXPECT_EQ(getRes, realRes);
206 }
207 
ThreadStr(void * arg)208 static void* ThreadStr(void* arg)
209 {
210     g_dtorOutput += *reinterpret_cast<std::string*>(arg);
211     return nullptr;
212 }
213 
214 /**
215  * @tc.name: pthread_create_002
216  * @tc.desc: When creating and waiting for a thread, the specified function of the object in the thread's
217  *           local storage can be correctly triggered, and the expected output result of the specified
218  *           function can be obtained in the main thread
219  * @tc.type: FUNC
220  * */
221 HWTEST_F(ThreadPthrdTest, pthread_create_002, TestSize.Level1)
222 {
223     std::string msg("dtor");
224     pthread_t thread;
225     EXPECT_EQ(0, pthread_create(&thread, nullptr, ThreadStr, &msg));
226     EXPECT_EQ(0, pthread_join(thread, nullptr));
227     EXPECT_EQ("dtor", g_dtorOutput);
228 }
229 
230 /**
231  * @tc.name: pthread_setcancelstate_001
232  * @tc.desc: Verify that the thread cancellation state was successfully set and verify the old state
233  * @tc.type: FUNC
234  * */
235 HWTEST_F(ThreadPthrdTest, pthread_setcancelstate_001, TestSize.Level1)
236 {
237 #ifdef FEATURE_PTHREAD_CANCEL
238     int oldstate;
239     EXPECT_EQ(0, pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate));
240     EXPECT_EQ(oldstate, PTHREAD_CANCEL_ENABLE);
241 
242     EXPECT_EQ(0, pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate));
243     EXPECT_EQ(oldstate, PTHREAD_CANCEL_DISABLE);
244 
245     EXPECT_EQ(0, pthread_setcancelstate(PTHREAD_CANCEL_MASKED, &oldstate));
246     EXPECT_EQ(oldstate, PTHREAD_CANCEL_ENABLE);
247 
248     EXPECT_EQ(0, pthread_setcancelstate(PTHREAD_CANCEL_DEFERRED, &oldstate));
249     EXPECT_EQ(oldstate, PTHREAD_CANCEL_MASKED);
250 
251     EXPECT_EQ(0, pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate));
252     EXPECT_EQ(oldstate, PTHREAD_CANCEL_DEFERRED);
253 #endif
254 }
255 
256 /**
257  * @tc.name: pthread_kill_001
258  * @tc.desc: When creating and waiting for a thread, the specified function of the object in the thread's
259  *           local storage can be correctly triggered, and the expected output result of the specified
260  *           function can be obtained in the main thread.
261  * @tc.type: FUNC
262  * */
263 HWTEST_F(ThreadPthrdTest, pthread_kill_001, TestSize.Level1)
264 {
265     EXPECT_EQ(0, pthread_kill(pthread_self(), 0));
266 }
267 
268 /**
269  * @tc.name: pthread_kill_002
270  * @tc.desc: Sending invalid signal to current thread, returning error.
271  * @tc.type: FUNC
272  * */
273 HWTEST_F(ThreadPthrdTest, pthread_kill_002, TestSize.Level1)
274 {
275     EXPECT_EQ(EINVAL, pthread_kill(pthread_self(), -6));
276 }
277 
278 /**
279  * @tc.name: pthread_kill_003
280  * @tc.desc: sending a signal to an empty thread returned an error
281  * @tc.type: FUNC
282  * */
283 HWTEST_F(ThreadPthrdDeathTest, pthread_kill_003, TestSize.Level1)
284 {
285     pthread_t nullThread = 0;
286     EXPECT_DEATH(pthread_kill(nullThread, 0), ".*");
287 }
288 
289 /**
290  * @tc.name: pthread_setschedparam_001
291  * @tc.desc: Testing the interface using dead threads
292  * @tc.type: FUNC
293  * */
294 HWTEST_F(ThreadPthrdDeathTest, pthread_setschedparam_001, TestSize.Level1)
295 {
296     pthread_t deadThread;
297     pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
298     pthread_join(deadThread, nullptr);
299 
300     int loadPolicy = 0;
301     sched_param pthreadSchedParam;
302     EXPECT_DEATH(pthread_setschedparam(deadThread, loadPolicy, &pthreadSchedParam), ".*");
303 }
304 
305 /**
306  * @tc.name: pthread_setschedparam_002
307  * @tc.desc: Testing the interface using null threads
308  * @tc.type: FUNC
309  * */
310 HWTEST_F(ThreadPthrdDeathTest, pthread_setschedparam_002, TestSize.Level1)
311 {
312     pthread_t nullThread = 0;
313     int loadPolicy = 0;
314     sched_param pthreadSchedParam;
315     EXPECT_DEATH(pthread_setschedparam(nullThread, loadPolicy, &pthreadSchedParam), ".*");
316 }
317 
318 /**
319  * @tc.name: pthread_setschedparam_003
320  * @tc.desc: Correct handling of invalid scheduling loadPolicy values
321  * @tc.type: FUNC
322  * */
323 HWTEST_F(ThreadPthrdTest, pthread_setschedparam_003, TestSize.Level1)
324 {
325     sched_param pthreadSchedParam = { .sched_priority = -6 };
326     EXPECT_EQ(EINVAL, pthread_setschedparam(pthread_self(), -6, &pthreadSchedParam));
327 }
328 
329 /**
330  * @tc.name: pthread_getschedparam_001
331  * @tc.desc: Testing the interface using dead threads
332  * @tc.type: FUNC
333  * */
334 HWTEST_F(ThreadPthrdDeathTest, pthread_getschedparam_001, TestSize.Level1)
335 {
336     pthread_t deadThread;
337     pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
338     pthread_join(deadThread, nullptr);
339 
340     int loadPolicy;
341     sched_param pthreadSchedParam;
342     EXPECT_DEATH(pthread_getschedparam(deadThread, &loadPolicy, &pthreadSchedParam), ".*");
343 }
344 
345 /**
346  * @tc.name: pthread_setschedprio_001
347  * @tc.desc: Testing the interface using dead threads
348  * @tc.type: FUNC
349  * */
350 HWTEST_F(ThreadPthrdDeathTest, pthread_setschedprio_001, TestSize.Level1)
351 {
352     pthread_t deadThread;
353     pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
354     pthread_join(deadThread, nullptr);
355 
356     EXPECT_DEATH(pthread_setschedprio(deadThread, 10), ".*");
357 }
358 
359 /**
360  * @tc.name: pthread_setschedprio_002
361  * @tc.desc: Testing the interface using null threads
362  * @tc.type: FUNC
363  * */
364 HWTEST_F(ThreadPthrdDeathTest, pthread_setschedprio_002, TestSize.Level1)
365 {
366     pthread_t nullThread = 0;
367     EXPECT_DEATH(pthread_setschedprio(nullThread, 10), ".*");
368 }
369 
370 /**
371  * @tc.name: pthread_setschedprio_003
372  * @tc.desc: Correct handling of invalid scheduling loadPolicy values
373  * @tc.type: FUNC
374  * */
375 HWTEST_F(ThreadPthrdTest, pthread_setschedprio_003, TestSize.Level1)
376 {
377     EXPECT_EQ(EINVAL, pthread_setschedprio(pthread_self(), 1000));
378 }
379 
380 /**
381  * @tc.name: pthread_getcpuclockid_001
382  * @tc.desc: Successfully called the function on the thread
383  * @tc.type: FUNC
384  * */
385 HWTEST_F(ThreadPthrdTest, pthread_getcpuclockid_001, TestSize.Level1)
386 {
387     g_controlFlag = true;
388     pthread_t thread;
389     clockid_t realClock;
390     timespec times;
391     EXPECT_EQ(0, pthread_create(&thread, nullptr, BeginLoop, nullptr));
392     EXPECT_EQ(0, pthread_getcpuclockid(thread, &realClock));
393     EXPECT_EQ(0, clock_gettime(realClock, &times));
394     CancelLoop();
395     EXPECT_EQ(0, pthread_join(thread, nullptr));
396 }
397 
398 /**
399  * @tc.name: pthread_getcpuclockid_002
400  * @tc.desc: Using dead threads for death testing This interface returns invalid threads
401  * @tc.type: FUNC
402  * */
403 HWTEST_F(ThreadPthrdDeathTest, pthread_getcpuclockid_002, TestSize.Level1)
404 {
405     pthread_t deadThread;
406     clockid_t realClock;
407     pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
408     pthread_join(deadThread, nullptr);
409     EXPECT_DEATH(pthread_getcpuclockid(deadThread, &realClock), ".*");
410 }
411 
412 /**
413  * @tc.name: pthread_getcpuclockid_003
414  * @tc.desc: Using null threads for death testing This interface returns invalid threads
415  * @tc.type: FUNC
416  * */
417 HWTEST_F(ThreadPthrdDeathTest, pthread_getcpuclockid_003, TestSize.Level1)
418 {
419     pthread_t nullThread = 0;
420     clockid_t c;
421     EXPECT_DEATH(pthread_getcpuclockid(nullThread, &c), ".*");
422 }
423 
JoinThrd(void * arg)424 static void* JoinThrd(void* arg)
425 {
426     return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), nullptr));
427 }
428 
429 /**
430  * @tc.name: pthread_join_002
431  * @tc.desc: Create thread thread1, strongly convert thread1 into a parameter of thread thread2, and set the destructor
432  * of thread2 to add thread1 to pthread_join, call pthread again_ Invalid return for detach (thread1), determine if
433  * thread1 does not end with a detached attribute
434  * @tc.type: FUNC
435  * */
436 HWTEST_F(ThreadPthrdDeathTest, pthread_join_002, TestSize.Level1)
437 {
438     g_controlFlag = true;
439     pthread_t thread1;
440     pthread_create(&thread1, nullptr, BeginLoop, nullptr);
441     pthread_t thread2;
442     pthread_create(&thread2, nullptr, JoinThrd, reinterpret_cast<void*>(thread1));
443 
444     sleep(1);
445     EXPECT_DEATH(pthread_detach(thread1), ".*");
446     pthread_attr_t detachAttr;
447     EXPECT_DEATH(pthread_getattr_np(thread1, &detachAttr), ".*");
448     int detachState;
449     pthread_attr_getdetachstate(&detachAttr, &detachState);
450     pthread_attr_destroy(&detachAttr);
451     EXPECT_EQ(PTHREAD_CREATE_JOINABLE, detachState);
452 
453     CancelLoop();
454 
455     void* joinResult;
456     EXPECT_EQ(0, pthread_join(thread2, &joinResult));
457     EXPECT_EQ(0U, reinterpret_cast<uintptr_t>(joinResult));
458 }
459 
460 /**
461  * @tc.name: pthread_join_003
462  * @tc.desc: Test that two identical threads call the function successively. The first time it succeeds, the second time
463  *           it fails, and finally verify the results of the first call
464  * @tc.type: FUNC
465  * */
466 HWTEST_F(ThreadPthrdDeathTest, pthread_join_003, TestSize.Level1)
467 {
468     g_controlFlag = true;
469     pthread_t thread1;
470     pthread_create(&thread1, nullptr, BeginLoop, nullptr);
471 
472     pthread_t thread2;
473     pthread_create(&thread2, nullptr, JoinThrd, reinterpret_cast<void*>(thread1));
474 
475     sleep(1);
476 
477     EXPECT_DEATH(pthread_join(thread1, nullptr), ".*");
478 
479     CancelLoop();
480 
481     void* joinResult;
482     EXPECT_EQ(0, pthread_join(thread2, &joinResult));
483     EXPECT_EQ(0U, reinterpret_cast<uintptr_t>(joinResult));
484 }
485 
486 /**
487  * @tc.name: pthread_join_004
488  * @tc.desc: Testing the interface using dead threads returns invalid threads
489  * @tc.type: FUNC
490  * */
491 HWTEST_F(ThreadPthrdDeathTest, pthread_join_004, TestSize.Level1)
492 {
493     pthread_t deadThread;
494     pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
495     pthread_join(deadThread, nullptr);
496 
497     EXPECT_DEATH(pthread_join(deadThread, nullptr), ".*");
498 }
499 
500 /**
501  * @tc.name: pthread_join_005
502  * @tc.desc: Testing the interface using null threads returns invalid threads
503  * @tc.type: FUNC
504  * */
505 HWTEST_F(ThreadPthrdDeathTest, pthread_join_005, TestSize.Level1)
506 {
507     pthread_t nullThread = 0;
508     EXPECT_DEATH(pthread_join(nullThread, nullptr), ".*");
509 }
510 
511 struct PthreadGettidArg {
512     pid_t tid = 0;
513     pthread_mutex_t mutex;
514 };
515 
ThreadGettidNpFn(PthreadGettidArg * arg)516 static void* ThreadGettidNpFn(PthreadGettidArg* arg)
517 {
518     if (arg == nullptr) {
519         return nullptr;
520     }
521     arg->tid = gettid();
522     pthread_mutex_lock(&arg->mutex);
523     pthread_mutex_unlock(&arg->mutex);
524     return nullptr;
525 }
526 
527 /**
528  * @tc.name: pthread_gettid_np_001
529  * @tc.desc: Get the ID of the current thread for comparison and equality.
530  * @tc.type: FUNC
531  * */
532 HWTEST_F(ThreadPthrdTest, pthread_gettid_np_001, TestSize.Level1)
533 {
534     EXPECT_EQ(gettid(), pthread_gettid_np(pthread_self()));
535 }
536 
537 /**
538  * @tc.name: pthread_gettid_np_002
539  * @tc.desc: 1. Get the ID of the current thread for comparison and equality.
540  *           2. Call the getid function in the new thread to get the ID equal to the main function ID
541 
542  * @tc.type: FUNC
543  * */
544 HWTEST_F(ThreadPthrdTest, pthread_gettid_np_002, TestSize.Level1)
545 {
546     pthread_t thread;
547     pthread_mutex_t pMutex = PTHREAD_MUTEX_INITIALIZER;
548     PthreadGettidArg arg;
549     arg.mutex = pMutex;
550     pthread_mutex_lock(&arg.mutex);
551     pthread_create(&thread, nullptr, reinterpret_cast<void* (*)(void*)>(ThreadGettidNpFn), &arg);
552     pid_t resultTid = pthread_gettid_np(thread);
553     pthread_mutex_unlock(&arg.mutex);
554     EXPECT_EQ(0, pthread_join(thread, nullptr));
555     EXPECT_EQ(arg.tid, resultTid);
556 }
557 
ThreadExitFunc(void * arg)558 void* ThreadExitFunc(void* arg)
559 {
560     const char* message = "pthread_exit";
561     pthread_exit(const_cast<void*>(static_cast<const void*>(message)));
562 }
563 
564 /**
565  * @tc.name: pthread_exit_001
566  * @tc.desc: Verify pthread_exit process success
567  * @tc.type: FUNC
568  */
569 HWTEST_F(ThreadPthrdTest, pthread_exit_001, TestSize.Level1)
570 {
571     pthread_t ph;
572     EXPECT_EQ(0, pthread_create(&ph, nullptr, ThreadExitFunc, nullptr));
573     void* resultFn = nullptr;
574     EXPECT_EQ(0, pthread_join(ph, &resultFn));
575     EXPECT_STREQ("pthread_exit", (char*)resultFn);
576 }