1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#include <gtest/gtest.h> 17800b99b8Sopenharmony_ci 18800b99b8Sopenharmony_ci#include <cerrno> 19800b99b8Sopenharmony_ci#include <cinttypes> 20800b99b8Sopenharmony_ci#include <cstdio> 21800b99b8Sopenharmony_ci#include <cstring> 22800b99b8Sopenharmony_ci#include <thread> 23800b99b8Sopenharmony_ci#include <vector> 24800b99b8Sopenharmony_ci 25800b99b8Sopenharmony_ci#include <pthread.h> 26800b99b8Sopenharmony_ci 27800b99b8Sopenharmony_ci#include "lock_parser.h" 28800b99b8Sopenharmony_ci#include "unwinder.h" 29800b99b8Sopenharmony_ci#include "unwinder_config.h" 30800b99b8Sopenharmony_ci 31800b99b8Sopenharmony_ciusing namespace OHOS::HiviewDFX; 32800b99b8Sopenharmony_ciusing namespace testing::ext; 33800b99b8Sopenharmony_ciusing namespace std; 34800b99b8Sopenharmony_ci 35800b99b8Sopenharmony_cinamespace OHOS { 36800b99b8Sopenharmony_cinamespace HiviewDFX { 37800b99b8Sopenharmony_ciclass LockParserUnittest : public testing::Test { 38800b99b8Sopenharmony_cipublic: 39800b99b8Sopenharmony_ci static void SetUpTestCase(void); 40800b99b8Sopenharmony_ci static void TearDownTestCase(void); 41800b99b8Sopenharmony_ci void SetUp(); 42800b99b8Sopenharmony_ci void TearDown(); 43800b99b8Sopenharmony_ci}; 44800b99b8Sopenharmony_ci} // namespace HiviewDFX 45800b99b8Sopenharmony_ci} // namespace OHOS 46800b99b8Sopenharmony_ci 47800b99b8Sopenharmony_civoid LockParserUnittest::SetUpTestCase(void) 48800b99b8Sopenharmony_ci{ 49800b99b8Sopenharmony_ci UnwinderConfig::SetEnableMiniDebugInfo(true); 50800b99b8Sopenharmony_ci UnwinderConfig::SetEnableLoadSymbolLazily(true); 51800b99b8Sopenharmony_ci} 52800b99b8Sopenharmony_ci 53800b99b8Sopenharmony_civoid LockParserUnittest::TearDownTestCase(void) 54800b99b8Sopenharmony_ci{ 55800b99b8Sopenharmony_ci} 56800b99b8Sopenharmony_ci 57800b99b8Sopenharmony_civoid LockParserUnittest::SetUp(void) 58800b99b8Sopenharmony_ci{ 59800b99b8Sopenharmony_ci} 60800b99b8Sopenharmony_ci 61800b99b8Sopenharmony_civoid LockParserUnittest::TearDown(void) 62800b99b8Sopenharmony_ci{ 63800b99b8Sopenharmony_ci} 64800b99b8Sopenharmony_ci 65800b99b8Sopenharmony_cinamespace { 66800b99b8Sopenharmony_ciconstexpr const int LOCK_TYPE_IDX = 0; 67800b99b8Sopenharmony_ciconstexpr const int LOCK_OWNER_IDX = 1; 68800b99b8Sopenharmony_ciconstexpr const int LOCK_OWNER_MASK = 0x3fffffff; 69800b99b8Sopenharmony_civoid InitMutexByType(int32_t type, pthread_mutex_t& mutex) 70800b99b8Sopenharmony_ci{ 71800b99b8Sopenharmony_ci pthread_mutexattr_t mutexAttr; 72800b99b8Sopenharmony_ci pthread_mutexattr_init(&mutexAttr); 73800b99b8Sopenharmony_ci pthread_mutexattr_settype(&mutexAttr, type); 74800b99b8Sopenharmony_ci 75800b99b8Sopenharmony_ci pthread_mutex_init(&mutex, &mutexAttr); 76800b99b8Sopenharmony_ci pthread_mutexattr_destroy(&mutexAttr); 77800b99b8Sopenharmony_ci} 78800b99b8Sopenharmony_ci 79800b99b8Sopenharmony_civoid LockMutex(pthread_mutex_t& mutex) 80800b99b8Sopenharmony_ci{ 81800b99b8Sopenharmony_ci auto mutexInt = reinterpret_cast<int*>(&mutex); 82800b99b8Sopenharmony_ci printf("mutex address:%llx\n", reinterpret_cast<long long>(&mutex)); 83800b99b8Sopenharmony_ci printf("mutex owner before lock:%d\n", mutexInt[LOCK_OWNER_IDX]); 84800b99b8Sopenharmony_ci pthread_mutex_lock(&mutex); 85800b99b8Sopenharmony_ci printf("mutex owner after lock:%d\n", mutexInt[LOCK_OWNER_IDX]); 86800b99b8Sopenharmony_ci} 87800b99b8Sopenharmony_ci 88800b99b8Sopenharmony_civoid WaitThreadBlock(int& tid) 89800b99b8Sopenharmony_ci{ 90800b99b8Sopenharmony_ci while (true) { 91800b99b8Sopenharmony_ci if (tid > 0) { 92800b99b8Sopenharmony_ci printf("WaitThreadBlock:%d\n", tid); 93800b99b8Sopenharmony_ci break; 94800b99b8Sopenharmony_ci } 95800b99b8Sopenharmony_ci sleep(1); 96800b99b8Sopenharmony_ci } 97800b99b8Sopenharmony_ci} 98800b99b8Sopenharmony_ci 99800b99b8Sopenharmony_ci/** 100800b99b8Sopenharmony_ci * @tc.name: LockParserUnittest001 101800b99b8Sopenharmony_ci * @tc.desc: unwinder parse errorcheck lock owner 102800b99b8Sopenharmony_ci * @tc.type: FUNC 103800b99b8Sopenharmony_ci */ 104800b99b8Sopenharmony_ciHWTEST_F(LockParserUnittest, LockParserUnittest001, TestSize.Level2) 105800b99b8Sopenharmony_ci{ 106800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "LockParserUnittest001: start."; 107800b99b8Sopenharmony_ci pthread_mutex_t mutex; 108800b99b8Sopenharmony_ci InitMutexByType(PTHREAD_MUTEX_ERRORCHECK, mutex); 109800b99b8Sopenharmony_ci 110800b99b8Sopenharmony_ci auto mutexInt = reinterpret_cast<int*>(&mutex); 111800b99b8Sopenharmony_ci LockMutex(mutex); 112800b99b8Sopenharmony_ci 113800b99b8Sopenharmony_ci int tid = 0; 114800b99b8Sopenharmony_ci std::thread t1([&tid, &mutex] { 115800b99b8Sopenharmony_ci tid = gettid(); 116800b99b8Sopenharmony_ci printf("BlockTid:%d\n", tid); 117800b99b8Sopenharmony_ci pthread_mutex_lock(&mutex); 118800b99b8Sopenharmony_ci }); 119800b99b8Sopenharmony_ci 120800b99b8Sopenharmony_ci WaitThreadBlock(tid); 121800b99b8Sopenharmony_ci printf("CurrentTid:%d BlockTid:%d\n", gettid(), tid); 122800b99b8Sopenharmony_ci auto unwinder = std::make_shared<Unwinder>(true); 123800b99b8Sopenharmony_ci ASSERT_EQ(unwinder->UnwindLocalWithTid(tid), true); 124800b99b8Sopenharmony_ci 125800b99b8Sopenharmony_ci std::vector<uintptr_t> pcs = unwinder->GetPcs(); 126800b99b8Sopenharmony_ci ASSERT_FALSE(pcs.empty()); 127800b99b8Sopenharmony_ci 128800b99b8Sopenharmony_ci std::vector<DfxFrame> frames; 129800b99b8Sopenharmony_ci (void)unwinder->GetFramesByPcs(frames, pcs); 130800b99b8Sopenharmony_ci ASSERT_FALSE(frames.empty()); 131800b99b8Sopenharmony_ci unwinder->SetFrames(frames); 132800b99b8Sopenharmony_ci 133800b99b8Sopenharmony_ci std::vector<char> buffer(sizeof(pthread_mutex_t), 0); 134800b99b8Sopenharmony_ci if (!unwinder->GetLockInfo(tid, buffer.data(), sizeof(pthread_mutex_t))) { 135800b99b8Sopenharmony_ci ASSERT_TRUE(false); 136800b99b8Sopenharmony_ci } 137800b99b8Sopenharmony_ci 138800b99b8Sopenharmony_ci if (memcmp(buffer.data(), &mutex, sizeof(pthread_mutex_t)) != 0) { 139800b99b8Sopenharmony_ci ASSERT_TRUE(false); 140800b99b8Sopenharmony_ci } 141800b99b8Sopenharmony_ci 142800b99b8Sopenharmony_ci int lockOwner = mutexInt[LOCK_OWNER_IDX] & LOCK_OWNER_MASK; 143800b99b8Sopenharmony_ci ASSERT_EQ(gettid(), lockOwner); 144800b99b8Sopenharmony_ci printf("CurrentTid:%d Lock owner:%d\n", gettid(), lockOwner); 145800b99b8Sopenharmony_ci ASSERT_EQ(PTHREAD_MUTEX_ERRORCHECK, mutexInt[LOCK_TYPE_IDX]); 146800b99b8Sopenharmony_ci pthread_mutex_unlock(&mutex); 147800b99b8Sopenharmony_ci if (t1.joinable()) { 148800b99b8Sopenharmony_ci t1.join(); 149800b99b8Sopenharmony_ci } 150800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "LockParserUnittest001: end."; 151800b99b8Sopenharmony_ci} 152800b99b8Sopenharmony_ci 153800b99b8Sopenharmony_ci/** 154800b99b8Sopenharmony_ci * @tc.name: LockParserUnittest002 155800b99b8Sopenharmony_ci * @tc.desc: unwinder parse normal lock owner 156800b99b8Sopenharmony_ci * @tc.type: FUNC 157800b99b8Sopenharmony_ci */ 158800b99b8Sopenharmony_ciHWTEST_F(LockParserUnittest, LockParserUnittest002, TestSize.Level2) 159800b99b8Sopenharmony_ci{ 160800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "LockParserUnittest002: start."; 161800b99b8Sopenharmony_ci pthread_mutex_t mutex; 162800b99b8Sopenharmony_ci InitMutexByType(PTHREAD_MUTEX_NORMAL, mutex); 163800b99b8Sopenharmony_ci 164800b99b8Sopenharmony_ci auto mutexInt = reinterpret_cast<int*>(&mutex); 165800b99b8Sopenharmony_ci LockMutex(mutex); 166800b99b8Sopenharmony_ci 167800b99b8Sopenharmony_ci int tid = 0; 168800b99b8Sopenharmony_ci std::thread t1([&tid, &mutex] { 169800b99b8Sopenharmony_ci tid = gettid(); 170800b99b8Sopenharmony_ci printf("BlockTid:%d\n", tid); 171800b99b8Sopenharmony_ci pthread_mutex_lock(&mutex); 172800b99b8Sopenharmony_ci }); 173800b99b8Sopenharmony_ci 174800b99b8Sopenharmony_ci WaitThreadBlock(tid); 175800b99b8Sopenharmony_ci printf("CurrentTid:%d BlockTid:%d\n", gettid(), tid); 176800b99b8Sopenharmony_ci auto unwinder = std::make_shared<Unwinder>(true); 177800b99b8Sopenharmony_ci ASSERT_EQ(unwinder->UnwindLocalWithTid(tid), true); 178800b99b8Sopenharmony_ci 179800b99b8Sopenharmony_ci std::vector<uintptr_t> pcs = unwinder->GetPcs(); 180800b99b8Sopenharmony_ci ASSERT_FALSE(pcs.empty()); 181800b99b8Sopenharmony_ci 182800b99b8Sopenharmony_ci std::vector<DfxFrame> frames; 183800b99b8Sopenharmony_ci (void)unwinder->GetFramesByPcs(frames, pcs); 184800b99b8Sopenharmony_ci ASSERT_FALSE(frames.empty()); 185800b99b8Sopenharmony_ci unwinder->SetFrames(frames); 186800b99b8Sopenharmony_ci 187800b99b8Sopenharmony_ci std::vector<char> buffer(sizeof(pthread_mutex_t), 0); 188800b99b8Sopenharmony_ci if (!unwinder->GetLockInfo(tid, buffer.data(), sizeof(pthread_mutex_t))) { 189800b99b8Sopenharmony_ci ASSERT_TRUE(false); 190800b99b8Sopenharmony_ci } 191800b99b8Sopenharmony_ci 192800b99b8Sopenharmony_ci if (memcmp(buffer.data(), &mutex, sizeof(pthread_mutex_t)) != 0) { 193800b99b8Sopenharmony_ci ASSERT_TRUE(false); 194800b99b8Sopenharmony_ci } 195800b99b8Sopenharmony_ci 196800b99b8Sopenharmony_ci int lockOwner = mutexInt[LOCK_OWNER_IDX] & LOCK_OWNER_MASK; 197800b99b8Sopenharmony_ci ASSERT_EQ(EBUSY, lockOwner); 198800b99b8Sopenharmony_ci printf("EBUSY:%d Lock owner:%d\n", EBUSY, lockOwner); 199800b99b8Sopenharmony_ci ASSERT_EQ(PTHREAD_MUTEX_NORMAL, mutexInt[LOCK_TYPE_IDX]); 200800b99b8Sopenharmony_ci pthread_mutex_unlock(&mutex); 201800b99b8Sopenharmony_ci if (t1.joinable()) { 202800b99b8Sopenharmony_ci t1.join(); 203800b99b8Sopenharmony_ci } 204800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "LockParserUnittest002: end."; 205800b99b8Sopenharmony_ci} 206800b99b8Sopenharmony_ci 207800b99b8Sopenharmony_ci/** 208800b99b8Sopenharmony_ci * @tc.name: LockParserUnittest003 209800b99b8Sopenharmony_ci * @tc.desc: test lock parser parse normal lock 210800b99b8Sopenharmony_ci * @tc.type: FUNC 211800b99b8Sopenharmony_ci */ 212800b99b8Sopenharmony_ciHWTEST_F(LockParserUnittest, LockParserUnittest003, TestSize.Level2) 213800b99b8Sopenharmony_ci{ 214800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "LockParserUnittest003: start."; 215800b99b8Sopenharmony_ci pthread_mutex_t mutex; 216800b99b8Sopenharmony_ci InitMutexByType(PTHREAD_MUTEX_NORMAL, mutex); 217800b99b8Sopenharmony_ci LockMutex(mutex); 218800b99b8Sopenharmony_ci 219800b99b8Sopenharmony_ci int tid = 0; 220800b99b8Sopenharmony_ci std::thread t1([&tid, &mutex] { 221800b99b8Sopenharmony_ci tid = gettid(); 222800b99b8Sopenharmony_ci printf("BlockTid:%d\n", tid); 223800b99b8Sopenharmony_ci pthread_mutex_lock(&mutex); 224800b99b8Sopenharmony_ci }); 225800b99b8Sopenharmony_ci 226800b99b8Sopenharmony_ci WaitThreadBlock(tid); 227800b99b8Sopenharmony_ci printf("CurrentTid:%d BlockTid:%d\n", gettid(), tid); 228800b99b8Sopenharmony_ci auto unwinder = std::make_shared<Unwinder>(true); 229800b99b8Sopenharmony_ci ASSERT_EQ(unwinder->UnwindLocalWithTid(tid), true); 230800b99b8Sopenharmony_ci 231800b99b8Sopenharmony_ci std::vector<uintptr_t> pcs = unwinder->GetPcs(); 232800b99b8Sopenharmony_ci std::vector<DfxFrame> frames; 233800b99b8Sopenharmony_ci (void)unwinder->GetFramesByPcs(frames, pcs); 234800b99b8Sopenharmony_ci unwinder->SetFrames(frames); 235800b99b8Sopenharmony_ci 236800b99b8Sopenharmony_ci bool ret = LockParser::ParseLockInfo(unwinder, getpid(), tid); 237800b99b8Sopenharmony_ci ASSERT_EQ(ret, true); 238800b99b8Sopenharmony_ci 239800b99b8Sopenharmony_ci pthread_mutex_unlock(&mutex); 240800b99b8Sopenharmony_ci if (t1.joinable()) { 241800b99b8Sopenharmony_ci t1.join(); 242800b99b8Sopenharmony_ci } 243800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "LockParserUnittest003: end."; 244800b99b8Sopenharmony_ci} 245800b99b8Sopenharmony_ci 246800b99b8Sopenharmony_ci/** 247800b99b8Sopenharmony_ci * @tc.name: LockParserUnittest004 248800b99b8Sopenharmony_ci * @tc.desc: test lock parser parse errorcheck lock 249800b99b8Sopenharmony_ci * @tc.type: FUNC 250800b99b8Sopenharmony_ci */ 251800b99b8Sopenharmony_ciHWTEST_F(LockParserUnittest, LockParserUnittest004, TestSize.Level2) 252800b99b8Sopenharmony_ci{ 253800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "LockParserUnittest004: start."; 254800b99b8Sopenharmony_ci pthread_mutex_t mutex; 255800b99b8Sopenharmony_ci InitMutexByType(PTHREAD_MUTEX_ERRORCHECK, mutex); 256800b99b8Sopenharmony_ci LockMutex(mutex); 257800b99b8Sopenharmony_ci 258800b99b8Sopenharmony_ci int tid = 0; 259800b99b8Sopenharmony_ci std::thread t1([&tid, &mutex] { 260800b99b8Sopenharmony_ci tid = gettid(); 261800b99b8Sopenharmony_ci printf("BlockTid:%d\n", tid); 262800b99b8Sopenharmony_ci pthread_mutex_lock(&mutex); 263800b99b8Sopenharmony_ci }); 264800b99b8Sopenharmony_ci 265800b99b8Sopenharmony_ci WaitThreadBlock(tid); 266800b99b8Sopenharmony_ci printf("CurrentTid:%d BlockTid:%d\n", gettid(), tid); 267800b99b8Sopenharmony_ci auto unwinder = std::make_shared<Unwinder>(true); 268800b99b8Sopenharmony_ci ASSERT_EQ(unwinder->UnwindLocalWithTid(tid), true); 269800b99b8Sopenharmony_ci 270800b99b8Sopenharmony_ci std::vector<uintptr_t> pcs = unwinder->GetPcs(); 271800b99b8Sopenharmony_ci std::vector<DfxFrame> frames; 272800b99b8Sopenharmony_ci (void)unwinder->GetFramesByPcs(frames, pcs); 273800b99b8Sopenharmony_ci unwinder->SetFrames(frames); 274800b99b8Sopenharmony_ci 275800b99b8Sopenharmony_ci bool ret = LockParser::ParseLockInfo(unwinder, getpid(), tid); 276800b99b8Sopenharmony_ci ASSERT_EQ(ret, true); 277800b99b8Sopenharmony_ci 278800b99b8Sopenharmony_ci pthread_mutex_unlock(&mutex); 279800b99b8Sopenharmony_ci if (t1.joinable()) { 280800b99b8Sopenharmony_ci t1.join(); 281800b99b8Sopenharmony_ci } 282800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "LockParserUnittest004: end."; 283800b99b8Sopenharmony_ci} 284800b99b8Sopenharmony_ci 285800b99b8Sopenharmony_ci/** 286800b99b8Sopenharmony_ci * @tc.name: LockParserUnittest005 287800b99b8Sopenharmony_ci * @tc.desc: test lock parser parse PTHREAD_MUTEX_RECURSIVE lock 288800b99b8Sopenharmony_ci * @tc.type: FUNC 289800b99b8Sopenharmony_ci */ 290800b99b8Sopenharmony_ciHWTEST_F(LockParserUnittest, LockParserUnittest005, TestSize.Level2) 291800b99b8Sopenharmony_ci{ 292800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "LockParserUnittest005: start."; 293800b99b8Sopenharmony_ci pthread_mutex_t mutex; 294800b99b8Sopenharmony_ci InitMutexByType(PTHREAD_MUTEX_RECURSIVE, mutex); 295800b99b8Sopenharmony_ci LockMutex(mutex); 296800b99b8Sopenharmony_ci 297800b99b8Sopenharmony_ci int tid = 0; 298800b99b8Sopenharmony_ci std::thread t1([&tid, &mutex] { 299800b99b8Sopenharmony_ci tid = gettid(); 300800b99b8Sopenharmony_ci printf("BlockTid:%d\n", tid); 301800b99b8Sopenharmony_ci pthread_mutex_lock(&mutex); 302800b99b8Sopenharmony_ci }); 303800b99b8Sopenharmony_ci 304800b99b8Sopenharmony_ci WaitThreadBlock(tid); 305800b99b8Sopenharmony_ci printf("CurrentTid:%d BlockTid:%d\n", gettid(), tid); 306800b99b8Sopenharmony_ci auto unwinder = std::make_shared<Unwinder>(true); 307800b99b8Sopenharmony_ci ASSERT_EQ(unwinder->UnwindLocalWithTid(tid), true); 308800b99b8Sopenharmony_ci 309800b99b8Sopenharmony_ci std::vector<uintptr_t> pcs = unwinder->GetPcs(); 310800b99b8Sopenharmony_ci ASSERT_FALSE(pcs.empty()); 311800b99b8Sopenharmony_ci 312800b99b8Sopenharmony_ci std::vector<DfxFrame> frames; 313800b99b8Sopenharmony_ci (void)unwinder->GetFramesByPcs(frames, pcs); 314800b99b8Sopenharmony_ci ASSERT_FALSE(frames.empty()); 315800b99b8Sopenharmony_ci unwinder->SetFrames(frames); 316800b99b8Sopenharmony_ci 317800b99b8Sopenharmony_ci std::vector<char> buffer(sizeof(pthread_mutex_t), 0); 318800b99b8Sopenharmony_ci if (!unwinder->GetLockInfo(tid, buffer.data(), sizeof(pthread_mutex_t))) { 319800b99b8Sopenharmony_ci ASSERT_TRUE(false); 320800b99b8Sopenharmony_ci } 321800b99b8Sopenharmony_ci 322800b99b8Sopenharmony_ci if (memcmp(buffer.data(), &mutex, sizeof(pthread_mutex_t)) != 0) { 323800b99b8Sopenharmony_ci ASSERT_TRUE(false); 324800b99b8Sopenharmony_ci } 325800b99b8Sopenharmony_ci 326800b99b8Sopenharmony_ci auto mutexInt = reinterpret_cast<int*>(&mutex); 327800b99b8Sopenharmony_ci int lockOwner = mutexInt[LOCK_OWNER_IDX] & LOCK_OWNER_MASK; 328800b99b8Sopenharmony_ci ASSERT_EQ(gettid(), lockOwner); 329800b99b8Sopenharmony_ci printf("CurrentTid:%d Lock owner:%d\n", gettid(), lockOwner); 330800b99b8Sopenharmony_ci ASSERT_EQ(PTHREAD_MUTEX_RECURSIVE, mutexInt[LOCK_TYPE_IDX]); 331800b99b8Sopenharmony_ci ASSERT_EQ(LockParser::ParseLockInfo(unwinder, getpid(), tid), true); 332800b99b8Sopenharmony_ci 333800b99b8Sopenharmony_ci pthread_mutex_unlock(&mutex); 334800b99b8Sopenharmony_ci if (t1.joinable()) { 335800b99b8Sopenharmony_ci t1.join(); 336800b99b8Sopenharmony_ci } 337800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "LockParserUnittest005: end."; 338800b99b8Sopenharmony_ci} 339800b99b8Sopenharmony_ci}