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