1 /*
2  * Copyright (C) 2022 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 <dlfcn.h>
18 #include <fcntl.h>
19 #include <stdint.h>
20 #include <string.h>
21 #include <sys/types.h>
22 #include <time.h>
23 #include <unistd.h>
24 
25 #include <gtest/gtest.h>
26 
27 #include <atomic>
28 #include <string>
29 #include <thread>
30 #include <vector>
31 
32 #include <android-base/strings.h>
33 #include <android-base/test_utils.h>
34 #include <android-base/threads.h>
35 
36 #include <unwindstack/AndroidUnwinder.h>
37 #include <unwindstack/Error.h>
38 #include <unwindstack/MachineArm.h>
39 #include <unwindstack/MachineArm64.h>
40 #include <unwindstack/MachineRiscv64.h>
41 #include <unwindstack/MachineX86.h>
42 #include <unwindstack/MachineX86_64.h>
43 #include <unwindstack/Regs.h>
44 #include <unwindstack/RegsArm.h>
45 #include <unwindstack/RegsArm64.h>
46 #include <unwindstack/RegsGetLocal.h>
47 #include <unwindstack/RegsRiscv64.h>
48 #include <unwindstack/RegsX86.h>
49 #include <unwindstack/RegsX86_64.h>
50 #include <unwindstack/UcontextArm.h>
51 #include <unwindstack/UcontextArm64.h>
52 #include <unwindstack/UcontextRiscv64.h>
53 #include <unwindstack/UcontextX86.h>
54 #include <unwindstack/UcontextX86_64.h>
55 #include <unwindstack/Unwinder.h>
56 
57 #include "ForkTest.h"
58 #include "PidUtils.h"
59 #include "TestUtils.h"
60 
61 namespace unwindstack {
62 
GetBacktrace(AndroidUnwinder & unwinder,std::vector<FrameData> & frames)63 static std::string GetBacktrace(AndroidUnwinder& unwinder, std::vector<FrameData>& frames) {
64   std::string backtrace_str;
65   for (auto& frame : frames) {
66     backtrace_str += unwinder.FormatFrame(frame) + '\n';
67   }
68   return backtrace_str;
69 }
70 
TEST(AndroidUnwinderDataTest,demangle_function_names)71 TEST(AndroidUnwinderDataTest, demangle_function_names) {
72   AndroidUnwinderData data;
73 
74   // Add a few frames with and without demangled function names.
75   data.frames.resize(4);
76   data.frames[0].function_name = "no_demangle()";
77   data.frames[1].function_name = "_Z4fakeb";
78   data.frames[3].function_name = "_Z8demanglei";
79 
80   data.DemangleFunctionNames();
81   EXPECT_EQ("no_demangle()", data.frames[0].function_name);
82   EXPECT_EQ("fake(bool)", data.frames[1].function_name);
83   EXPECT_EQ("", data.frames[2].function_name);
84   EXPECT_EQ("demangle(int)", data.frames[3].function_name);
85 
86   // Make sure that this action is idempotent.
87   data.DemangleFunctionNames();
88   EXPECT_EQ("no_demangle()", data.frames[0].function_name);
89   EXPECT_EQ("fake(bool)", data.frames[1].function_name);
90   EXPECT_EQ("", data.frames[2].function_name);
91   EXPECT_EQ("demangle(int)", data.frames[3].function_name);
92 }
93 
TEST(AndroidUnwinderDataTest,get_error_string)94 TEST(AndroidUnwinderDataTest, get_error_string) {
95   AndroidUnwinderData data;
96 
97   EXPECT_EQ("None", data.GetErrorString());
98   data.error.code = ERROR_INVALID_ELF;
99   EXPECT_EQ("Invalid Elf", data.GetErrorString());
100   data.error.code = ERROR_MEMORY_INVALID;
101   EXPECT_EQ("Memory Invalid", data.GetErrorString());
102   data.error.address = 0x1000;
103   EXPECT_EQ("Memory Invalid at address 0x1000", data.GetErrorString());
104 }
105 
106 using AndroidUnwinderTest = ForkTest;
107 
TEST_F(AndroidUnwinderTest,unwind_errors)108 TEST_F(AndroidUnwinderTest, unwind_errors) {
109   AndroidLocalUnwinder unwinder;
110 
111   AndroidUnwinderData data;
112   void* ucontext = nullptr;
113   EXPECT_FALSE(unwinder.Unwind(ucontext, data));
114   EXPECT_EQ(ERROR_INVALID_PARAMETER, data.error.code);
115   std::unique_ptr<Regs> regs;
116   EXPECT_FALSE(unwinder.Unwind(regs.get(), data));
117   EXPECT_EQ(ERROR_INVALID_PARAMETER, data.error.code);
118   // Make sure that we are using a different arch from the
119   // current arch.
120   if (Regs::CurrentArch() == ARCH_ARM) {
121     regs.reset(new RegsArm64);
122   } else {
123     regs.reset(new RegsArm);
124   }
125   EXPECT_FALSE(unwinder.Unwind(regs.get(), data));
126   EXPECT_EQ(ERROR_BAD_ARCH, data.error.code);
127 }
128 
TEST_F(AndroidUnwinderTest,create)129 TEST_F(AndroidUnwinderTest, create) {
130   // Verify the local unwinder object is created.
131   std::unique_ptr<AndroidUnwinder> unwinder(AndroidUnwinder::Create(getpid()));
132   AndroidUnwinderData data;
133   ASSERT_TRUE(unwinder->Unwind(data));
134 
135   ForkAndWaitForPidState([this, &unwinder]() {
136     // Verify the remote unwinder object is created.
137     unwinder.reset(AndroidUnwinder::Create(pid_));
138     AndroidUnwinderData data;
139     if (!unwinder->Unwind(data)) {
140       printf("Failed to unwind %s\n", data.GetErrorString().c_str());
141       return PID_RUN_FAIL;
142     }
143     return PID_RUN_PASS;
144   });
145 }
146 
TEST_F(AndroidUnwinderTest,initialize_fails)147 TEST_F(AndroidUnwinderTest, initialize_fails) {
148   AndroidLocalUnwinder unwinder;
149 
150   // Induce a failure in the initialize function by grabbing every
151   // fd available.
152   std::vector<android::base::unique_fd> fds;
153   while (true) {
154     auto fd = android::base::unique_fd(TEMP_FAILURE_RETRY(open("/dev/null", O_RDONLY)));
155     if (fd == -1) {
156       break;
157     }
158     fds.emplace_back(std::move(fd));
159   }
160 
161   ErrorData error;
162   ASSERT_FALSE(unwinder.Initialize(error));
163 
164   // Make sure there is no crash when trying to unwind.
165   AndroidUnwinderData data;
166   ASSERT_FALSE(unwinder.Unwind(data));
167 }
168 
TEST(AndroidLocalUnwinderTest,initialize_before)169 TEST(AndroidLocalUnwinderTest, initialize_before) {
170   AndroidLocalUnwinder unwinder;
171   ErrorData error;
172   ASSERT_TRUE(unwinder.Initialize(error));
173 
174   AndroidUnwinderData data;
175   ASSERT_TRUE(unwinder.Unwind(data));
176 }
177 
TEST(AndroidLocalUnwinderTest,suffix_ignore)178 TEST(AndroidLocalUnwinderTest, suffix_ignore) {
179   AndroidLocalUnwinder unwinder(std::vector<std::string>{}, std::vector<std::string>{"so"});
180   AndroidUnwinderData data;
181   // This should work as long as the first frame is in the test executable.
182   ASSERT_TRUE(unwinder.Unwind(data));
183   // Make sure the unwind doesn't include any .so frames.
184   for (const auto& frame : data.frames) {
185     ASSERT_TRUE(frame.map_info == nullptr ||
186                 !android::base::EndsWith(frame.map_info->name(), ".so"))
187         << GetBacktrace(unwinder, data.frames);
188   }
189 }
190 
TEST_F(AndroidUnwinderTest,verify_all_unwind_functions)191 TEST_F(AndroidUnwinderTest, verify_all_unwind_functions) {
192   // Do not reuse the unwinder object to verify initialization is done
193   // correctly.
194   AndroidUnwinderData data;
195   {
196     AndroidLocalUnwinder unwinder;
197     ASSERT_TRUE(unwinder.Unwind(data));
198   }
199   {
200     AndroidLocalUnwinder unwinder;
201     ASSERT_TRUE(unwinder.Unwind(std::nullopt, data));
202   }
203   {
204     AndroidLocalUnwinder unwinder;
205     ASSERT_TRUE(unwinder.Unwind(getpid(), data));
206   }
207 
208   std::unique_ptr<Regs> regs(Regs::CreateFromLocal());
209   RegsGetLocal(regs.get());
210   void* ucontext;
211   switch (regs->Arch()) {
212     case ARCH_ARM: {
213       arm_ucontext_t* arm_ucontext =
214           reinterpret_cast<arm_ucontext_t*>(malloc(sizeof(arm_ucontext_t)));
215       ucontext = arm_ucontext;
216       memcpy(&arm_ucontext->uc_mcontext.regs[0], regs->RawData(), ARM_REG_LAST * sizeof(uint32_t));
217     } break;
218     case ARCH_ARM64: {
219       arm64_ucontext_t* arm64_ucontext =
220           reinterpret_cast<arm64_ucontext_t*>(malloc(sizeof(arm64_ucontext_t)));
221       ucontext = arm64_ucontext;
222       memcpy(&arm64_ucontext->uc_mcontext.regs[0], regs->RawData(),
223              ARM64_REG_LAST * sizeof(uint64_t));
224     } break;
225     case ARCH_X86: {
226       x86_ucontext_t* x86_ucontext =
227           reinterpret_cast<x86_ucontext_t*>(malloc(sizeof(x86_ucontext_t)));
228       ucontext = x86_ucontext;
229       RegsX86* regs_x86 = static_cast<RegsX86*>(regs.get());
230 
231       x86_ucontext->uc_mcontext.edi = (*regs_x86)[X86_REG_EDI];
232       x86_ucontext->uc_mcontext.esi = (*regs_x86)[X86_REG_ESI];
233       x86_ucontext->uc_mcontext.ebp = (*regs_x86)[X86_REG_EBP];
234       x86_ucontext->uc_mcontext.esp = (*regs_x86)[X86_REG_ESP];
235       x86_ucontext->uc_mcontext.ebx = (*regs_x86)[X86_REG_EBX];
236       x86_ucontext->uc_mcontext.edx = (*regs_x86)[X86_REG_EDX];
237       x86_ucontext->uc_mcontext.ecx = (*regs_x86)[X86_REG_ECX];
238       x86_ucontext->uc_mcontext.eax = (*regs_x86)[X86_REG_EAX];
239       x86_ucontext->uc_mcontext.eip = (*regs_x86)[X86_REG_EIP];
240     } break;
241     case ARCH_X86_64: {
242       x86_64_ucontext_t* x86_64_ucontext =
243           reinterpret_cast<x86_64_ucontext_t*>(malloc(sizeof(x86_64_ucontext_t)));
244       ucontext = x86_64_ucontext;
245       RegsX86_64* regs_x86_64 = static_cast<RegsX86_64*>(regs.get());
246 
247       memcpy(&x86_64_ucontext->uc_mcontext.r8, &(*regs_x86_64)[X86_64_REG_R8],
248              8 * sizeof(uint64_t));
249 
250       x86_64_ucontext->uc_mcontext.rdi = (*regs_x86_64)[X86_64_REG_RDI];
251       x86_64_ucontext->uc_mcontext.rsi = (*regs_x86_64)[X86_64_REG_RSI];
252       x86_64_ucontext->uc_mcontext.rbp = (*regs_x86_64)[X86_64_REG_RBP];
253       x86_64_ucontext->uc_mcontext.rbx = (*regs_x86_64)[X86_64_REG_RBX];
254       x86_64_ucontext->uc_mcontext.rdx = (*regs_x86_64)[X86_64_REG_RDX];
255       x86_64_ucontext->uc_mcontext.rax = (*regs_x86_64)[X86_64_REG_RAX];
256       x86_64_ucontext->uc_mcontext.rcx = (*regs_x86_64)[X86_64_REG_RCX];
257       x86_64_ucontext->uc_mcontext.rsp = (*regs_x86_64)[X86_64_REG_RSP];
258       x86_64_ucontext->uc_mcontext.rip = (*regs_x86_64)[X86_64_REG_RIP];
259     } break;
260     case ARCH_RISCV64: {
261       riscv64_ucontext_t* riscv64_ucontext =
262           reinterpret_cast<riscv64_ucontext_t*>(malloc(sizeof(riscv64_ucontext_t)));
263       ucontext = riscv64_ucontext;
264       memcpy(&riscv64_ucontext->uc_mcontext.__gregs, regs->RawData(),
265              RISCV64_REG_REAL_COUNT * sizeof(uint64_t));
266     } break;
267     default:
268       ucontext = nullptr;
269       break;
270   }
271 
272   AndroidLocalUnwinder unwinder_with_ucontext;
273   ASSERT_TRUE(ucontext != nullptr);
274   ASSERT_TRUE(unwinder_with_ucontext.Unwind(ucontext, data));
275   free(ucontext);
276 
277   AndroidLocalUnwinder unwinder_with_regs;
278   AndroidUnwinderData reg_data;
279   ASSERT_TRUE(unwinder_with_regs.Unwind(regs.get(), reg_data));
280   ASSERT_EQ(data.frames.size(), reg_data.frames.size());
281   // Make sure all of the frame data is exactly the same.
282   for (size_t i = 0; i < data.frames.size(); i++) {
283     SCOPED_TRACE("\nMismatch at Frame " + std::to_string(i) + "\nucontext trace:\n" +
284                  GetBacktrace(unwinder_with_ucontext, data.frames) + "\nregs trace:\n" +
285                  GetBacktrace(unwinder_with_regs, reg_data.frames));
286     const auto& frame_context = data.frames[i];
287     const auto& frame_reg = reg_data.frames[i];
288     ASSERT_EQ(frame_context.num, frame_reg.num);
289     ASSERT_EQ(frame_context.rel_pc, frame_reg.rel_pc);
290     ASSERT_EQ(frame_context.pc, frame_reg.pc);
291     ASSERT_EQ(frame_context.sp, frame_reg.sp);
292     ASSERT_STREQ(frame_context.function_name.c_str(), frame_reg.function_name.c_str());
293     ASSERT_EQ(frame_context.function_offset, frame_reg.function_offset);
294     ASSERT_STREQ(frame_context.map_info->name().c_str(), frame_reg.map_info->name().c_str());
295     ASSERT_EQ(frame_context.map_info->start(), frame_reg.map_info->start());
296     ASSERT_EQ(frame_context.map_info->end(), frame_reg.map_info->end());
297   }
298 }
299 
TEST(AndroidLocalUnwinderTest,unwind_current_thread)300 TEST(AndroidLocalUnwinderTest, unwind_current_thread) {
301   AndroidLocalUnwinder unwinder;
302   AndroidUnwinderData data;
303   ASSERT_TRUE(unwinder.Unwind(data));
304   // Verify that the libunwindstack.so does not appear in the first frame.
305   ASSERT_TRUE(data.frames[0].map_info == nullptr ||
306               !android::base::EndsWith(data.frames[0].map_info->name(), "/libunwindstack.so"))
307       << "libunwindstack.so not removed properly\n"
308       << GetBacktrace(unwinder, data.frames);
309 }
310 
TEST(AndroidLocalUnwinderTest,unwind_current_thread_show_all_frames)311 TEST(AndroidLocalUnwinderTest, unwind_current_thread_show_all_frames) {
312   AndroidLocalUnwinder unwinder;
313   AndroidUnwinderData data(true);
314   ASSERT_TRUE(unwinder.Unwind(data));
315   // Verify that the libunwindstack.so does appear in the first frame.
316   ASSERT_TRUE(data.frames[0].map_info != nullptr &&
317               android::base::EndsWith(data.frames[0].map_info->name(), "/libunwindstack.so"))
318       << "libunwindstack.so was removed improperly\n"
319       << GetBacktrace(unwinder, data.frames);
320 }
321 
ThreadBusyWait(std::atomic<pid_t> * tid,volatile bool * keep_running)322 __attribute__((__noinline__)) extern "C" void ThreadBusyWait(std::atomic<pid_t>* tid,
323                                                              volatile bool* keep_running) {
324   *tid = android::base::GetThreadId();
325   while (*keep_running) {
326   }
327 }
328 
TEST(AndroidLocalUnwinderTest,unwind_different_thread)329 TEST(AndroidLocalUnwinderTest, unwind_different_thread) {
330   std::atomic<pid_t> tid;
331   volatile bool keep_running = true;
332   std::thread thread([&tid, &keep_running] {
333     ThreadBusyWait(&tid, &keep_running);
334     return nullptr;
335   });
336 
337   while (tid == 0) {
338   }
339 
340   AndroidLocalUnwinder unwinder;
341   AndroidUnwinderData data;
342   ASSERT_TRUE(unwinder.Unwind(tid, data));
343   // Verify that we are unwinding the thread.
344 
345   // It's possible that ThreadBusyWait is not the lowest called function.
346   // This can happen when running hwasan or if you run fast enough, you
347   // can catch the code still in the atomic operator= function, but after
348   // the tid is set. We really only care that the unwind sees you are in
349   // ThreadBusyWait, so look for it specifically.
350   size_t i = 0;
351   for (; i < data.frames.size(); i++) {
352     if (data.frames[i].function_name == "ThreadBusyWait") {
353       break;
354     }
355   }
356   ASSERT_NE(i, data.frames.size()) << "Cannot find ThreadBusyWait in backtrace\n"
357                                    << GetBacktrace(unwinder, data.frames);
358   ASSERT_NE(i + 1, data.frames.size())
359       << "ThreadBusyWait function is the last frame of the unwind.\n"
360       << GetBacktrace(unwinder, data.frames);
361 
362   // Allow the thread to terminate normally.
363   keep_running = false;
364   thread.join();
365 }
366 
367 class AndroidRemoteUnwinderTest : public ForkTest {
368  protected:
Verify(std::function<PidRunEnum (const FrameData & frame)> verify_func)369   void Verify(std::function<PidRunEnum(const FrameData& frame)> verify_func) {
370     ForkAndWaitForPidState([this, &verify_func]() {
371       AndroidRemoteUnwinder unwinder(pid_);
372       AndroidUnwinderData data;
373       if (!unwinder.Unwind(data)) {
374         printf("Failed to unwind %s\n", data.GetErrorString().c_str());
375         return PID_RUN_FAIL;
376       }
377       const auto& frame = data.frames[0];
378       return verify_func(frame);
379     });
380   }
381 };
382 
TEST_F(AndroidRemoteUnwinderTest,initialize_before)383 TEST_F(AndroidRemoteUnwinderTest, initialize_before) {
384   ASSERT_NO_FATAL_FAILURE(Fork());
385 
386   AndroidRemoteUnwinder unwinder(pid_);
387   ErrorData error;
388   ASSERT_TRUE(unwinder.Initialize(error));
389 
390   AndroidUnwinderData data;
391   ASSERT_TRUE(unwinder.Unwind(data));
392 }
393 
TEST_F(AndroidRemoteUnwinderTest,skip_libraries)394 TEST_F(AndroidRemoteUnwinderTest, skip_libraries) {
395   void* test_lib = GetTestLibHandle();
396   ASSERT_TRUE(test_lib != nullptr);
397   void (*wait_func)() = reinterpret_cast<void (*)()>(dlsym(test_lib, "WaitForever"));
398   ASSERT_TRUE(wait_func != nullptr);
399 
400   SetForkFunc([wait_func]() { wait_func(); });
401   Verify([this](const FrameData& frame) {
402     // Make sure that the frame is in the dlopen'd library before proceeding.
403     if (frame.map_info == nullptr ||
404         !android::base::EndsWith(frame.map_info->name(), "/libunwindstack_local.so")) {
405       return PID_RUN_KEEP_GOING;
406     }
407 
408     // Do an unwind removing the libunwindstack_local.so library.
409     AndroidRemoteUnwinder unwinder(pid_, std::vector<std::string>{"libunwindstack_local.so"});
410     AndroidUnwinderData data;
411     if (!unwinder.Unwind(data)) {
412       printf("Failed to unwind %s\n", data.GetErrorString().c_str());
413       return PID_RUN_FAIL;
414     }
415 
416     // Verify that library is properly ignored.
417     if (android::base::EndsWith(data.frames[0].map_info->name(), "/libunwindstack_local.so")) {
418       printf("Failed to strip libunwindstack_local.so\n%s\n",
419              GetBacktrace(unwinder, data.frames).c_str());
420       return PID_RUN_FAIL;
421     }
422     return PID_RUN_PASS;
423   });
424 }
425 
TEST_F(AndroidRemoteUnwinderTest,suffix_ignore)426 TEST_F(AndroidRemoteUnwinderTest, suffix_ignore) {
427   Verify([this](const FrameData& frame) {
428     // Wait until the forked process is no longer in libc.so.
429     if (frame.map_info != nullptr && android::base::EndsWith(frame.map_info->name(), ".so")) {
430       return PID_RUN_KEEP_GOING;
431     }
432 
433     AndroidRemoteUnwinder unwinder(pid_, std::vector<std::string>{},
434                                    std::vector<std::string>{"so"});
435     AndroidUnwinderData data;
436     if (!unwinder.Unwind(data)) {
437       printf("Failed to unwind %s\n", data.GetErrorString().c_str());
438 
439       AndroidRemoteUnwinder normal_unwinder(pid_);
440       if (normal_unwinder.Unwind(data)) {
441         printf("Full unwind %s\n", GetBacktrace(normal_unwinder, data.frames).c_str());
442       }
443       return PID_RUN_FAIL;
444     }
445 
446     // Make sure the unwind doesn't include any .so frames.
447     for (const auto& frame : data.frames) {
448       if (frame.map_info != nullptr && android::base::EndsWith(frame.map_info->name(), ".so")) {
449         printf("Found unexpected .so frame\n%s\n", GetBacktrace(unwinder, data.frames).c_str());
450         return PID_RUN_FAIL;
451       }
452     }
453     return PID_RUN_PASS;
454   });
455 }
456 
TEST_F(AndroidRemoteUnwinderTest,remote_get_arch_ptrace_fails)457 TEST_F(AndroidRemoteUnwinderTest, remote_get_arch_ptrace_fails) {
458   AndroidRemoteUnwinder unwinder(getpid());
459   AndroidUnwinderData data;
460   ASSERT_FALSE(unwinder.Unwind(data));
461   EXPECT_EQ("Ptrace Call Failed", data.GetErrorString());
462 }
463 
TEST_F(AndroidRemoteUnwinderTest,remote_get_ptrace_fails)464 TEST_F(AndroidRemoteUnwinderTest, remote_get_ptrace_fails) {
465   AndroidRemoteUnwinder unwinder(getpid(), Regs::CurrentArch());
466   AndroidUnwinderData data;
467   ASSERT_FALSE(unwinder.Unwind(data));
468   EXPECT_EQ("Ptrace Call Failed", data.GetErrorString());
469 }
470 
471 }  // namespace unwindstack
472