1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <errno.h>
18 #include <signal.h>
19 #include <stdint.h>
20 #include <string.h>
21 #include <sys/ptrace.h>
22 #include <sys/syscall.h>
23 #include <unistd.h>
24 
25 #include <gtest/gtest.h>
26 
27 #include <atomic>
28 #include <memory>
29 #include <sstream>
30 #include <string>
31 #include <thread>
32 #include <vector>
33 
34 #include <android-base/stringprintf.h>
35 #include <android-base/threads.h>
36 
37 #include <unwindstack/Maps.h>
38 #include <unwindstack/Regs.h>
39 #include <unwindstack/RegsGetLocal.h>
40 #include <unwindstack/Unwinder.h>
41 
42 #include "MemoryRemote.h"
43 #include "TestUtils.h"
44 
45 namespace unwindstack {
46 
47 enum TestTypeEnum : uint8_t {
48   TEST_TYPE_LOCAL_UNWINDER = 0,
49   TEST_TYPE_LOCAL_UNWINDER_FROM_PID,
50   TEST_TYPE_LOCAL_WAIT_FOR_FINISH,
51   TEST_TYPE_REMOTE,
52   TEST_TYPE_REMOTE_WITH_INVALID_CALL,
53 };
54 
55 static std::atomic_bool g_ready;
56 static volatile bool g_ready_for_remote;
57 static volatile bool g_signal_ready_for_remote;
58 static std::atomic_bool g_finish;
59 static std::atomic_uintptr_t g_ucontext;
60 static std::atomic_int g_waiters;
61 
ResetGlobals()62 static void ResetGlobals() {
63   g_ready = false;
64   g_ready_for_remote = false;
65   g_signal_ready_for_remote = false;
66   g_finish = false;
67   g_ucontext = 0;
68   g_waiters = 0;
69 }
70 
71 static std::vector<const char*> kFunctionOrder{"OuterFunction", "MiddleFunction", "InnerFunction"};
72 
73 static std::vector<const char*> kFunctionSignalOrder{"OuterFunction",        "MiddleFunction",
74                                                      "InnerFunction",        "SignalOuterFunction",
75                                                      "SignalMiddleFunction", "SignalInnerFunction"};
76 
SignalHandler(int,siginfo_t *,void * sigcontext)77 static void SignalHandler(int, siginfo_t*, void* sigcontext) {
78   g_ucontext = reinterpret_cast<uintptr_t>(sigcontext);
79   while (!g_finish.load()) {
80   }
81 }
82 
SignalInnerFunction()83 extern "C" void SignalInnerFunction() {
84   g_signal_ready_for_remote = true;
85   // Avoid any function calls because not every instruction will be
86   // unwindable.
87   // This method of looping is only used when testing a remote unwind.
88   while (true) {
89   }
90 }
91 
SignalMiddleFunction()92 extern "C" void SignalMiddleFunction() {
93   SignalInnerFunction();
94 }
95 
SignalOuterFunction()96 extern "C" void SignalOuterFunction() {
97   SignalMiddleFunction();
98 }
99 
SignalCallerHandler(int,siginfo_t *,void *)100 static void SignalCallerHandler(int, siginfo_t*, void*) {
101   SignalOuterFunction();
102 }
103 
ErrorMsg(const std::vector<const char * > & function_names,Unwinder * unwinder)104 static std::string ErrorMsg(const std::vector<const char*>& function_names, Unwinder* unwinder) {
105   std::string unwind;
106   for (size_t i = 0; i < unwinder->NumFrames(); i++) {
107     unwind += unwinder->FormatFrame(i) + '\n';
108   }
109 
110   return std::string(
111              "Unwind completed without finding all frames\n"
112              "  Looking for function: ") +
113          function_names.front() + "\n" + "Unwind data:\n" + unwind;
114 }
115 
VerifyUnwindFrames(Unwinder * unwinder,std::vector<const char * > expected_function_names)116 static void VerifyUnwindFrames(Unwinder* unwinder,
117                                std::vector<const char*> expected_function_names) {
118   for (auto& frame : unwinder->frames()) {
119     if (frame.function_name == expected_function_names.back()) {
120       expected_function_names.pop_back();
121       if (expected_function_names.empty()) {
122         break;
123       }
124     }
125   }
126 
127   ASSERT_TRUE(expected_function_names.empty()) << ErrorMsg(expected_function_names, unwinder);
128 }
129 
VerifyUnwind(Unwinder * unwinder,std::vector<const char * > expected_function_names)130 static void VerifyUnwind(Unwinder* unwinder, std::vector<const char*> expected_function_names) {
131   unwinder->Unwind();
132 
133   VerifyUnwindFrames(unwinder, expected_function_names);
134 }
135 
VerifyUnwind(pid_t pid,Maps * maps,Regs * regs,std::vector<const char * > expected_function_names)136 static void VerifyUnwind(pid_t pid, Maps* maps, Regs* regs,
137                          std::vector<const char*> expected_function_names) {
138   auto process_memory(Memory::CreateProcessMemory(pid));
139 
140   Unwinder unwinder(512, maps, regs, process_memory);
141   VerifyUnwind(&unwinder, expected_function_names);
142 }
143 
144 // This test assumes that this code is compiled with optimizations turned
145 // off. If this doesn't happen, then all of the calls will be optimized
146 // away.
InnerFunction(TestTypeEnum test_type)147 extern "C" void InnerFunction(TestTypeEnum test_type) {
148   // Use a switch statement to force the compiler to create unwinding information
149   // for each case.
150   switch (test_type) {
151     case TEST_TYPE_LOCAL_WAIT_FOR_FINISH: {
152       g_waiters++;
153       while (!g_finish.load()) {
154       }
155       break;
156     }
157 
158     case TEST_TYPE_REMOTE:
159     case TEST_TYPE_REMOTE_WITH_INVALID_CALL: {
160       g_ready_for_remote = true;
161       g_ready = true;
162       if (test_type == TEST_TYPE_REMOTE_WITH_INVALID_CALL) {
163         void (*crash_func)() = nullptr;
164         crash_func();
165       }
166       while (true) {
167       }
168       break;
169     }
170 
171     default: {
172       std::unique_ptr<Unwinder> unwinder;
173       std::unique_ptr<Regs> regs(Regs::CreateFromLocal());
174       RegsGetLocal(regs.get());
175       std::unique_ptr<Maps> maps;
176 
177       if (test_type == TEST_TYPE_LOCAL_UNWINDER) {
178         maps.reset(new LocalMaps());
179         ASSERT_TRUE(maps->Parse());
180         auto process_memory(Memory::CreateProcessMemory(getpid()));
181         unwinder.reset(new Unwinder(512, maps.get(), regs.get(), process_memory));
182       } else {
183         UnwinderFromPid* unwinder_from_pid = new UnwinderFromPid(512, getpid());
184         unwinder_from_pid->SetRegs(regs.get());
185         unwinder.reset(unwinder_from_pid);
186       }
187       VerifyUnwind(unwinder.get(), kFunctionOrder);
188       break;
189     }
190   }
191 }
192 
MiddleFunction(TestTypeEnum test_type)193 extern "C" void MiddleFunction(TestTypeEnum test_type) {
194   InnerFunction(test_type);
195 }
196 
OuterFunction(TestTypeEnum test_type)197 extern "C" void OuterFunction(TestTypeEnum test_type) {
198   MiddleFunction(test_type);
199 }
200 
201 class UnwindTest : public ::testing::Test {
202  public:
SetUp()203   void SetUp() override { ResetGlobals(); }
204 };
205 
TEST_F(UnwindTest,local)206 TEST_F(UnwindTest, local) {
207   OuterFunction(TEST_TYPE_LOCAL_UNWINDER);
208 }
209 
TEST_F(UnwindTest,local_use_from_pid)210 TEST_F(UnwindTest, local_use_from_pid) {
211   OuterFunction(TEST_TYPE_LOCAL_UNWINDER_FROM_PID);
212 }
213 
LocalUnwind(void * data)214 static void LocalUnwind(void* data) {
215   TestTypeEnum* test_type = reinterpret_cast<TestTypeEnum*>(data);
216   OuterFunction(*test_type);
217 }
218 
TEST_F(UnwindTest,local_check_for_leak)219 TEST_F(UnwindTest, local_check_for_leak) {
220   TestTypeEnum test_type = TEST_TYPE_LOCAL_UNWINDER;
221   TestCheckForLeaks(LocalUnwind, &test_type);
222 }
223 
TEST_F(UnwindTest,local_use_from_pid_check_for_leak)224 TEST_F(UnwindTest, local_use_from_pid_check_for_leak) {
225   TestTypeEnum test_type = TEST_TYPE_LOCAL_UNWINDER_FROM_PID;
226   TestCheckForLeaks(LocalUnwind, &test_type);
227 }
228 
WaitForRemote(pid_t pid,uint64_t addr,bool leave_attached,bool * completed)229 void WaitForRemote(pid_t pid, uint64_t addr, bool leave_attached, bool* completed) {
230   *completed = false;
231   // Need to sleep before attempting first ptrace. Without this, on the
232   // host it becomes impossible to attach and ptrace sets errno to EPERM.
233   usleep(1000);
234   for (size_t i = 0; i < 1000; i++) {
235     if (ptrace(PTRACE_ATTACH, pid, 0, 0) == 0) {
236       ASSERT_TRUE(TestQuiescePid(pid))
237           << "Waiting for process to quiesce failed: " << strerror(errno);
238 
239       MemoryRemote memory(pid);
240       // Read the remote value to see if we are ready.
241       bool value;
242       if (memory.ReadFully(addr, &value, sizeof(value)) && value) {
243         *completed = true;
244       }
245       if (!*completed || !leave_attached) {
246         ASSERT_EQ(0, ptrace(PTRACE_DETACH, pid, 0, 0));
247       }
248       if (*completed) {
249         break;
250       }
251     } else {
252       ASSERT_EQ(ESRCH, errno) << "ptrace attach failed with unexpected error: " << strerror(errno);
253     }
254     usleep(5000);
255   }
256 }
257 
TEST_F(UnwindTest,remote)258 TEST_F(UnwindTest, remote) {
259   pid_t pid;
260   if ((pid = fork()) == 0) {
261     OuterFunction(TEST_TYPE_REMOTE);
262     exit(0);
263   }
264   ASSERT_NE(-1, pid);
265   TestScopedPidReaper reap(pid);
266 
267   bool completed;
268   WaitForRemote(pid, reinterpret_cast<uint64_t>(&g_ready_for_remote), true, &completed);
269   ASSERT_TRUE(completed) << "Timed out waiting for remote process to be ready.";
270 
271   RemoteMaps maps(pid);
272   ASSERT_TRUE(maps.Parse());
273   std::unique_ptr<Regs> regs(Regs::RemoteGet(pid));
274   ASSERT_TRUE(regs.get() != nullptr);
275 
276   VerifyUnwind(pid, &maps, regs.get(), kFunctionOrder);
277 
278   ASSERT_EQ(0, ptrace(PTRACE_DETACH, pid, 0, 0))
279       << "ptrace detach failed with unexpected error: " << strerror(errno);
280 }
281 
TEST_F(UnwindTest,unwind_from_pid_remote)282 TEST_F(UnwindTest, unwind_from_pid_remote) {
283   pid_t pid;
284   if ((pid = fork()) == 0) {
285     OuterFunction(TEST_TYPE_REMOTE);
286     exit(0);
287   }
288   ASSERT_NE(-1, pid);
289   TestScopedPidReaper reap(pid);
290 
291   bool completed;
292   WaitForRemote(pid, reinterpret_cast<uint64_t>(&g_ready_for_remote), true, &completed);
293   ASSERT_TRUE(completed) << "Timed out waiting for remote process to be ready.";
294 
295   std::unique_ptr<Regs> regs(Regs::RemoteGet(pid));
296   ASSERT_TRUE(regs.get() != nullptr);
297 
298   UnwinderFromPid unwinder(512, pid);
299   unwinder.SetRegs(regs.get());
300 
301   VerifyUnwind(&unwinder, kFunctionOrder);
302 
303   // Verify that calling the same object works again.
304 
305   ASSERT_EQ(0, ptrace(PTRACE_DETACH, pid, 0, 0))
306       << "ptrace detach failed with unexpected error: " << strerror(errno);
307 }
308 
RemoteCheckForLeaks(void (* unwind_func)(void *))309 static void RemoteCheckForLeaks(void (*unwind_func)(void*)) {
310   pid_t pid;
311   if ((pid = fork()) == 0) {
312     OuterFunction(TEST_TYPE_REMOTE);
313     exit(0);
314   }
315   ASSERT_NE(-1, pid);
316   TestScopedPidReaper reap(pid);
317 
318   bool completed;
319   WaitForRemote(pid, reinterpret_cast<uint64_t>(&g_ready_for_remote), true, &completed);
320   ASSERT_TRUE(completed) << "Timed out waiting for remote process to be ready.";
321 
322   TestCheckForLeaks(unwind_func, &pid);
323 
324   ASSERT_EQ(0, ptrace(PTRACE_DETACH, pid, 0, 0))
325       << "ptrace detach failed with unexpected error: " << strerror(errno);
326 }
327 
RemoteUnwind(void * data)328 static void RemoteUnwind(void* data) {
329   pid_t* pid = reinterpret_cast<pid_t*>(data);
330 
331   RemoteMaps maps(*pid);
332   ASSERT_TRUE(maps.Parse());
333   std::unique_ptr<Regs> regs(Regs::RemoteGet(*pid));
334   ASSERT_TRUE(regs.get() != nullptr);
335 
336   VerifyUnwind(*pid, &maps, regs.get(), kFunctionOrder);
337 }
338 
TEST_F(UnwindTest,remote_check_for_leaks)339 TEST_F(UnwindTest, remote_check_for_leaks) {
340   RemoteCheckForLeaks(RemoteUnwind);
341 }
342 
RemoteUnwindFromPid(void * data)343 static void RemoteUnwindFromPid(void* data) {
344   pid_t* pid = reinterpret_cast<pid_t*>(data);
345 
346   std::unique_ptr<Regs> regs(Regs::RemoteGet(*pid));
347   ASSERT_TRUE(regs.get() != nullptr);
348 
349   UnwinderFromPid unwinder(512, *pid);
350   unwinder.SetRegs(regs.get());
351 
352   VerifyUnwind(&unwinder, kFunctionOrder);
353 }
354 
TEST_F(UnwindTest,remote_unwind_for_pid_check_for_leaks)355 TEST_F(UnwindTest, remote_unwind_for_pid_check_for_leaks) {
356   RemoteCheckForLeaks(RemoteUnwindFromPid);
357 }
358 
TEST_F(UnwindTest,from_context)359 TEST_F(UnwindTest, from_context) {
360   std::atomic_int tid(0);
361   std::thread thread([&]() {
362     tid = syscall(__NR_gettid);
363     OuterFunction(TEST_TYPE_LOCAL_WAIT_FOR_FINISH);
364   });
365 
366   struct sigaction act, oldact;
367   memset(&act, 0, sizeof(act));
368   act.sa_sigaction = SignalHandler;
369   act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
370   ASSERT_EQ(0, sigaction(SIGUSR1, &act, &oldact));
371   // Wait for the tid to get set.
372   for (size_t i = 0; i < 100; i++) {
373     if (tid.load() != 0) {
374       break;
375     }
376     usleep(1000);
377   }
378   ASSERT_NE(0, tid.load());
379   ASSERT_EQ(0, tgkill(getpid(), tid.load(), SIGUSR1)) << "Error: " << strerror(errno);
380 
381   // Wait for context data.
382   void* ucontext;
383   for (size_t i = 0; i < 2000; i++) {
384     ucontext = reinterpret_cast<void*>(g_ucontext.load());
385     if (ucontext != nullptr) {
386       break;
387     }
388     usleep(1000);
389   }
390   ASSERT_TRUE(ucontext != nullptr) << "Timed out waiting for thread to respond to signal.";
391 
392   LocalMaps maps;
393   ASSERT_TRUE(maps.Parse());
394   std::unique_ptr<Regs> regs(Regs::CreateFromUcontext(Regs::CurrentArch(), ucontext));
395 
396   VerifyUnwind(getpid(), &maps, regs.get(), kFunctionOrder);
397 
398   ASSERT_EQ(0, sigaction(SIGUSR1, &oldact, nullptr));
399 
400   g_finish = true;
401   thread.join();
402 }
403 
RemoteThroughSignal(int signal,unsigned int sa_flags)404 static void RemoteThroughSignal(int signal, unsigned int sa_flags) {
405   pid_t pid;
406   if ((pid = fork()) == 0) {
407     struct sigaction act, oldact;
408     memset(&act, 0, sizeof(act));
409     act.sa_sigaction = SignalCallerHandler;
410     act.sa_flags = SA_RESTART | SA_ONSTACK | sa_flags;
411     ASSERT_EQ(0, sigaction(signal, &act, &oldact));
412 
413     OuterFunction(signal != SIGSEGV ? TEST_TYPE_REMOTE : TEST_TYPE_REMOTE_WITH_INVALID_CALL);
414     exit(0);
415   }
416   ASSERT_NE(-1, pid);
417   TestScopedPidReaper reap(pid);
418 
419   bool completed;
420   if (signal != SIGSEGV) {
421     WaitForRemote(pid, reinterpret_cast<uint64_t>(&g_ready_for_remote), false, &completed);
422     ASSERT_TRUE(completed) << "Timed out waiting for remote process to be ready.";
423     ASSERT_EQ(0, kill(pid, SIGUSR1));
424   }
425   WaitForRemote(pid, reinterpret_cast<uint64_t>(&g_signal_ready_for_remote), true, &completed);
426   ASSERT_TRUE(completed) << "Timed out waiting for remote process to be in signal handler.";
427 
428   RemoteMaps maps(pid);
429   ASSERT_TRUE(maps.Parse());
430   std::unique_ptr<Regs> regs(Regs::RemoteGet(pid));
431   ASSERT_TRUE(regs.get() != nullptr);
432 
433   VerifyUnwind(pid, &maps, regs.get(), kFunctionSignalOrder);
434 
435   ASSERT_EQ(0, ptrace(PTRACE_DETACH, pid, 0, 0))
436       << "ptrace detach failed with unexpected error: " << strerror(errno);
437 }
438 
TEST_F(UnwindTest,remote_through_signal)439 TEST_F(UnwindTest, remote_through_signal) {
440   RemoteThroughSignal(SIGUSR1, 0);
441 }
442 
TEST_F(UnwindTest,remote_through_signal_sa_siginfo)443 TEST_F(UnwindTest, remote_through_signal_sa_siginfo) {
444   RemoteThroughSignal(SIGUSR1, SA_SIGINFO);
445 }
446 
TEST_F(UnwindTest,remote_through_signal_with_invalid_func)447 TEST_F(UnwindTest, remote_through_signal_with_invalid_func) {
448   RemoteThroughSignal(SIGSEGV, 0);
449 }
450 
TEST_F(UnwindTest,remote_through_signal_sa_siginfo_with_invalid_func)451 TEST_F(UnwindTest, remote_through_signal_sa_siginfo_with_invalid_func) {
452   RemoteThroughSignal(SIGSEGV, SA_SIGINFO);
453 }
454 
455 // Verify that using the same map while unwinding multiple threads at the
456 // same time doesn't cause problems.
TEST_F(UnwindTest,multiple_threads_unwind_same_map)457 TEST_F(UnwindTest, multiple_threads_unwind_same_map) {
458   static constexpr size_t kNumConcurrentThreads = 100;
459 
460   LocalMaps maps;
461   ASSERT_TRUE(maps.Parse());
462   auto process_memory(Memory::CreateProcessMemory(getpid()));
463 
464   std::vector<std::thread*> threads;
465 
466   std::atomic_bool wait;
467   wait = true;
468   size_t frames[kNumConcurrentThreads];
469   for (size_t i = 0; i < kNumConcurrentThreads; i++) {
470     std::thread* thread = new std::thread([i, &frames, &maps, &process_memory, &wait]() {
471       while (wait)
472         ;
473       std::unique_ptr<Regs> regs(Regs::CreateFromLocal());
474       RegsGetLocal(regs.get());
475 
476       Unwinder unwinder(512, &maps, regs.get(), process_memory);
477       unwinder.Unwind();
478       frames[i] = unwinder.NumFrames();
479       ASSERT_LE(3U, frames[i]) << "Failed for thread " << i;
480     });
481     threads.push_back(thread);
482   }
483   wait = false;
484   for (auto thread : threads) {
485     thread->join();
486     delete thread;
487   }
488 }
489 
TEST_F(UnwindTest,thread_unwind)490 TEST_F(UnwindTest, thread_unwind) {
491   ResetGlobals();
492 
493   std::atomic_int tid(0);
494   std::thread thread([&tid]() {
495     tid = android::base::GetThreadId();
496     OuterFunction(TEST_TYPE_LOCAL_WAIT_FOR_FINISH);
497   });
498 
499   while (tid.load() == 0)
500     ;
501 
502   ThreadUnwinder unwinder(512);
503   ASSERT_TRUE(unwinder.Init());
504   unwinder.UnwindWithSignal(SIGRTMIN, tid);
505   VerifyUnwindFrames(&unwinder, kFunctionOrder);
506 
507   g_finish = true;
508   thread.join();
509 }
510 
TEST_F(UnwindTest,thread_unwind_with_external_maps)511 TEST_F(UnwindTest, thread_unwind_with_external_maps) {
512   ResetGlobals();
513 
514   std::atomic_int tid(0);
515   std::thread thread([&tid]() {
516     tid = android::base::GetThreadId();
517     OuterFunction(TEST_TYPE_LOCAL_WAIT_FOR_FINISH);
518   });
519 
520   while (tid.load() == 0)
521     ;
522 
523   LocalMaps maps;
524   ASSERT_TRUE(maps.Parse());
525 
526   ThreadUnwinder unwinder(512, &maps);
527   ASSERT_EQ(&maps, unwinder.GetMaps());
528   ASSERT_TRUE(unwinder.Init());
529   ASSERT_EQ(&maps, unwinder.GetMaps());
530   unwinder.UnwindWithSignal(SIGRTMIN, tid);
531   VerifyUnwindFrames(&unwinder, kFunctionOrder);
532   ASSERT_EQ(&maps, unwinder.GetMaps());
533 
534   g_finish = true;
535   thread.join();
536 }
537 
TEST_F(UnwindTest,thread_unwind_cur_pid)538 TEST_F(UnwindTest, thread_unwind_cur_pid) {
539   ThreadUnwinder unwinder(512);
540   ASSERT_TRUE(unwinder.Init());
541   unwinder.UnwindWithSignal(SIGRTMIN, getpid());
542   EXPECT_EQ(0U, unwinder.NumFrames());
543   EXPECT_EQ(ERROR_UNSUPPORTED, unwinder.LastErrorCode());
544 }
545 
CreateUnwindThread(std::atomic_int & tid,ThreadUnwinder & unwinder,std::atomic_bool & start_unwinding,std::atomic_int & unwinders)546 static std::thread* CreateUnwindThread(std::atomic_int& tid, ThreadUnwinder& unwinder,
547                                        std::atomic_bool& start_unwinding,
548                                        std::atomic_int& unwinders) {
549   return new std::thread([&tid, &unwinder, &start_unwinding, &unwinders]() {
550     while (!start_unwinding.load())
551       ;
552 
553     ThreadUnwinder thread_unwinder(512, &unwinder);
554     thread_unwinder.UnwindWithSignal(SIGRTMIN, tid);
555 #if defined(__arm__)
556     // On arm, there is a chance of winding up in case that doesn't unwind.
557     // Identify that case and allow unwinding in that case.
558     for (size_t i = 0; i < 10; i++) {
559       auto frames = thread_unwinder.frames();
560       if (frames.size() > 1 && frames[frames.size() - 1].pc < 1000 &&
561           frames[frames.size() - 2].function_name == "InnerFunction") {
562         thread_unwinder.UnwindWithSignal(SIGRTMIN, tid);
563       } else {
564         break;
565       }
566     }
567 #endif
568     VerifyUnwindFrames(&thread_unwinder, kFunctionOrder);
569     ++unwinders;
570   });
571 }
572 
TEST_F(UnwindTest,thread_unwind_same_thread_from_threads)573 TEST_F(UnwindTest, thread_unwind_same_thread_from_threads) {
574   static constexpr size_t kNumThreads = 300;
575   ResetGlobals();
576 
577   std::atomic_int tid(0);
578   std::thread thread([&tid]() {
579     tid = android::base::GetThreadId();
580     OuterFunction(TEST_TYPE_LOCAL_WAIT_FOR_FINISH);
581   });
582 
583   while (g_waiters.load() != 1)
584     ;
585 
586   ThreadUnwinder unwinder(512);
587   ASSERT_TRUE(unwinder.Init());
588 
589   std::atomic_bool start_unwinding(false);
590   std::vector<std::thread*> threads;
591   std::atomic_int unwinders(0);
592   for (size_t i = 0; i < kNumThreads; i++) {
593     threads.push_back(CreateUnwindThread(tid, unwinder, start_unwinding, unwinders));
594   }
595 
596   start_unwinding = true;
597   while (unwinders.load() != kNumThreads)
598     ;
599 
600   for (auto* thread : threads) {
601     thread->join();
602     delete thread;
603   }
604 
605   g_finish = true;
606   thread.join();
607 }
608 
TEST_F(UnwindTest,thread_unwind_multiple_thread_from_threads)609 TEST_F(UnwindTest, thread_unwind_multiple_thread_from_threads) {
610   static constexpr size_t kNumThreads = 100;
611   ResetGlobals();
612 
613   std::atomic_int tids[kNumThreads] = {};
614   std::vector<std::thread*> threads;
615   for (size_t i = 0; i < kNumThreads; i++) {
616     std::thread* thread = new std::thread([&tids, i]() {
617       tids[i] = android::base::GetThreadId();
618       OuterFunction(TEST_TYPE_LOCAL_WAIT_FOR_FINISH);
619     });
620     threads.push_back(thread);
621   }
622 
623   while (g_waiters.load() != kNumThreads)
624     ;
625 
626   ThreadUnwinder unwinder(512);
627   ASSERT_TRUE(unwinder.Init());
628 
629   std::atomic_bool start_unwinding(false);
630   std::vector<std::thread*> unwinder_threads;
631   std::atomic_int unwinders(0);
632   for (size_t i = 0; i < kNumThreads; i++) {
633     unwinder_threads.push_back(CreateUnwindThread(tids[i], unwinder, start_unwinding, unwinders));
634   }
635 
636   start_unwinding = true;
637   while (unwinders.load() != kNumThreads)
638     ;
639 
640   for (auto* thread : unwinder_threads) {
641     thread->join();
642     delete thread;
643   }
644 
645   g_finish = true;
646 
647   for (auto* thread : threads) {
648     thread->join();
649     delete thread;
650   }
651 }
652 
TEST_F(UnwindTest,thread_unwind_multiple_thread_from_threads_updatable_maps)653 TEST_F(UnwindTest, thread_unwind_multiple_thread_from_threads_updatable_maps) {
654   static constexpr size_t kNumThreads = 100;
655   ResetGlobals();
656 
657   // Do this before the threads are started so that the maps needed to
658   // unwind are not created yet, and this verifies the dynamic nature
659   // of the LocalUpdatableMaps object.
660   LocalUpdatableMaps maps;
661   ASSERT_TRUE(maps.Parse());
662 
663   std::atomic_int tids[kNumThreads] = {};
664   std::vector<std::thread*> threads;
665   for (size_t i = 0; i < kNumThreads; i++) {
666     std::thread* thread = new std::thread([&tids, i]() {
667       tids[i] = android::base::GetThreadId();
668       OuterFunction(TEST_TYPE_LOCAL_WAIT_FOR_FINISH);
669     });
670     threads.push_back(thread);
671   }
672 
673   while (g_waiters.load() != kNumThreads)
674     ;
675 
676   ThreadUnwinder unwinder(512, &maps);
677   ASSERT_TRUE(unwinder.Init());
678 
679   std::atomic_bool start_unwinding(false);
680   std::vector<std::thread*> unwinder_threads;
681   std::atomic_int unwinders(0);
682   for (size_t i = 0; i < kNumThreads; i++) {
683     unwinder_threads.push_back(CreateUnwindThread(tids[i], unwinder, start_unwinding, unwinders));
684   }
685 
686   start_unwinding = true;
687   while (unwinders.load() != kNumThreads)
688     ;
689 
690   for (auto* thread : unwinder_threads) {
691     thread->join();
692     delete thread;
693   }
694 
695   g_finish = true;
696 
697   for (auto* thread : threads) {
698     thread->join();
699     delete thread;
700   }
701 }
702 
703 }  // namespace unwindstack
704