blob: 9fe2d1cb596f88e028de4c69bd1819a92432746b [file] [log] [blame]
Christopher Ferris17e91d42013-10-21 13:30:52 -07001/*
2 * Copyright (C) 2013 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
Christopher Ferrisca09ce92015-03-31 17:28:22 -070017#define _GNU_SOURCE 1
Christopher Ferris17e91d42013-10-21 13:30:52 -070018#include <dirent.h>
Christopher Ferris67aba682015-05-08 15:44:46 -070019#include <dlfcn.h>
Christopher Ferris17e91d42013-10-21 13:30:52 -070020#include <errno.h>
Christopher Ferris67aba682015-05-08 15:44:46 -070021#include <fcntl.h>
Christopher Ferrise2960912014-03-07 19:42:19 -080022#include <inttypes.h>
Christopher Ferris17e91d42013-10-21 13:30:52 -070023#include <pthread.h>
24#include <signal.h>
Christopher Ferrise2960912014-03-07 19:42:19 -080025#include <stdint.h>
Christopher Ferris17e91d42013-10-21 13:30:52 -070026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/ptrace.h>
Christopher Ferris67aba682015-05-08 15:44:46 -070030#include <sys/stat.h>
Christopher Ferris17e91d42013-10-21 13:30:52 -070031#include <sys/types.h>
32#include <sys/wait.h>
33#include <time.h>
34#include <unistd.h>
35
Christopher Ferrise2960912014-03-07 19:42:19 -080036#include <algorithm>
Christopher Ferris67aba682015-05-08 15:44:46 -070037#include <list>
Christopher Ferris2b4a63f2015-03-17 14:42:03 -070038#include <memory>
Christopher Ferris5ea2c1f2017-03-23 14:55:01 -070039#include <ostream>
Christopher Ferris2c43cff2015-03-26 19:18:36 -070040#include <string>
Christopher Ferris17e91d42013-10-21 13:30:52 -070041#include <vector>
42
Dan Albert23f750b2015-04-30 12:52:21 -070043#include <backtrace/Backtrace.h>
44#include <backtrace/BacktraceMap.h>
45
Christopher Ferrisf5e568e2017-03-22 13:18:31 -070046#include <android-base/macros.h>
Elliott Hughes4f713192015-12-04 22:00:26 -080047#include <android-base/stringprintf.h>
Christopher Ferris82f3bbd2017-03-14 15:22:26 -070048#include <android-base/unique_fd.h>
Dan Albert23f750b2015-04-30 12:52:21 -070049#include <cutils/atomic.h>
50#include <cutils/threads.h>
51
52#include <gtest/gtest.h>
53
54// For the THREAD_SIGNAL definition.
55#include "BacktraceCurrent.h"
Christopher Ferris5ea2c1f2017-03-23 14:55:01 -070056#include "backtrace_testlib.h"
Christopher Ferris17e91d42013-10-21 13:30:52 -070057#include "thread_utils.h"
58
59// Number of microseconds per milliseconds.
60#define US_PER_MSEC 1000
61
62// Number of nanoseconds in a second.
63#define NS_PER_SEC 1000000000ULL
64
65// Number of simultaneous dumping operations to perform.
Christopher Ferris3cdbfdc2014-11-08 15:57:11 -080066#define NUM_THREADS 40
Christopher Ferris17e91d42013-10-21 13:30:52 -070067
68// Number of simultaneous threads running in our forked process.
69#define NUM_PTRACE_THREADS 5
70
Christopher Ferris46756822014-01-14 20:16:30 -080071struct thread_t {
Christopher Ferris17e91d42013-10-21 13:30:52 -070072 pid_t tid;
73 int32_t state;
74 pthread_t threadId;
Christopher Ferris2b4a63f2015-03-17 14:42:03 -070075 void* data;
Christopher Ferris46756822014-01-14 20:16:30 -080076};
Christopher Ferris17e91d42013-10-21 13:30:52 -070077
Christopher Ferris46756822014-01-14 20:16:30 -080078struct dump_thread_t {
Christopher Ferris17e91d42013-10-21 13:30:52 -070079 thread_t thread;
Christopher Ferris20303f82014-01-10 16:33:16 -080080 Backtrace* backtrace;
Christopher Ferris17e91d42013-10-21 13:30:52 -070081 int32_t* now;
82 int32_t done;
Christopher Ferris46756822014-01-14 20:16:30 -080083};
Christopher Ferris17e91d42013-10-21 13:30:52 -070084
Christopher Ferris82f3bbd2017-03-14 15:22:26 -070085static uint64_t NanoTime() {
Christopher Ferris17e91d42013-10-21 13:30:52 -070086 struct timespec t = { 0, 0 };
87 clock_gettime(CLOCK_MONOTONIC, &t);
88 return static_cast<uint64_t>(t.tv_sec * NS_PER_SEC + t.tv_nsec);
89}
90
Christopher Ferris82f3bbd2017-03-14 15:22:26 -070091static std::string DumpFrames(Backtrace* backtrace) {
Christopher Ferris20303f82014-01-10 16:33:16 -080092 if (backtrace->NumFrames() == 0) {
Christopher Ferris97e00bb2015-04-02 14:22:31 -070093 return " No frames to dump.\n";
Christopher Ferris20303f82014-01-10 16:33:16 -080094 }
95
Christopher Ferris2c43cff2015-03-26 19:18:36 -070096 std::string frame;
Christopher Ferris20303f82014-01-10 16:33:16 -080097 for (size_t i = 0; i < backtrace->NumFrames(); i++) {
Christopher Ferris2c43cff2015-03-26 19:18:36 -070098 frame += " " + backtrace->FormatFrameData(i) + '\n';
Christopher Ferris17e91d42013-10-21 13:30:52 -070099 }
Christopher Ferris2c43cff2015-03-26 19:18:36 -0700100 return frame;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700101}
102
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700103static void WaitForStop(pid_t pid) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700104 uint64_t start = NanoTime();
105
106 siginfo_t si;
107 while (ptrace(PTRACE_GETSIGINFO, pid, 0, &si) < 0 && (errno == EINTR || errno == ESRCH)) {
108 if ((NanoTime() - start) > NS_PER_SEC) {
109 printf("The process did not get to a stopping point in 1 second.\n");
110 break;
111 }
112 usleep(US_PER_MSEC);
113 }
114}
115
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700116static void CreateRemoteProcess(pid_t* pid) {
117 if ((*pid = fork()) == 0) {
118 while (true)
119 ;
120 _exit(0);
121 }
122 ASSERT_NE(-1, *pid);
123
124 ASSERT_TRUE(ptrace(PTRACE_ATTACH, *pid, 0, 0) == 0);
125
126 // Wait for the process to get to a stopping point.
127 WaitForStop(*pid);
128}
129
130static void FinishRemoteProcess(pid_t pid) {
131 ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0);
132
133 kill(pid, SIGKILL);
134 ASSERT_EQ(waitpid(pid, nullptr, 0), pid);
135}
136
137static bool ReadyLevelBacktrace(Backtrace* backtrace) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700138 // See if test_level_four is in the backtrace.
139 bool found = false;
Christopher Ferris46756822014-01-14 20:16:30 -0800140 for (Backtrace::const_iterator it = backtrace->begin(); it != backtrace->end(); ++it) {
141 if (it->func_name == "test_level_four") {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700142 found = true;
143 break;
144 }
145 }
146
147 return found;
148}
149
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700150static void VerifyLevelDump(Backtrace* backtrace) {
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700151 ASSERT_GT(backtrace->NumFrames(), static_cast<size_t>(0))
152 << DumpFrames(backtrace);
153 ASSERT_LT(backtrace->NumFrames(), static_cast<size_t>(MAX_BACKTRACE_FRAMES))
154 << DumpFrames(backtrace);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700155
156 // Look through the frames starting at the highest to find the
157 // frame we want.
158 size_t frame_num = 0;
Christopher Ferris20303f82014-01-10 16:33:16 -0800159 for (size_t i = backtrace->NumFrames()-1; i > 2; i--) {
Christopher Ferris46756822014-01-14 20:16:30 -0800160 if (backtrace->GetFrame(i)->func_name == "test_level_one") {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700161 frame_num = i;
162 break;
163 }
164 }
Christopher Ferris2c43cff2015-03-26 19:18:36 -0700165 ASSERT_LT(static_cast<size_t>(0), frame_num) << DumpFrames(backtrace);
166 ASSERT_LE(static_cast<size_t>(3), frame_num) << DumpFrames(backtrace);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700167
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700168 ASSERT_EQ(backtrace->GetFrame(frame_num)->func_name, "test_level_one")
169 << DumpFrames(backtrace);
170 ASSERT_EQ(backtrace->GetFrame(frame_num-1)->func_name, "test_level_two")
171 << DumpFrames(backtrace);
172 ASSERT_EQ(backtrace->GetFrame(frame_num-2)->func_name, "test_level_three")
173 << DumpFrames(backtrace);
174 ASSERT_EQ(backtrace->GetFrame(frame_num-3)->func_name, "test_level_four")
175 << DumpFrames(backtrace);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700176}
177
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700178static void VerifyLevelBacktrace(void*) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700179 std::unique_ptr<Backtrace> backtrace(
Christopher Ferris20303f82014-01-10 16:33:16 -0800180 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700181 ASSERT_TRUE(backtrace.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800182 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800183 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700184
Christopher Ferris20303f82014-01-10 16:33:16 -0800185 VerifyLevelDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700186}
187
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700188static bool ReadyMaxBacktrace(Backtrace* backtrace) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800189 return (backtrace->NumFrames() == MAX_BACKTRACE_FRAMES);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700190}
191
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700192static void VerifyMaxDump(Backtrace* backtrace) {
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700193 ASSERT_EQ(backtrace->NumFrames(), static_cast<size_t>(MAX_BACKTRACE_FRAMES))
194 << DumpFrames(backtrace);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700195 // Verify that the last frame is our recursive call.
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700196 ASSERT_EQ(backtrace->GetFrame(MAX_BACKTRACE_FRAMES-1)->func_name, "test_recursive_call")
197 << DumpFrames(backtrace);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700198}
199
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700200static void VerifyMaxBacktrace(void*) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700201 std::unique_ptr<Backtrace> backtrace(
Christopher Ferris20303f82014-01-10 16:33:16 -0800202 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700203 ASSERT_TRUE(backtrace.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800204 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800205 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700206
Christopher Ferris20303f82014-01-10 16:33:16 -0800207 VerifyMaxDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700208}
209
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700210static void ThreadSetState(void* data) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700211 thread_t* thread = reinterpret_cast<thread_t*>(data);
212 android_atomic_acquire_store(1, &thread->state);
213 volatile int i = 0;
214 while (thread->state) {
215 i++;
216 }
217}
218
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700219static bool WaitForNonZero(int32_t* value, uint64_t seconds) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700220 uint64_t start = NanoTime();
221 do {
222 if (android_atomic_acquire_load(value)) {
223 return true;
224 }
225 } while ((NanoTime() - start) < seconds * NS_PER_SEC);
226 return false;
227}
228
Christopher Ferrisca09ce92015-03-31 17:28:22 -0700229TEST(libbacktrace, local_no_unwind_frames) {
230 // Verify that a local unwind does not include any frames within
231 // libunwind or libbacktrace.
232 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), getpid()));
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700233 ASSERT_TRUE(backtrace.get() != nullptr);
Christopher Ferrisca09ce92015-03-31 17:28:22 -0700234 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800235 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferrisca09ce92015-03-31 17:28:22 -0700236
237 ASSERT_TRUE(backtrace->NumFrames() != 0);
238 for (const auto& frame : *backtrace ) {
239 if (BacktraceMap::IsValid(frame.map)) {
240 const std::string name = basename(frame.map.name.c_str());
241 ASSERT_TRUE(name != "libunwind.so" && name != "libbacktrace.so")
242 << DumpFrames(backtrace.get());
243 }
244 break;
245 }
246}
247
Christopher Ferris17e91d42013-10-21 13:30:52 -0700248TEST(libbacktrace, local_trace) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700249 ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelBacktrace, nullptr), 0);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700250}
251
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700252static void VerifyIgnoreFrames(Backtrace* bt_all, Backtrace* bt_ign1, Backtrace* bt_ign2,
253 const char* cur_proc) {
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700254 EXPECT_EQ(bt_all->NumFrames(), bt_ign1->NumFrames() + 1)
255 << "All backtrace:\n" << DumpFrames(bt_all) << "Ignore 1 backtrace:\n" << DumpFrames(bt_ign1);
256 EXPECT_EQ(bt_all->NumFrames(), bt_ign2->NumFrames() + 2)
257 << "All backtrace:\n" << DumpFrames(bt_all) << "Ignore 2 backtrace:\n" << DumpFrames(bt_ign2);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700258
259 // Check all of the frames are the same > the current frame.
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700260 bool check = (cur_proc == nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800261 for (size_t i = 0; i < bt_ign2->NumFrames(); i++) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700262 if (check) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800263 EXPECT_EQ(bt_ign2->GetFrame(i)->pc, bt_ign1->GetFrame(i+1)->pc);
264 EXPECT_EQ(bt_ign2->GetFrame(i)->sp, bt_ign1->GetFrame(i+1)->sp);
265 EXPECT_EQ(bt_ign2->GetFrame(i)->stack_size, bt_ign1->GetFrame(i+1)->stack_size);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700266
Christopher Ferris20303f82014-01-10 16:33:16 -0800267 EXPECT_EQ(bt_ign2->GetFrame(i)->pc, bt_all->GetFrame(i+2)->pc);
268 EXPECT_EQ(bt_ign2->GetFrame(i)->sp, bt_all->GetFrame(i+2)->sp);
269 EXPECT_EQ(bt_ign2->GetFrame(i)->stack_size, bt_all->GetFrame(i+2)->stack_size);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700270 }
Christopher Ferris46756822014-01-14 20:16:30 -0800271 if (!check && bt_ign2->GetFrame(i)->func_name == cur_proc) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700272 check = true;
273 }
274 }
275}
276
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700277static void VerifyLevelIgnoreFrames(void*) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700278 std::unique_ptr<Backtrace> all(
Christopher Ferris20303f82014-01-10 16:33:16 -0800279 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700280 ASSERT_TRUE(all.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800281 ASSERT_TRUE(all->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800282 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, all->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700283
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700284 std::unique_ptr<Backtrace> ign1(
Christopher Ferris20303f82014-01-10 16:33:16 -0800285 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700286 ASSERT_TRUE(ign1.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800287 ASSERT_TRUE(ign1->Unwind(1));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800288 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, ign1->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700289
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700290 std::unique_ptr<Backtrace> ign2(
Christopher Ferris20303f82014-01-10 16:33:16 -0800291 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700292 ASSERT_TRUE(ign2.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800293 ASSERT_TRUE(ign2->Unwind(2));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800294 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, ign2->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700295
Christopher Ferris20303f82014-01-10 16:33:16 -0800296 VerifyIgnoreFrames(all.get(), ign1.get(), ign2.get(), "VerifyLevelIgnoreFrames");
Christopher Ferris17e91d42013-10-21 13:30:52 -0700297}
298
299TEST(libbacktrace, local_trace_ignore_frames) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700300 ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelIgnoreFrames, nullptr), 0);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700301}
302
303TEST(libbacktrace, local_max_trace) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700304 ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, VerifyMaxBacktrace, nullptr), 0);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700305}
306
Christopher Ferris458cc662017-08-28 16:31:18 -0700307static void VerifyProcTest(pid_t pid, pid_t tid, bool (*ReadyFunc)(Backtrace*),
308 void (*VerifyFunc)(Backtrace*),
309 Backtrace* (*back_func)(pid_t, pid_t, BacktraceMap*),
310 BacktraceMap* (*map_func)(pid_t, bool)) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700311 pid_t ptrace_tid;
312 if (tid < 0) {
313 ptrace_tid = pid;
314 } else {
315 ptrace_tid = tid;
316 }
317 uint64_t start = NanoTime();
318 bool verified = false;
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700319 std::string last_dump;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700320 do {
321 usleep(US_PER_MSEC);
322 if (ptrace(PTRACE_ATTACH, ptrace_tid, 0, 0) == 0) {
323 // Wait for the process to get to a stopping point.
324 WaitForStop(ptrace_tid);
325
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700326 std::unique_ptr<BacktraceMap> map;
Christopher Ferris458cc662017-08-28 16:31:18 -0700327 map.reset(map_func(pid, false));
328 std::unique_ptr<Backtrace> backtrace(back_func(pid, tid, map.get()));
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700329 ASSERT_TRUE(backtrace.get() != nullptr);
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700330 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800331 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferris20303f82014-01-10 16:33:16 -0800332 if (ReadyFunc(backtrace.get())) {
333 VerifyFunc(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700334 verified = true;
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700335 } else {
336 last_dump = DumpFrames(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700337 }
Christopher Ferris20303f82014-01-10 16:33:16 -0800338
Christopher Ferris17e91d42013-10-21 13:30:52 -0700339 ASSERT_TRUE(ptrace(PTRACE_DETACH, ptrace_tid, 0, 0) == 0);
340 }
341 // If 5 seconds have passed, then we are done.
342 } while (!verified && (NanoTime() - start) <= 5 * NS_PER_SEC);
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700343 ASSERT_TRUE(verified) << "Last backtrace:\n" << last_dump;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700344}
345
346TEST(libbacktrace, ptrace_trace) {
347 pid_t pid;
348 if ((pid = fork()) == 0) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700349 ASSERT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0);
Christopher Ferrise2960912014-03-07 19:42:19 -0800350 _exit(1);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700351 }
Christopher Ferris458cc662017-08-28 16:31:18 -0700352 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyLevelBacktrace, VerifyLevelDump,
353 Backtrace::Create, BacktraceMap::Create);
Christopher Ferrisdf290612014-01-22 19:21:07 -0800354
355 kill(pid, SIGKILL);
356 int status;
357 ASSERT_EQ(waitpid(pid, &status, 0), pid);
358}
359
Christopher Ferris458cc662017-08-28 16:31:18 -0700360TEST(libbacktrace, ptrace_trace_new) {
Christopher Ferrisdf290612014-01-22 19:21:07 -0800361 pid_t pid;
362 if ((pid = fork()) == 0) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700363 ASSERT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0);
Christopher Ferrise2960912014-03-07 19:42:19 -0800364 _exit(1);
Christopher Ferrisdf290612014-01-22 19:21:07 -0800365 }
Christopher Ferris458cc662017-08-28 16:31:18 -0700366 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyLevelBacktrace, VerifyLevelDump,
367 Backtrace::CreateNew, BacktraceMap::CreateNew);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700368
369 kill(pid, SIGKILL);
370 int status;
371 ASSERT_EQ(waitpid(pid, &status, 0), pid);
372}
373
374TEST(libbacktrace, ptrace_max_trace) {
375 pid_t pid;
376 if ((pid = fork()) == 0) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700377 ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, nullptr, nullptr), 0);
Christopher Ferrise2960912014-03-07 19:42:19 -0800378 _exit(1);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700379 }
Christopher Ferris458cc662017-08-28 16:31:18 -0700380 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyMaxBacktrace, VerifyMaxDump, Backtrace::Create,
381 BacktraceMap::Create);
382
383 kill(pid, SIGKILL);
384 int status;
385 ASSERT_EQ(waitpid(pid, &status, 0), pid);
386}
387
388TEST(libbacktrace, ptrace_max_trace_new) {
389 pid_t pid;
390 if ((pid = fork()) == 0) {
391 ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES + 10, nullptr, nullptr), 0);
392 _exit(1);
393 }
394 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyMaxBacktrace, VerifyMaxDump,
395 Backtrace::CreateNew, BacktraceMap::CreateNew);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700396
397 kill(pid, SIGKILL);
398 int status;
399 ASSERT_EQ(waitpid(pid, &status, 0), pid);
400}
401
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700402static void VerifyProcessIgnoreFrames(Backtrace* bt_all) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700403 std::unique_ptr<Backtrace> ign1(Backtrace::Create(bt_all->Pid(), BACKTRACE_CURRENT_THREAD));
404 ASSERT_TRUE(ign1.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800405 ASSERT_TRUE(ign1->Unwind(1));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800406 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, ign1->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700407
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700408 std::unique_ptr<Backtrace> ign2(Backtrace::Create(bt_all->Pid(), BACKTRACE_CURRENT_THREAD));
409 ASSERT_TRUE(ign2.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800410 ASSERT_TRUE(ign2->Unwind(2));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800411 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, ign2->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700412
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700413 VerifyIgnoreFrames(bt_all, ign1.get(), ign2.get(), nullptr);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700414}
415
416TEST(libbacktrace, ptrace_ignore_frames) {
417 pid_t pid;
418 if ((pid = fork()) == 0) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700419 ASSERT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0);
Christopher Ferrise2960912014-03-07 19:42:19 -0800420 _exit(1);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700421 }
Christopher Ferris458cc662017-08-28 16:31:18 -0700422 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyLevelBacktrace, VerifyProcessIgnoreFrames,
423 Backtrace::Create, BacktraceMap::Create);
424
425 kill(pid, SIGKILL);
426 int status;
427 ASSERT_EQ(waitpid(pid, &status, 0), pid);
428}
429
430TEST(libbacktrace, ptrace_ignore_frames_new) {
431 pid_t pid;
432 if ((pid = fork()) == 0) {
433 ASSERT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0);
434 _exit(1);
435 }
436 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyLevelBacktrace, VerifyProcessIgnoreFrames,
437 Backtrace::CreateNew, BacktraceMap::CreateNew);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700438
439 kill(pid, SIGKILL);
440 int status;
441 ASSERT_EQ(waitpid(pid, &status, 0), pid);
442}
443
444// Create a process with multiple threads and dump all of the threads.
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700445static void* PtraceThreadLevelRun(void*) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700446 EXPECT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0);
447 return nullptr;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700448}
449
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700450static void GetThreads(pid_t pid, std::vector<pid_t>* threads) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700451 // Get the list of tasks.
452 char task_path[128];
453 snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
454
James Hawkins588a2ca2016-02-18 14:52:46 -0800455 std::unique_ptr<DIR, decltype(&closedir)> tasks_dir(opendir(task_path), closedir);
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700456 ASSERT_TRUE(tasks_dir != nullptr);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700457 struct dirent* entry;
James Hawkins588a2ca2016-02-18 14:52:46 -0800458 while ((entry = readdir(tasks_dir.get())) != nullptr) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700459 char* end;
460 pid_t tid = strtoul(entry->d_name, &end, 10);
461 if (*end == '\0') {
462 threads->push_back(tid);
463 }
464 }
Christopher Ferris17e91d42013-10-21 13:30:52 -0700465}
466
467TEST(libbacktrace, ptrace_threads) {
468 pid_t pid;
469 if ((pid = fork()) == 0) {
470 for (size_t i = 0; i < NUM_PTRACE_THREADS; i++) {
471 pthread_attr_t attr;
472 pthread_attr_init(&attr);
473 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
474
475 pthread_t thread;
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700476 ASSERT_TRUE(pthread_create(&thread, &attr, PtraceThreadLevelRun, nullptr) == 0);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700477 }
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700478 ASSERT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0);
Christopher Ferrise2960912014-03-07 19:42:19 -0800479 _exit(1);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700480 }
481
482 // Check to see that all of the threads are running before unwinding.
483 std::vector<pid_t> threads;
484 uint64_t start = NanoTime();
485 do {
486 usleep(US_PER_MSEC);
487 threads.clear();
488 GetThreads(pid, &threads);
489 } while ((threads.size() != NUM_PTRACE_THREADS + 1) &&
490 ((NanoTime() - start) <= 5 * NS_PER_SEC));
491 ASSERT_EQ(threads.size(), static_cast<size_t>(NUM_PTRACE_THREADS + 1));
492
493 ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0);
494 WaitForStop(pid);
495 for (std::vector<int>::const_iterator it = threads.begin(); it != threads.end(); ++it) {
496 // Skip the current forked process, we only care about the threads.
497 if (pid == *it) {
498 continue;
499 }
Christopher Ferris458cc662017-08-28 16:31:18 -0700500 VerifyProcTest(pid, *it, ReadyLevelBacktrace, VerifyLevelDump, Backtrace::Create,
501 BacktraceMap::Create);
502 }
503
504 FinishRemoteProcess(pid);
505}
506
507TEST(libbacktrace, ptrace_threads_new) {
508 pid_t pid;
509 if ((pid = fork()) == 0) {
510 for (size_t i = 0; i < NUM_PTRACE_THREADS; i++) {
511 pthread_attr_t attr;
512 pthread_attr_init(&attr);
513 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
514
515 pthread_t thread;
516 ASSERT_TRUE(pthread_create(&thread, &attr, PtraceThreadLevelRun, nullptr) == 0);
517 }
518 ASSERT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0);
519 _exit(1);
520 }
521
522 // Check to see that all of the threads are running before unwinding.
523 std::vector<pid_t> threads;
524 uint64_t start = NanoTime();
525 do {
526 usleep(US_PER_MSEC);
527 threads.clear();
528 GetThreads(pid, &threads);
529 } while ((threads.size() != NUM_PTRACE_THREADS + 1) && ((NanoTime() - start) <= 5 * NS_PER_SEC));
530 ASSERT_EQ(threads.size(), static_cast<size_t>(NUM_PTRACE_THREADS + 1));
531
532 ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0);
533 WaitForStop(pid);
534 for (std::vector<int>::const_iterator it = threads.begin(); it != threads.end(); ++it) {
535 // Skip the current forked process, we only care about the threads.
536 if (pid == *it) {
537 continue;
538 }
539 VerifyProcTest(pid, *it, ReadyLevelBacktrace, VerifyLevelDump, Backtrace::CreateNew,
540 BacktraceMap::CreateNew);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700541 }
Christopher Ferris17e91d42013-10-21 13:30:52 -0700542
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700543 FinishRemoteProcess(pid);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700544}
545
546void VerifyLevelThread(void*) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700547 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), gettid()));
548 ASSERT_TRUE(backtrace.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800549 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800550 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700551
Christopher Ferris20303f82014-01-10 16:33:16 -0800552 VerifyLevelDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700553}
554
555TEST(libbacktrace, thread_current_level) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700556 ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelThread, nullptr), 0);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700557}
558
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700559static void VerifyMaxThread(void*) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700560 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), gettid()));
561 ASSERT_TRUE(backtrace.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800562 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800563 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700564
Christopher Ferris20303f82014-01-10 16:33:16 -0800565 VerifyMaxDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700566}
567
568TEST(libbacktrace, thread_current_max) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700569 ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, VerifyMaxThread, nullptr), 0);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700570}
571
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700572static void* ThreadLevelRun(void* data) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700573 thread_t* thread = reinterpret_cast<thread_t*>(data);
574
575 thread->tid = gettid();
576 EXPECT_NE(test_level_one(1, 2, 3, 4, ThreadSetState, data), 0);
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700577 return nullptr;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700578}
579
580TEST(libbacktrace, thread_level_trace) {
581 pthread_attr_t attr;
582 pthread_attr_init(&attr);
583 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
584
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700585 thread_t thread_data = { 0, 0, 0, nullptr };
Christopher Ferris17e91d42013-10-21 13:30:52 -0700586 pthread_t thread;
587 ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0);
588
589 // Wait up to 2 seconds for the tid to be set.
590 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));
591
Christopher Ferrisaa63d9f2014-04-29 09:35:30 -0700592 // Make sure that the thread signal used is not visible when compiled for
593 // the target.
594#if !defined(__GLIBC__)
595 ASSERT_LT(THREAD_SIGNAL, SIGRTMIN);
596#endif
597
Christopher Ferris17e91d42013-10-21 13:30:52 -0700598 // Save the current signal action and make sure it is restored afterwards.
599 struct sigaction cur_action;
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700600 ASSERT_TRUE(sigaction(THREAD_SIGNAL, nullptr, &cur_action) == 0);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700601
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700602 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid));
603 ASSERT_TRUE(backtrace.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800604 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800605 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700606
Christopher Ferris20303f82014-01-10 16:33:16 -0800607 VerifyLevelDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700608
609 // Tell the thread to exit its infinite loop.
610 android_atomic_acquire_store(0, &thread_data.state);
611
612 // Verify that the old action was restored.
613 struct sigaction new_action;
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700614 ASSERT_TRUE(sigaction(THREAD_SIGNAL, nullptr, &new_action) == 0);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700615 EXPECT_EQ(cur_action.sa_sigaction, new_action.sa_sigaction);
Christopher Ferris3cdbfdc2014-11-08 15:57:11 -0800616 // The SA_RESTORER flag gets set behind our back, so a direct comparison
617 // doesn't work unless we mask the value off. Mips doesn't have this
618 // flag, so skip this on that platform.
Christopher Ferris2c43cff2015-03-26 19:18:36 -0700619#if defined(SA_RESTORER)
Christopher Ferris3cdbfdc2014-11-08 15:57:11 -0800620 cur_action.sa_flags &= ~SA_RESTORER;
621 new_action.sa_flags &= ~SA_RESTORER;
Christopher Ferris2c43cff2015-03-26 19:18:36 -0700622#elif defined(__GLIBC__)
623 // Our host compiler doesn't appear to define this flag for some reason.
624 cur_action.sa_flags &= ~0x04000000;
625 new_action.sa_flags &= ~0x04000000;
Christopher Ferris3cdbfdc2014-11-08 15:57:11 -0800626#endif
Christopher Ferris17e91d42013-10-21 13:30:52 -0700627 EXPECT_EQ(cur_action.sa_flags, new_action.sa_flags);
628}
629
630TEST(libbacktrace, thread_ignore_frames) {
631 pthread_attr_t attr;
632 pthread_attr_init(&attr);
633 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
634
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700635 thread_t thread_data = { 0, 0, 0, nullptr };
Christopher Ferris17e91d42013-10-21 13:30:52 -0700636 pthread_t thread;
637 ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0);
638
639 // Wait up to 2 seconds for the tid to be set.
640 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));
641
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700642 std::unique_ptr<Backtrace> all(Backtrace::Create(getpid(), thread_data.tid));
643 ASSERT_TRUE(all.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800644 ASSERT_TRUE(all->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800645 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, all->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700646
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700647 std::unique_ptr<Backtrace> ign1(Backtrace::Create(getpid(), thread_data.tid));
648 ASSERT_TRUE(ign1.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800649 ASSERT_TRUE(ign1->Unwind(1));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800650 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, ign1->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700651
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700652 std::unique_ptr<Backtrace> ign2(Backtrace::Create(getpid(), thread_data.tid));
653 ASSERT_TRUE(ign2.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800654 ASSERT_TRUE(ign2->Unwind(2));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800655 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, ign2->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700656
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700657 VerifyIgnoreFrames(all.get(), ign1.get(), ign2.get(), nullptr);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700658
659 // Tell the thread to exit its infinite loop.
660 android_atomic_acquire_store(0, &thread_data.state);
661}
662
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700663static void* ThreadMaxRun(void* data) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700664 thread_t* thread = reinterpret_cast<thread_t*>(data);
665
666 thread->tid = gettid();
667 EXPECT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, ThreadSetState, data), 0);
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700668 return nullptr;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700669}
670
671TEST(libbacktrace, thread_max_trace) {
672 pthread_attr_t attr;
673 pthread_attr_init(&attr);
674 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
675
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700676 thread_t thread_data = { 0, 0, 0, nullptr };
Christopher Ferris17e91d42013-10-21 13:30:52 -0700677 pthread_t thread;
678 ASSERT_TRUE(pthread_create(&thread, &attr, ThreadMaxRun, &thread_data) == 0);
679
680 // Wait for the tid to be set.
681 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));
682
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700683 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid));
684 ASSERT_TRUE(backtrace.get() != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800685 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800686 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700687
Christopher Ferris20303f82014-01-10 16:33:16 -0800688 VerifyMaxDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700689
690 // Tell the thread to exit its infinite loop.
691 android_atomic_acquire_store(0, &thread_data.state);
692}
693
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700694static void* ThreadDump(void* data) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700695 dump_thread_t* dump = reinterpret_cast<dump_thread_t*>(data);
696 while (true) {
697 if (android_atomic_acquire_load(dump->now)) {
698 break;
699 }
700 }
701
Christopher Ferris17e91d42013-10-21 13:30:52 -0700702 // The status of the actual unwind will be checked elsewhere.
Christopher Ferris20303f82014-01-10 16:33:16 -0800703 dump->backtrace = Backtrace::Create(getpid(), dump->thread.tid);
704 dump->backtrace->Unwind(0);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700705
706 android_atomic_acquire_store(1, &dump->done);
707
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700708 return nullptr;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700709}
710
711TEST(libbacktrace, thread_multiple_dump) {
712 // Dump NUM_THREADS simultaneously.
713 std::vector<thread_t> runners(NUM_THREADS);
714 std::vector<dump_thread_t> dumpers(NUM_THREADS);
715
716 pthread_attr_t attr;
717 pthread_attr_init(&attr);
718 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
719 for (size_t i = 0; i < NUM_THREADS; i++) {
720 // Launch the runners, they will spin in hard loops doing nothing.
721 runners[i].tid = 0;
722 runners[i].state = 0;
723 ASSERT_TRUE(pthread_create(&runners[i].threadId, &attr, ThreadMaxRun, &runners[i]) == 0);
724 }
725
726 // Wait for tids to be set.
727 for (std::vector<thread_t>::iterator it = runners.begin(); it != runners.end(); ++it) {
Christopher Ferris3cdbfdc2014-11-08 15:57:11 -0800728 ASSERT_TRUE(WaitForNonZero(&it->state, 30));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700729 }
730
731 // Start all of the dumpers at once, they will spin until they are signalled
732 // to begin their dump run.
733 int32_t dump_now = 0;
734 for (size_t i = 0; i < NUM_THREADS; i++) {
735 dumpers[i].thread.tid = runners[i].tid;
736 dumpers[i].thread.state = 0;
737 dumpers[i].done = 0;
738 dumpers[i].now = &dump_now;
739
740 ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0);
741 }
742
743 // Start all of the dumpers going at once.
744 android_atomic_acquire_store(1, &dump_now);
745
746 for (size_t i = 0; i < NUM_THREADS; i++) {
Christopher Ferris3cdbfdc2014-11-08 15:57:11 -0800747 ASSERT_TRUE(WaitForNonZero(&dumpers[i].done, 30));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700748
749 // Tell the runner thread to exit its infinite loop.
750 android_atomic_acquire_store(0, &runners[i].state);
751
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700752 ASSERT_TRUE(dumpers[i].backtrace != nullptr);
Christopher Ferris20303f82014-01-10 16:33:16 -0800753 VerifyMaxDump(dumpers[i].backtrace);
754
755 delete dumpers[i].backtrace;
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700756 dumpers[i].backtrace = nullptr;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700757 }
758}
759
Christopher Ferrisa2efd3a2014-05-06 15:23:59 -0700760TEST(libbacktrace, thread_multiple_dump_same_thread) {
761 pthread_attr_t attr;
762 pthread_attr_init(&attr);
763 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
764 thread_t runner;
765 runner.tid = 0;
766 runner.state = 0;
767 ASSERT_TRUE(pthread_create(&runner.threadId, &attr, ThreadMaxRun, &runner) == 0);
768
769 // Wait for tids to be set.
Christopher Ferris3cdbfdc2014-11-08 15:57:11 -0800770 ASSERT_TRUE(WaitForNonZero(&runner.state, 30));
Christopher Ferrisa2efd3a2014-05-06 15:23:59 -0700771
772 // Start all of the dumpers at once, they will spin until they are signalled
773 // to begin their dump run.
774 int32_t dump_now = 0;
775 // Dump the same thread NUM_THREADS simultaneously.
776 std::vector<dump_thread_t> dumpers(NUM_THREADS);
777 for (size_t i = 0; i < NUM_THREADS; i++) {
778 dumpers[i].thread.tid = runner.tid;
779 dumpers[i].thread.state = 0;
780 dumpers[i].done = 0;
781 dumpers[i].now = &dump_now;
782
783 ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0);
784 }
785
786 // Start all of the dumpers going at once.
787 android_atomic_acquire_store(1, &dump_now);
788
789 for (size_t i = 0; i < NUM_THREADS; i++) {
Christopher Ferris3cdbfdc2014-11-08 15:57:11 -0800790 ASSERT_TRUE(WaitForNonZero(&dumpers[i].done, 30));
Christopher Ferrisa2efd3a2014-05-06 15:23:59 -0700791
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700792 ASSERT_TRUE(dumpers[i].backtrace != nullptr);
Christopher Ferrisa2efd3a2014-05-06 15:23:59 -0700793 VerifyMaxDump(dumpers[i].backtrace);
794
795 delete dumpers[i].backtrace;
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700796 dumpers[i].backtrace = nullptr;
Christopher Ferrisa2efd3a2014-05-06 15:23:59 -0700797 }
798
799 // Tell the runner thread to exit its infinite loop.
800 android_atomic_acquire_store(0, &runner.state);
801}
802
Christopher Ferrisdf290612014-01-22 19:21:07 -0800803// This test is for UnwindMaps that should share the same map cursor when
804// multiple maps are created for the current process at the same time.
805TEST(libbacktrace, simultaneous_maps) {
806 BacktraceMap* map1 = BacktraceMap::Create(getpid());
807 BacktraceMap* map2 = BacktraceMap::Create(getpid());
808 BacktraceMap* map3 = BacktraceMap::Create(getpid());
809
810 Backtrace* back1 = Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD, map1);
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700811 ASSERT_TRUE(back1 != nullptr);
Christopher Ferrisdf290612014-01-22 19:21:07 -0800812 EXPECT_TRUE(back1->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800813 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, back1->GetError());
Christopher Ferrisdf290612014-01-22 19:21:07 -0800814 delete back1;
815 delete map1;
816
817 Backtrace* back2 = Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD, map2);
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700818 ASSERT_TRUE(back2 != nullptr);
Christopher Ferrisdf290612014-01-22 19:21:07 -0800819 EXPECT_TRUE(back2->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800820 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, back2->GetError());
Christopher Ferrisdf290612014-01-22 19:21:07 -0800821 delete back2;
822 delete map2;
823
824 Backtrace* back3 = Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD, map3);
Christopher Ferris97e00bb2015-04-02 14:22:31 -0700825 ASSERT_TRUE(back3 != nullptr);
Christopher Ferrisdf290612014-01-22 19:21:07 -0800826 EXPECT_TRUE(back3->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -0800827 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, back3->GetError());
Christopher Ferrisdf290612014-01-22 19:21:07 -0800828 delete back3;
829 delete map3;
830}
831
Christopher Ferris12385e32015-02-06 13:22:01 -0800832TEST(libbacktrace, fillin_erases) {
833 BacktraceMap* back_map = BacktraceMap::Create(getpid());
834
835 backtrace_map_t map;
836
837 map.start = 1;
838 map.end = 3;
839 map.flags = 1;
840 map.name = "Initialized";
841 back_map->FillIn(0, &map);
842 delete back_map;
843
844 ASSERT_FALSE(BacktraceMap::IsValid(map));
845 ASSERT_EQ(static_cast<uintptr_t>(0), map.start);
846 ASSERT_EQ(static_cast<uintptr_t>(0), map.end);
847 ASSERT_EQ(0, map.flags);
848 ASSERT_EQ("", map.name);
849}
850
Christopher Ferris17e91d42013-10-21 13:30:52 -0700851TEST(libbacktrace, format_test) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700852 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD));
853 ASSERT_TRUE(backtrace.get() != nullptr);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700854
Christopher Ferris20303f82014-01-10 16:33:16 -0800855 backtrace_frame_data_t frame;
Christopher Ferris46756822014-01-14 20:16:30 -0800856 frame.num = 1;
857 frame.pc = 2;
Christopher Ferris96722b02017-07-19 14:20:46 -0700858 frame.rel_pc = 2;
Christopher Ferris46756822014-01-14 20:16:30 -0800859 frame.sp = 0;
860 frame.stack_size = 0;
Christopher Ferris46756822014-01-14 20:16:30 -0800861 frame.func_offset = 0;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700862
Christopher Ferris46756822014-01-14 20:16:30 -0800863 // Check no map set.
Christopher Ferris20303f82014-01-10 16:33:16 -0800864 frame.num = 1;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700865#if defined(__LP64__)
Christopher Ferris46756822014-01-14 20:16:30 -0800866 EXPECT_EQ("#01 pc 0000000000000002 <unknown>",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700867#else
Christopher Ferris46756822014-01-14 20:16:30 -0800868 EXPECT_EQ("#01 pc 00000002 <unknown>",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700869#endif
Christopher Ferris46756822014-01-14 20:16:30 -0800870 backtrace->FormatFrameData(&frame));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700871
Christopher Ferris46756822014-01-14 20:16:30 -0800872 // Check map name empty, but exists.
Christopher Ferrisda750a72015-11-30 13:36:08 -0800873 frame.pc = 0xb0020;
Christopher Ferris96722b02017-07-19 14:20:46 -0700874 frame.rel_pc = 0x20;
Christopher Ferrisda750a72015-11-30 13:36:08 -0800875 frame.map.start = 0xb0000;
876 frame.map.end = 0xbffff;
Christopher Ferris96722b02017-07-19 14:20:46 -0700877 frame.map.load_bias = 0;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700878#if defined(__LP64__)
Christopher Ferrisda750a72015-11-30 13:36:08 -0800879 EXPECT_EQ("#01 pc 0000000000000020 <anonymous:00000000000b0000>",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700880#else
Christopher Ferrisda750a72015-11-30 13:36:08 -0800881 EXPECT_EQ("#01 pc 00000020 <anonymous:000b0000>",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700882#endif
Christopher Ferris46756822014-01-14 20:16:30 -0800883 backtrace->FormatFrameData(&frame));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700884
Christopher Ferrisda750a72015-11-30 13:36:08 -0800885 // Check map name begins with a [.
886 frame.pc = 0xc0020;
887 frame.map.start = 0xc0000;
888 frame.map.end = 0xcffff;
Christopher Ferris96722b02017-07-19 14:20:46 -0700889 frame.map.load_bias = 0;
Christopher Ferrisda750a72015-11-30 13:36:08 -0800890 frame.map.name = "[anon:thread signal stack]";
891#if defined(__LP64__)
892 EXPECT_EQ("#01 pc 0000000000000020 [anon:thread signal stack:00000000000c0000]",
893#else
894 EXPECT_EQ("#01 pc 00000020 [anon:thread signal stack:000c0000]",
895#endif
896 backtrace->FormatFrameData(&frame));
Christopher Ferris46756822014-01-14 20:16:30 -0800897
898 // Check relative pc is set and map name is set.
899 frame.pc = 0x12345679;
Christopher Ferris96722b02017-07-19 14:20:46 -0700900 frame.rel_pc = 0x12345678;
Christopher Ferris12385e32015-02-06 13:22:01 -0800901 frame.map.name = "MapFake";
902 frame.map.start = 1;
903 frame.map.end = 1;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700904#if defined(__LP64__)
Christopher Ferris46756822014-01-14 20:16:30 -0800905 EXPECT_EQ("#01 pc 0000000012345678 MapFake",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700906#else
Christopher Ferris46756822014-01-14 20:16:30 -0800907 EXPECT_EQ("#01 pc 12345678 MapFake",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700908#endif
Christopher Ferris46756822014-01-14 20:16:30 -0800909 backtrace->FormatFrameData(&frame));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700910
Christopher Ferris46756822014-01-14 20:16:30 -0800911 // Check func_name is set, but no func offset.
912 frame.func_name = "ProcFake";
913#if defined(__LP64__)
914 EXPECT_EQ("#01 pc 0000000012345678 MapFake (ProcFake)",
915#else
916 EXPECT_EQ("#01 pc 12345678 MapFake (ProcFake)",
917#endif
918 backtrace->FormatFrameData(&frame));
919
920 // Check func_name is set, and func offset is non-zero.
Christopher Ferris20303f82014-01-10 16:33:16 -0800921 frame.func_offset = 645;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700922#if defined(__LP64__)
Christopher Ferris46756822014-01-14 20:16:30 -0800923 EXPECT_EQ("#01 pc 0000000012345678 MapFake (ProcFake+645)",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700924#else
Christopher Ferris46756822014-01-14 20:16:30 -0800925 EXPECT_EQ("#01 pc 12345678 MapFake (ProcFake+645)",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700926#endif
Christopher Ferris46756822014-01-14 20:16:30 -0800927 backtrace->FormatFrameData(&frame));
Christopher Ferris2106f4b2015-05-01 15:02:03 -0700928
Christopher Ferris96722b02017-07-19 14:20:46 -0700929 // Check func_name is set, func offset is non-zero, and load_bias is non-zero.
930 frame.rel_pc = 0x123456dc;
Christopher Ferris2106f4b2015-05-01 15:02:03 -0700931 frame.func_offset = 645;
Christopher Ferris96722b02017-07-19 14:20:46 -0700932 frame.map.load_bias = 100;
Christopher Ferris2106f4b2015-05-01 15:02:03 -0700933#if defined(__LP64__)
934 EXPECT_EQ("#01 pc 00000000123456dc MapFake (ProcFake+645)",
935#else
936 EXPECT_EQ("#01 pc 123456dc MapFake (ProcFake+645)",
937#endif
938 backtrace->FormatFrameData(&frame));
Christopher Ferrise0ab2322015-08-20 11:16:54 -0700939
940 // Check a non-zero map offset.
941 frame.map.offset = 0x1000;
942#if defined(__LP64__)
943 EXPECT_EQ("#01 pc 00000000123456dc MapFake (offset 0x1000) (ProcFake+645)",
944#else
945 EXPECT_EQ("#01 pc 123456dc MapFake (offset 0x1000) (ProcFake+645)",
946#endif
947 backtrace->FormatFrameData(&frame));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700948}
Christopher Ferrise2960912014-03-07 19:42:19 -0800949
950struct map_test_t {
951 uintptr_t start;
952 uintptr_t end;
953};
954
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700955static bool map_sort(map_test_t i, map_test_t j) { return i.start < j.start; }
Christopher Ferrise2960912014-03-07 19:42:19 -0800956
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700957static void VerifyMap(pid_t pid) {
Christopher Ferrise2960912014-03-07 19:42:19 -0800958 char buffer[4096];
959 snprintf(buffer, sizeof(buffer), "/proc/%d/maps", pid);
960
961 FILE* map_file = fopen(buffer, "r");
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700962 ASSERT_TRUE(map_file != nullptr);
Christopher Ferrise2960912014-03-07 19:42:19 -0800963 std::vector<map_test_t> test_maps;
964 while (fgets(buffer, sizeof(buffer), map_file)) {
965 map_test_t map;
966 ASSERT_EQ(2, sscanf(buffer, "%" SCNxPTR "-%" SCNxPTR " ", &map.start, &map.end));
967 test_maps.push_back(map);
968 }
969 fclose(map_file);
970 std::sort(test_maps.begin(), test_maps.end(), map_sort);
971
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700972 std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(pid));
Christopher Ferrise2960912014-03-07 19:42:19 -0800973
974 // Basic test that verifies that the map is in the expected order.
Christopher Ferris3a140042016-06-15 15:49:50 -0700975 ScopedBacktraceMapIteratorLock lock(map.get());
Christopher Ferrise2960912014-03-07 19:42:19 -0800976 std::vector<map_test_t>::const_iterator test_it = test_maps.begin();
977 for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) {
978 ASSERT_TRUE(test_it != test_maps.end());
979 ASSERT_EQ(test_it->start, it->start);
980 ASSERT_EQ(test_it->end, it->end);
981 ++test_it;
982 }
983 ASSERT_TRUE(test_it == test_maps.end());
984}
985
986TEST(libbacktrace, verify_map_remote) {
987 pid_t pid;
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700988 CreateRemoteProcess(&pid);
Christopher Ferrise2960912014-03-07 19:42:19 -0800989
990 // The maps should match exactly since the forked process has been paused.
991 VerifyMap(pid);
992
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700993 FinishRemoteProcess(pid);
Christopher Ferris2b4a63f2015-03-17 14:42:03 -0700994}
995
Christopher Ferris82f3bbd2017-03-14 15:22:26 -0700996static void InitMemory(uint8_t* memory, size_t bytes) {
Christopher Ferris944f4172015-05-06 16:36:34 -0700997 for (size_t i = 0; i < bytes; i++) {
998 memory[i] = i;
999 if (memory[i] == '\0') {
1000 // Don't use '\0' in our data so we can verify that an overread doesn't
1001 // occur by using a '\0' as the character after the read data.
1002 memory[i] = 23;
1003 }
1004 }
1005}
1006
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001007static void* ThreadReadTest(void* data) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001008 thread_t* thread_data = reinterpret_cast<thread_t*>(data);
1009
1010 thread_data->tid = gettid();
1011
1012 // Create two map pages.
1013 // Mark the second page as not-readable.
1014 size_t pagesize = static_cast<size_t>(sysconf(_SC_PAGE_SIZE));
1015 uint8_t* memory;
1016 if (posix_memalign(reinterpret_cast<void**>(&memory), pagesize, 2 * pagesize) != 0) {
1017 return reinterpret_cast<void*>(-1);
1018 }
1019
1020 if (mprotect(&memory[pagesize], pagesize, PROT_NONE) != 0) {
1021 return reinterpret_cast<void*>(-1);
1022 }
1023
1024 // Set up a simple pattern in memory.
Christopher Ferris944f4172015-05-06 16:36:34 -07001025 InitMemory(memory, pagesize);
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001026
1027 thread_data->data = memory;
1028
1029 // Tell the caller it's okay to start reading memory.
1030 android_atomic_acquire_store(1, &thread_data->state);
1031
Christopher Ferris2c43cff2015-03-26 19:18:36 -07001032 // Loop waiting for the caller to finish reading the memory.
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001033 while (thread_data->state) {
1034 }
1035
Christopher Ferris2c43cff2015-03-26 19:18:36 -07001036 // Re-enable read-write on the page so that we don't crash if we try
1037 // and access data on this page when freeing the memory.
1038 if (mprotect(&memory[pagesize], pagesize, PROT_READ | PROT_WRITE) != 0) {
1039 return reinterpret_cast<void*>(-1);
1040 }
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001041 free(memory);
1042
1043 android_atomic_acquire_store(1, &thread_data->state);
1044
1045 return nullptr;
1046}
1047
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001048static void RunReadTest(Backtrace* backtrace, uintptr_t read_addr) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001049 size_t pagesize = static_cast<size_t>(sysconf(_SC_PAGE_SIZE));
1050
1051 // Create a page of data to use to do quick compares.
1052 uint8_t* expected = new uint8_t[pagesize];
Christopher Ferris944f4172015-05-06 16:36:34 -07001053 InitMemory(expected, pagesize);
1054
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001055 uint8_t* data = new uint8_t[2*pagesize];
1056 // Verify that we can only read one page worth of data.
1057 size_t bytes_read = backtrace->Read(read_addr, data, 2 * pagesize);
1058 ASSERT_EQ(pagesize, bytes_read);
1059 ASSERT_TRUE(memcmp(data, expected, pagesize) == 0);
1060
1061 // Verify unaligned reads.
1062 for (size_t i = 1; i < sizeof(word_t); i++) {
1063 bytes_read = backtrace->Read(read_addr + i, data, 2 * sizeof(word_t));
1064 ASSERT_EQ(2 * sizeof(word_t), bytes_read);
1065 ASSERT_TRUE(memcmp(data, &expected[i], 2 * sizeof(word_t)) == 0)
1066 << "Offset at " << i << " failed";
1067 }
Christopher Ferris944f4172015-05-06 16:36:34 -07001068
1069 // Verify small unaligned reads.
1070 for (size_t i = 1; i < sizeof(word_t); i++) {
1071 for (size_t j = 1; j < sizeof(word_t); j++) {
1072 // Set one byte past what we expect to read, to guarantee we don't overread.
1073 data[j] = '\0';
1074 bytes_read = backtrace->Read(read_addr + i, data, j);
1075 ASSERT_EQ(j, bytes_read);
1076 ASSERT_TRUE(memcmp(data, &expected[i], j) == 0)
1077 << "Offset at " << i << " length " << j << " miscompared";
1078 ASSERT_EQ('\0', data[j])
1079 << "Offset at " << i << " length " << j << " wrote too much data";
1080 }
1081 }
Pirama Arumuga Nainar837eff22015-07-09 10:50:04 -07001082 delete[] data;
1083 delete[] expected;
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001084}
1085
1086TEST(libbacktrace, thread_read) {
1087 pthread_attr_t attr;
1088 pthread_attr_init(&attr);
1089 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1090 pthread_t thread;
1091 thread_t thread_data = { 0, 0, 0, nullptr };
1092 ASSERT_TRUE(pthread_create(&thread, &attr, ThreadReadTest, &thread_data) == 0);
1093
1094 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 10));
1095
1096 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid));
1097 ASSERT_TRUE(backtrace.get() != nullptr);
1098
1099 RunReadTest(backtrace.get(), reinterpret_cast<uintptr_t>(thread_data.data));
1100
1101 android_atomic_acquire_store(0, &thread_data.state);
1102
1103 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 10));
1104}
1105
1106volatile uintptr_t g_ready = 0;
1107volatile uintptr_t g_addr = 0;
1108
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001109static void ForkedReadTest() {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001110 // Create two map pages.
1111 size_t pagesize = static_cast<size_t>(sysconf(_SC_PAGE_SIZE));
1112 uint8_t* memory;
1113 if (posix_memalign(reinterpret_cast<void**>(&memory), pagesize, 2 * pagesize) != 0) {
1114 perror("Failed to allocate memory\n");
1115 exit(1);
1116 }
1117
1118 // Mark the second page as not-readable.
1119 if (mprotect(&memory[pagesize], pagesize, PROT_NONE) != 0) {
1120 perror("Failed to mprotect memory\n");
1121 exit(1);
1122 }
1123
1124 // Set up a simple pattern in memory.
Christopher Ferris944f4172015-05-06 16:36:34 -07001125 InitMemory(memory, pagesize);
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001126
1127 g_addr = reinterpret_cast<uintptr_t>(memory);
1128 g_ready = 1;
1129
1130 while (1) {
1131 usleep(US_PER_MSEC);
1132 }
1133}
1134
1135TEST(libbacktrace, process_read) {
Christopher Ferris67aba682015-05-08 15:44:46 -07001136 g_ready = 0;
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001137 pid_t pid;
1138 if ((pid = fork()) == 0) {
1139 ForkedReadTest();
1140 exit(0);
1141 }
1142 ASSERT_NE(-1, pid);
1143
1144 bool test_executed = false;
1145 uint64_t start = NanoTime();
1146 while (1) {
1147 if (ptrace(PTRACE_ATTACH, pid, 0, 0) == 0) {
1148 WaitForStop(pid);
1149
1150 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, pid));
Christopher Ferris97e00bb2015-04-02 14:22:31 -07001151 ASSERT_TRUE(backtrace.get() != nullptr);
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001152
1153 uintptr_t read_addr;
1154 size_t bytes_read = backtrace->Read(reinterpret_cast<uintptr_t>(&g_ready),
1155 reinterpret_cast<uint8_t*>(&read_addr),
1156 sizeof(uintptr_t));
1157 ASSERT_EQ(sizeof(uintptr_t), bytes_read);
1158 if (read_addr) {
1159 // The forked process is ready to be read.
1160 bytes_read = backtrace->Read(reinterpret_cast<uintptr_t>(&g_addr),
1161 reinterpret_cast<uint8_t*>(&read_addr),
1162 sizeof(uintptr_t));
1163 ASSERT_EQ(sizeof(uintptr_t), bytes_read);
1164
1165 RunReadTest(backtrace.get(), read_addr);
1166
1167 test_executed = true;
1168 break;
1169 }
1170 ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0);
1171 }
1172 if ((NanoTime() - start) > 5 * NS_PER_SEC) {
1173 break;
1174 }
1175 usleep(US_PER_MSEC);
1176 }
1177 kill(pid, SIGKILL);
1178 ASSERT_EQ(waitpid(pid, nullptr, 0), pid);
1179
1180 ASSERT_TRUE(test_executed);
Christopher Ferrise2960912014-03-07 19:42:19 -08001181}
1182
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001183static void VerifyFunctionsFound(const std::vector<std::string>& found_functions) {
Christopher Ferris67aba682015-05-08 15:44:46 -07001184 // We expect to find these functions in libbacktrace_test. If we don't
1185 // find them, that's a bug in the memory read handling code in libunwind.
1186 std::list<std::string> expected_functions;
1187 expected_functions.push_back("test_recursive_call");
1188 expected_functions.push_back("test_level_one");
1189 expected_functions.push_back("test_level_two");
1190 expected_functions.push_back("test_level_three");
1191 expected_functions.push_back("test_level_four");
1192 for (const auto& found_function : found_functions) {
1193 for (const auto& expected_function : expected_functions) {
1194 if (found_function == expected_function) {
1195 expected_functions.remove(found_function);
1196 break;
1197 }
1198 }
1199 }
1200 ASSERT_TRUE(expected_functions.empty()) << "Not all functions found in shared library.";
1201}
1202
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001203static const char* CopySharedLibrary() {
Christopher Ferris67aba682015-05-08 15:44:46 -07001204#if defined(__LP64__)
1205 const char* lib_name = "lib64";
1206#else
1207 const char* lib_name = "lib";
1208#endif
1209
1210#if defined(__BIONIC__)
1211 const char* tmp_so_name = "/data/local/tmp/libbacktrace_test.so";
1212 std::string cp_cmd = android::base::StringPrintf("cp /system/%s/libbacktrace_test.so %s",
1213 lib_name, tmp_so_name);
1214#else
1215 const char* tmp_so_name = "/tmp/libbacktrace_test.so";
1216 if (getenv("ANDROID_HOST_OUT") == NULL) {
1217 fprintf(stderr, "ANDROID_HOST_OUT not set, make sure you run lunch.");
1218 return nullptr;
1219 }
1220 std::string cp_cmd = android::base::StringPrintf("cp %s/%s/libbacktrace_test.so %s",
1221 getenv("ANDROID_HOST_OUT"), lib_name,
1222 tmp_so_name);
1223#endif
1224
1225 // Copy the shared so to a tempory directory.
1226 system(cp_cmd.c_str());
1227
1228 return tmp_so_name;
1229}
1230
1231TEST(libbacktrace, check_unreadable_elf_local) {
1232 const char* tmp_so_name = CopySharedLibrary();
1233 ASSERT_TRUE(tmp_so_name != nullptr);
1234
1235 struct stat buf;
1236 ASSERT_TRUE(stat(tmp_so_name, &buf) != -1);
1237 uintptr_t map_size = buf.st_size;
1238
1239 int fd = open(tmp_so_name, O_RDONLY);
1240 ASSERT_TRUE(fd != -1);
1241
Christopher Ferris61c48ac2016-01-15 16:08:58 -08001242 void* map = mmap(NULL, map_size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
Christopher Ferris67aba682015-05-08 15:44:46 -07001243 ASSERT_TRUE(map != MAP_FAILED);
1244 close(fd);
1245 ASSERT_TRUE(unlink(tmp_so_name) != -1);
1246
1247 std::vector<std::string> found_functions;
1248 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS,
1249 BACKTRACE_CURRENT_THREAD));
1250 ASSERT_TRUE(backtrace.get() != nullptr);
1251
1252 // Needed before GetFunctionName will work.
1253 backtrace->Unwind(0);
1254
1255 // Loop through the entire map, and get every function we can find.
1256 map_size += reinterpret_cast<uintptr_t>(map);
1257 std::string last_func;
1258 for (uintptr_t read_addr = reinterpret_cast<uintptr_t>(map);
1259 read_addr < map_size; read_addr += 4) {
1260 uintptr_t offset;
1261 std::string func_name = backtrace->GetFunctionName(read_addr, &offset);
1262 if (!func_name.empty() && last_func != func_name) {
1263 found_functions.push_back(func_name);
1264 }
1265 last_func = func_name;
1266 }
1267
1268 ASSERT_TRUE(munmap(map, map_size - reinterpret_cast<uintptr_t>(map)) == 0);
1269
1270 VerifyFunctionsFound(found_functions);
1271}
1272
1273TEST(libbacktrace, check_unreadable_elf_remote) {
1274 const char* tmp_so_name = CopySharedLibrary();
1275 ASSERT_TRUE(tmp_so_name != nullptr);
1276
1277 g_ready = 0;
1278
1279 struct stat buf;
1280 ASSERT_TRUE(stat(tmp_so_name, &buf) != -1);
1281 uintptr_t map_size = buf.st_size;
1282
1283 pid_t pid;
1284 if ((pid = fork()) == 0) {
1285 int fd = open(tmp_so_name, O_RDONLY);
1286 if (fd == -1) {
1287 fprintf(stderr, "Failed to open file %s: %s\n", tmp_so_name, strerror(errno));
1288 unlink(tmp_so_name);
1289 exit(0);
1290 }
1291
Christopher Ferris61c48ac2016-01-15 16:08:58 -08001292 void* map = mmap(NULL, map_size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
Christopher Ferris67aba682015-05-08 15:44:46 -07001293 if (map == MAP_FAILED) {
1294 fprintf(stderr, "Failed to map in memory: %s\n", strerror(errno));
1295 unlink(tmp_so_name);
1296 exit(0);
1297 }
1298 close(fd);
1299 if (unlink(tmp_so_name) == -1) {
1300 fprintf(stderr, "Failed to unlink: %s\n", strerror(errno));
1301 exit(0);
1302 }
1303
1304 g_addr = reinterpret_cast<uintptr_t>(map);
1305 g_ready = 1;
1306 while (true) {
1307 usleep(US_PER_MSEC);
1308 }
1309 exit(0);
1310 }
1311 ASSERT_TRUE(pid > 0);
1312
1313 std::vector<std::string> found_functions;
1314 uint64_t start = NanoTime();
1315 while (true) {
1316 ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0);
1317
1318 // Wait for the process to get to a stopping point.
1319 WaitForStop(pid);
1320
1321 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, BACKTRACE_CURRENT_THREAD));
1322 ASSERT_TRUE(backtrace.get() != nullptr);
1323
1324 uintptr_t read_addr;
1325 ASSERT_EQ(sizeof(uintptr_t), backtrace->Read(reinterpret_cast<uintptr_t>(&g_ready), reinterpret_cast<uint8_t*>(&read_addr), sizeof(uintptr_t)));
1326 if (read_addr) {
1327 ASSERT_EQ(sizeof(uintptr_t), backtrace->Read(reinterpret_cast<uintptr_t>(&g_addr), reinterpret_cast<uint8_t*>(&read_addr), sizeof(uintptr_t)));
1328
1329 // Needed before GetFunctionName will work.
1330 backtrace->Unwind(0);
1331
1332 // Loop through the entire map, and get every function we can find.
1333 map_size += read_addr;
1334 std::string last_func;
1335 for (; read_addr < map_size; read_addr += 4) {
1336 uintptr_t offset;
1337 std::string func_name = backtrace->GetFunctionName(read_addr, &offset);
1338 if (!func_name.empty() && last_func != func_name) {
1339 found_functions.push_back(func_name);
1340 }
1341 last_func = func_name;
1342 }
1343 break;
1344 }
1345 ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0);
1346
1347 if ((NanoTime() - start) > 5 * NS_PER_SEC) {
1348 break;
1349 }
1350 usleep(US_PER_MSEC);
1351 }
1352
1353 kill(pid, SIGKILL);
1354 ASSERT_EQ(waitpid(pid, nullptr, 0), pid);
1355
1356 VerifyFunctionsFound(found_functions);
1357}
1358
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001359static bool FindFuncFrameInBacktrace(Backtrace* backtrace, uintptr_t test_func, size_t* frame_num) {
Christopher Ferris67aba682015-05-08 15:44:46 -07001360 backtrace_map_t map;
1361 backtrace->FillInMap(test_func, &map);
1362 if (!BacktraceMap::IsValid(map)) {
1363 return false;
1364 }
1365
1366 // Loop through the frames, and find the one that is in the map.
1367 *frame_num = 0;
1368 for (Backtrace::const_iterator it = backtrace->begin(); it != backtrace->end(); ++it) {
1369 if (BacktraceMap::IsValid(it->map) && map.start == it->map.start &&
1370 it->pc >= test_func) {
1371 *frame_num = it->num;
1372 return true;
1373 }
1374 }
1375 return false;
1376}
1377
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001378static void VerifyUnreadableElfFrame(Backtrace* backtrace, uintptr_t test_func, size_t frame_num) {
Christopher Ferris67aba682015-05-08 15:44:46 -07001379 ASSERT_LT(backtrace->NumFrames(), static_cast<size_t>(MAX_BACKTRACE_FRAMES))
1380 << DumpFrames(backtrace);
1381
1382 ASSERT_TRUE(frame_num != 0) << DumpFrames(backtrace);
1383 // Make sure that there is at least one more frame above the test func call.
1384 ASSERT_LT(frame_num, backtrace->NumFrames()) << DumpFrames(backtrace);
1385
1386 uintptr_t diff = backtrace->GetFrame(frame_num)->pc - test_func;
1387 ASSERT_LT(diff, 200U) << DumpFrames(backtrace);
1388}
1389
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001390static void VerifyUnreadableElfBacktrace(uintptr_t test_func) {
Christopher Ferris67aba682015-05-08 15:44:46 -07001391 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS,
1392 BACKTRACE_CURRENT_THREAD));
1393 ASSERT_TRUE(backtrace.get() != nullptr);
1394 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -08001395 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferris67aba682015-05-08 15:44:46 -07001396
1397 size_t frame_num;
1398 ASSERT_TRUE(FindFuncFrameInBacktrace(backtrace.get(), test_func, &frame_num));
1399
1400 VerifyUnreadableElfFrame(backtrace.get(), test_func, frame_num);
1401}
1402
1403typedef int (*test_func_t)(int, int, int, int, void (*)(uintptr_t), uintptr_t);
1404
1405TEST(libbacktrace, unwind_through_unreadable_elf_local) {
1406 const char* tmp_so_name = CopySharedLibrary();
1407 ASSERT_TRUE(tmp_so_name != nullptr);
1408 void* lib_handle = dlopen(tmp_so_name, RTLD_NOW);
1409 ASSERT_TRUE(lib_handle != nullptr);
1410 ASSERT_TRUE(unlink(tmp_so_name) != -1);
1411
1412 test_func_t test_func;
1413 test_func = reinterpret_cast<test_func_t>(dlsym(lib_handle, "test_level_one"));
1414 ASSERT_TRUE(test_func != nullptr);
1415
1416 ASSERT_NE(test_func(1, 2, 3, 4, VerifyUnreadableElfBacktrace,
1417 reinterpret_cast<uintptr_t>(test_func)), 0);
1418
1419 ASSERT_TRUE(dlclose(lib_handle) == 0);
1420}
1421
1422TEST(libbacktrace, unwind_through_unreadable_elf_remote) {
1423 const char* tmp_so_name = CopySharedLibrary();
1424 ASSERT_TRUE(tmp_so_name != nullptr);
1425 void* lib_handle = dlopen(tmp_so_name, RTLD_NOW);
1426 ASSERT_TRUE(lib_handle != nullptr);
1427 ASSERT_TRUE(unlink(tmp_so_name) != -1);
1428
1429 test_func_t test_func;
1430 test_func = reinterpret_cast<test_func_t>(dlsym(lib_handle, "test_level_one"));
1431 ASSERT_TRUE(test_func != nullptr);
1432
1433 pid_t pid;
1434 if ((pid = fork()) == 0) {
1435 test_func(1, 2, 3, 4, 0, 0);
1436 exit(0);
1437 }
1438 ASSERT_TRUE(pid > 0);
1439 ASSERT_TRUE(dlclose(lib_handle) == 0);
1440
1441 uint64_t start = NanoTime();
1442 bool done = false;
1443 while (!done) {
1444 ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0);
1445
1446 // Wait for the process to get to a stopping point.
1447 WaitForStop(pid);
1448
1449 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, BACKTRACE_CURRENT_THREAD));
1450 ASSERT_TRUE(backtrace.get() != nullptr);
1451 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -08001452 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferris67aba682015-05-08 15:44:46 -07001453
1454 size_t frame_num;
1455 if (FindFuncFrameInBacktrace(backtrace.get(),
1456 reinterpret_cast<uintptr_t>(test_func), &frame_num)) {
1457
1458 VerifyUnreadableElfFrame(backtrace.get(), reinterpret_cast<uintptr_t>(test_func), frame_num);
1459 done = true;
1460 }
1461
1462 ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0);
1463
1464 if ((NanoTime() - start) > 5 * NS_PER_SEC) {
1465 break;
1466 }
1467 usleep(US_PER_MSEC);
1468 }
1469
1470 kill(pid, SIGKILL);
1471 ASSERT_EQ(waitpid(pid, nullptr, 0), pid);
1472
1473 ASSERT_TRUE(done) << "Test function never found in unwind.";
1474}
1475
Christopher Ferris206a3b92016-03-09 14:35:54 -08001476TEST(libbacktrace, unwind_thread_doesnt_exist) {
1477 std::unique_ptr<Backtrace> backtrace(
1478 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, 99999999));
1479 ASSERT_TRUE(backtrace.get() != nullptr);
1480 ASSERT_FALSE(backtrace->Unwind(0));
1481 ASSERT_EQ(BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST, backtrace->GetError());
1482}
1483
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001484TEST(libbacktrace, local_get_function_name_before_unwind) {
1485 std::unique_ptr<Backtrace> backtrace(
1486 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
1487 ASSERT_TRUE(backtrace.get() != nullptr);
1488
1489 // Verify that trying to get a function name before doing an unwind works.
1490 uintptr_t cur_func_offset = reinterpret_cast<uintptr_t>(&test_level_one) + 1;
1491 size_t offset;
1492 ASSERT_NE(std::string(""), backtrace->GetFunctionName(cur_func_offset, &offset));
1493}
1494
1495TEST(libbacktrace, remote_get_function_name_before_unwind) {
1496 pid_t pid;
1497 CreateRemoteProcess(&pid);
1498
1499 // Now create an unwind object.
1500 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, pid));
1501
1502 // Verify that trying to get a function name before doing an unwind works.
1503 uintptr_t cur_func_offset = reinterpret_cast<uintptr_t>(&test_level_one) + 1;
1504 size_t offset;
1505 ASSERT_NE(std::string(""), backtrace->GetFunctionName(cur_func_offset, &offset));
1506
1507 FinishRemoteProcess(pid);
1508}
1509
Christopher Ferrisf5e568e2017-03-22 13:18:31 -07001510static void SetUcontextSp(uintptr_t sp, ucontext_t* ucontext) {
1511#if defined(__arm__)
1512 ucontext->uc_mcontext.arm_sp = sp;
1513#elif defined(__aarch64__)
1514 ucontext->uc_mcontext.sp = sp;
1515#elif defined(__i386__)
1516 ucontext->uc_mcontext.gregs[REG_ESP] = sp;
1517#elif defined(__x86_64__)
1518 ucontext->uc_mcontext.gregs[REG_RSP] = sp;
1519#else
1520 UNUSED(sp);
1521 UNUSED(ucontext);
1522 ASSERT_TRUE(false) << "Unsupported architecture";
1523#endif
1524}
1525
1526static void SetUcontextPc(uintptr_t pc, ucontext_t* ucontext) {
1527#if defined(__arm__)
1528 ucontext->uc_mcontext.arm_pc = pc;
1529#elif defined(__aarch64__)
1530 ucontext->uc_mcontext.pc = pc;
1531#elif defined(__i386__)
1532 ucontext->uc_mcontext.gregs[REG_EIP] = pc;
1533#elif defined(__x86_64__)
1534 ucontext->uc_mcontext.gregs[REG_RIP] = pc;
1535#else
1536 UNUSED(pc);
1537 UNUSED(ucontext);
1538 ASSERT_TRUE(false) << "Unsupported architecture";
1539#endif
1540}
1541
1542static void SetUcontextLr(uintptr_t lr, ucontext_t* ucontext) {
1543#if defined(__arm__)
1544 ucontext->uc_mcontext.arm_lr = lr;
1545#elif defined(__aarch64__)
1546 ucontext->uc_mcontext.regs[30] = lr;
1547#elif defined(__i386__)
1548 // The lr is on the stack.
1549 ASSERT_TRUE(lr != 0);
1550 ASSERT_TRUE(ucontext != nullptr);
1551#elif defined(__x86_64__)
1552 // The lr is on the stack.
1553 ASSERT_TRUE(lr != 0);
1554 ASSERT_TRUE(ucontext != nullptr);
1555#else
1556 UNUSED(lr);
1557 UNUSED(ucontext);
1558 ASSERT_TRUE(false) << "Unsupported architecture";
1559#endif
1560}
1561
1562static constexpr size_t DEVICE_MAP_SIZE = 1024;
1563
1564static void SetupDeviceMap(void** device_map) {
1565 // Make sure that anything in a device map will result in fails
1566 // to read.
1567 android::base::unique_fd device_fd(open("/dev/zero", O_RDONLY | O_CLOEXEC));
1568
1569 *device_map = mmap(nullptr, 1024, PROT_READ, MAP_PRIVATE, device_fd, 0);
1570 ASSERT_TRUE(*device_map != MAP_FAILED);
1571
1572 // Make sure the map is readable.
1573 ASSERT_EQ(0, reinterpret_cast<int*>(*device_map)[0]);
1574}
1575
1576static void UnwindFromDevice(Backtrace* backtrace, void* device_map) {
1577 uintptr_t device_map_uint = reinterpret_cast<uintptr_t>(device_map);
1578
1579 backtrace_map_t map;
1580 backtrace->FillInMap(device_map_uint, &map);
1581 // Verify the flag is set.
1582 ASSERT_EQ(PROT_DEVICE_MAP, map.flags & PROT_DEVICE_MAP);
1583
1584 // Quick sanity checks.
1585 size_t offset;
1586 ASSERT_EQ(std::string(""), backtrace->GetFunctionName(device_map_uint, &offset));
1587 ASSERT_EQ(std::string(""), backtrace->GetFunctionName(device_map_uint, &offset, &map));
1588 ASSERT_EQ(std::string(""), backtrace->GetFunctionName(0, &offset));
1589
1590 uintptr_t cur_func_offset = reinterpret_cast<uintptr_t>(&test_level_one) + 1;
1591 // Now verify the device map flag actually causes the function name to be empty.
1592 backtrace->FillInMap(cur_func_offset, &map);
1593 ASSERT_TRUE((map.flags & PROT_DEVICE_MAP) == 0);
1594 ASSERT_NE(std::string(""), backtrace->GetFunctionName(cur_func_offset, &offset, &map));
1595 map.flags |= PROT_DEVICE_MAP;
1596 ASSERT_EQ(std::string(""), backtrace->GetFunctionName(cur_func_offset, &offset, &map));
1597
1598 ucontext_t ucontext;
1599
1600 // Create a context that has the pc in the device map, but the sp
1601 // in a non-device map.
1602 memset(&ucontext, 0, sizeof(ucontext));
1603 SetUcontextSp(reinterpret_cast<uintptr_t>(&ucontext), &ucontext);
1604 SetUcontextPc(device_map_uint, &ucontext);
1605 SetUcontextLr(cur_func_offset, &ucontext);
1606
1607 ASSERT_TRUE(backtrace->Unwind(0, &ucontext));
1608
1609 // The buffer should only be a single element.
1610 ASSERT_EQ(1U, backtrace->NumFrames());
1611 const backtrace_frame_data_t* frame = backtrace->GetFrame(0);
1612 ASSERT_EQ(device_map_uint, frame->pc);
1613 ASSERT_EQ(reinterpret_cast<uintptr_t>(&ucontext), frame->sp);
1614
1615 // Check what happens when skipping the first frame.
1616 ASSERT_TRUE(backtrace->Unwind(1, &ucontext));
1617 ASSERT_EQ(0U, backtrace->NumFrames());
1618
1619 // Create a context that has the sp in the device map, but the pc
1620 // in a non-device map.
1621 memset(&ucontext, 0, sizeof(ucontext));
1622 SetUcontextSp(device_map_uint, &ucontext);
1623 SetUcontextPc(cur_func_offset, &ucontext);
1624 SetUcontextLr(cur_func_offset, &ucontext);
1625
1626 ASSERT_TRUE(backtrace->Unwind(0, &ucontext));
1627
1628 // The buffer should only be a single element.
1629 ASSERT_EQ(1U, backtrace->NumFrames());
1630 frame = backtrace->GetFrame(0);
1631 ASSERT_EQ(cur_func_offset, frame->pc);
1632 ASSERT_EQ(device_map_uint, frame->sp);
1633
1634 // Check what happens when skipping the first frame.
1635 ASSERT_TRUE(backtrace->Unwind(1, &ucontext));
1636 ASSERT_EQ(0U, backtrace->NumFrames());
1637}
1638
1639TEST(libbacktrace, unwind_disallow_device_map_local) {
1640 void* device_map;
1641 SetupDeviceMap(&device_map);
1642
1643 // Now create an unwind object.
1644 std::unique_ptr<Backtrace> backtrace(
1645 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
1646 ASSERT_TRUE(backtrace);
1647
1648 UnwindFromDevice(backtrace.get(), device_map);
1649
1650 munmap(device_map, DEVICE_MAP_SIZE);
1651}
1652
Christopher Ferris458cc662017-08-28 16:31:18 -07001653TEST(libbacktrace, unwind_disallow_device_map_remote_new) {
Christopher Ferrisf5e568e2017-03-22 13:18:31 -07001654 void* device_map;
1655 SetupDeviceMap(&device_map);
1656
1657 // Fork a process to do a remote backtrace.
1658 pid_t pid;
1659 CreateRemoteProcess(&pid);
1660
1661 // Now create an unwind object.
Christopher Ferris458cc662017-08-28 16:31:18 -07001662 std::unique_ptr<BacktraceMap> map(BacktraceMap::CreateNew(pid));
1663 ASSERT_TRUE(map.get() != nullptr);
1664 std::unique_ptr<Backtrace> backtrace(Backtrace::CreateNew(pid, pid, map.get()));
Christopher Ferrisf5e568e2017-03-22 13:18:31 -07001665
Christopher Ferris458cc662017-08-28 16:31:18 -07001666 UnwindFromDevice(backtrace.get(), device_map);
Christopher Ferrisf5e568e2017-03-22 13:18:31 -07001667
1668 FinishRemoteProcess(pid);
1669
1670 munmap(device_map, DEVICE_MAP_SIZE);
1671}
1672
Christopher Ferris5ea2c1f2017-03-23 14:55:01 -07001673class ScopedSignalHandler {
1674 public:
1675 ScopedSignalHandler(int signal_number, void (*handler)(int)) : signal_number_(signal_number) {
1676 memset(&action_, 0, sizeof(action_));
1677 action_.sa_handler = handler;
1678 sigaction(signal_number_, &action_, &old_action_);
1679 }
1680
1681 ScopedSignalHandler(int signal_number, void (*action)(int, siginfo_t*, void*))
1682 : signal_number_(signal_number) {
1683 memset(&action_, 0, sizeof(action_));
1684 action_.sa_flags = SA_SIGINFO;
1685 action_.sa_sigaction = action;
1686 sigaction(signal_number_, &action_, &old_action_);
1687 }
1688
1689 ~ScopedSignalHandler() { sigaction(signal_number_, &old_action_, nullptr); }
1690
1691 private:
1692 struct sigaction action_;
1693 struct sigaction old_action_;
1694 const int signal_number_;
1695};
1696
1697static void SetValueAndLoop(void* data) {
1698 volatile int* value = reinterpret_cast<volatile int*>(data);
1699
1700 *value = 1;
1701 for (volatile int i = 0;; i++)
1702 ;
1703}
1704
Christopher Ferris458cc662017-08-28 16:31:18 -07001705static void UnwindThroughSignal(bool use_action,
1706 Backtrace* (*back_func)(pid_t, pid_t, BacktraceMap*),
1707 BacktraceMap* (*map_func)(pid_t, bool)) {
Christopher Ferris5ea2c1f2017-03-23 14:55:01 -07001708 volatile int value = 0;
1709 pid_t pid;
1710 if ((pid = fork()) == 0) {
1711 if (use_action) {
1712 ScopedSignalHandler ssh(SIGUSR1, test_signal_action);
1713
1714 test_level_one(1, 2, 3, 4, SetValueAndLoop, const_cast<int*>(&value));
1715 } else {
1716 ScopedSignalHandler ssh(SIGUSR1, test_signal_handler);
1717
1718 test_level_one(1, 2, 3, 4, SetValueAndLoop, const_cast<int*>(&value));
1719 }
1720 }
1721 ASSERT_NE(-1, pid);
1722
1723 int read_value = 0;
1724 uint64_t start = NanoTime();
1725 while (read_value == 0) {
1726 usleep(1000);
1727
1728 // Loop until the remote function gets into the final function.
1729 ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0);
1730
1731 WaitForStop(pid);
1732
Christopher Ferris458cc662017-08-28 16:31:18 -07001733 std::unique_ptr<BacktraceMap> map(map_func(pid, false));
1734 std::unique_ptr<Backtrace> backtrace(back_func(pid, pid, map.get()));
Christopher Ferris5ea2c1f2017-03-23 14:55:01 -07001735
1736 size_t bytes_read = backtrace->Read(reinterpret_cast<uintptr_t>(const_cast<int*>(&value)),
1737 reinterpret_cast<uint8_t*>(&read_value), sizeof(read_value));
1738 ASSERT_EQ(sizeof(read_value), bytes_read);
1739
1740 ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0);
1741
1742 ASSERT_TRUE(NanoTime() - start < 5 * NS_PER_SEC)
1743 << "Remote process did not execute far enough in 5 seconds.";
1744 }
1745
1746 // Now need to send a signal to the remote process.
1747 kill(pid, SIGUSR1);
1748
1749 // Wait for the process to get to the signal handler loop.
1750 Backtrace::const_iterator frame_iter;
1751 start = NanoTime();
Christopher Ferris458cc662017-08-28 16:31:18 -07001752 std::unique_ptr<BacktraceMap> map;
Christopher Ferris5ea2c1f2017-03-23 14:55:01 -07001753 std::unique_ptr<Backtrace> backtrace;
1754 while (true) {
1755 usleep(1000);
1756
1757 ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0);
1758
1759 WaitForStop(pid);
1760
Christopher Ferris458cc662017-08-28 16:31:18 -07001761 map.reset(map_func(pid, false));
1762 ASSERT_TRUE(map.get() != nullptr);
1763 backtrace.reset(back_func(pid, pid, map.get()));
Christopher Ferris5ea2c1f2017-03-23 14:55:01 -07001764 ASSERT_TRUE(backtrace->Unwind(0));
1765 bool found = false;
1766 for (frame_iter = backtrace->begin(); frame_iter != backtrace->end(); ++frame_iter) {
1767 if (frame_iter->func_name == "test_loop_forever") {
1768 ++frame_iter;
1769 found = true;
1770 break;
1771 }
1772 }
1773 if (found) {
1774 break;
1775 }
1776
1777 ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0);
1778
1779 ASSERT_TRUE(NanoTime() - start < 5 * NS_PER_SEC)
1780 << "Remote process did not get in signal handler in 5 seconds." << std::endl
1781 << DumpFrames(backtrace.get());
1782 }
1783
1784 std::vector<std::string> names;
1785 // Loop through the frames, and save the function names.
1786 size_t frame = 0;
1787 for (; frame_iter != backtrace->end(); ++frame_iter) {
1788 if (frame_iter->func_name == "test_level_four") {
1789 frame = names.size() + 1;
1790 }
1791 names.push_back(frame_iter->func_name);
1792 }
1793 ASSERT_NE(0U, frame) << "Unable to find test_level_four in backtrace" << std::endl
1794 << DumpFrames(backtrace.get());
1795
1796 // The expected order of the frames:
1797 // test_loop_forever
1798 // test_signal_handler|test_signal_action
1799 // <OPTIONAL_FRAME> May or may not exist.
1800 // SetValueAndLoop (but the function name might be empty)
1801 // test_level_four
1802 // test_level_three
1803 // test_level_two
1804 // test_level_one
1805 ASSERT_LE(frame + 2, names.size()) << DumpFrames(backtrace.get());
1806 ASSERT_LE(2U, frame) << DumpFrames(backtrace.get());
1807 if (use_action) {
1808 ASSERT_EQ("test_signal_action", names[0]) << DumpFrames(backtrace.get());
1809 } else {
1810 ASSERT_EQ("test_signal_handler", names[0]) << DumpFrames(backtrace.get());
1811 }
1812 ASSERT_EQ("test_level_three", names[frame]) << DumpFrames(backtrace.get());
1813 ASSERT_EQ("test_level_two", names[frame + 1]) << DumpFrames(backtrace.get());
1814 ASSERT_EQ("test_level_one", names[frame + 2]) << DumpFrames(backtrace.get());
1815
1816 FinishRemoteProcess(pid);
1817}
1818
Christopher Ferris96722b02017-07-19 14:20:46 -07001819TEST(libbacktrace, unwind_remote_through_signal_using_handler) {
Christopher Ferris458cc662017-08-28 16:31:18 -07001820 UnwindThroughSignal(false, Backtrace::Create, BacktraceMap::Create);
1821}
1822
1823TEST(libbacktrace, unwind_remote_through_signal_using_handler_new) {
1824 UnwindThroughSignal(false, Backtrace::CreateNew, BacktraceMap::CreateNew);
Christopher Ferris96722b02017-07-19 14:20:46 -07001825}
Christopher Ferris5ea2c1f2017-03-23 14:55:01 -07001826
Christopher Ferris96722b02017-07-19 14:20:46 -07001827TEST(libbacktrace, unwind_remote_through_signal_using_action) {
Christopher Ferris458cc662017-08-28 16:31:18 -07001828 UnwindThroughSignal(true, Backtrace::Create, BacktraceMap::Create);
1829}
1830
1831TEST(libbacktrace, unwind_remote_through_signal_using_action_new) {
1832 UnwindThroughSignal(true, Backtrace::CreateNew, BacktraceMap::CreateNew);
Christopher Ferris96722b02017-07-19 14:20:46 -07001833}
Christopher Ferris5ea2c1f2017-03-23 14:55:01 -07001834
Christopher Ferrise2960912014-03-07 19:42:19 -08001835#if defined(ENABLE_PSS_TESTS)
1836#include "GetPss.h"
1837
Chih-Hung Hsieh67867db2016-05-18 15:53:15 -07001838#define MAX_LEAK_BYTES (32*1024UL)
Christopher Ferrise2960912014-03-07 19:42:19 -08001839
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001840static void CheckForLeak(pid_t pid, pid_t tid) {
Christopher Ferrise2960912014-03-07 19:42:19 -08001841 // Do a few runs to get the PSS stable.
1842 for (size_t i = 0; i < 100; i++) {
1843 Backtrace* backtrace = Backtrace::Create(pid, tid);
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001844 ASSERT_TRUE(backtrace != nullptr);
Christopher Ferrise2960912014-03-07 19:42:19 -08001845 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -08001846 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferrise2960912014-03-07 19:42:19 -08001847 delete backtrace;
1848 }
1849 size_t stable_pss = GetPssBytes();
Christopher Ferris2c43cff2015-03-26 19:18:36 -07001850 ASSERT_TRUE(stable_pss != 0);
Christopher Ferrise2960912014-03-07 19:42:19 -08001851
1852 // Loop enough that even a small leak should be detectable.
1853 for (size_t i = 0; i < 4096; i++) {
1854 Backtrace* backtrace = Backtrace::Create(pid, tid);
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001855 ASSERT_TRUE(backtrace != nullptr);
Christopher Ferrise2960912014-03-07 19:42:19 -08001856 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris206a3b92016-03-09 14:35:54 -08001857 ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError());
Christopher Ferrise2960912014-03-07 19:42:19 -08001858 delete backtrace;
1859 }
1860 size_t new_pss = GetPssBytes();
Christopher Ferris2c43cff2015-03-26 19:18:36 -07001861 ASSERT_TRUE(new_pss != 0);
Christopher Ferris5ccdfa62016-03-07 19:18:31 -08001862 if (new_pss > stable_pss) {
1863 ASSERT_LE(new_pss - stable_pss, MAX_LEAK_BYTES);
1864 }
Christopher Ferrise2960912014-03-07 19:42:19 -08001865}
1866
1867TEST(libbacktrace, check_for_leak_local) {
1868 CheckForLeak(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD);
1869}
1870
1871TEST(libbacktrace, check_for_leak_local_thread) {
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001872 thread_t thread_data = { 0, 0, 0, nullptr };
Christopher Ferrise2960912014-03-07 19:42:19 -08001873 pthread_t thread;
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001874 ASSERT_TRUE(pthread_create(&thread, nullptr, ThreadLevelRun, &thread_data) == 0);
Christopher Ferrise2960912014-03-07 19:42:19 -08001875
1876 // Wait up to 2 seconds for the tid to be set.
1877 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));
1878
1879 CheckForLeak(BACKTRACE_CURRENT_PROCESS, thread_data.tid);
1880
1881 // Tell the thread to exit its infinite loop.
1882 android_atomic_acquire_store(0, &thread_data.state);
1883
Christopher Ferris2b4a63f2015-03-17 14:42:03 -07001884 ASSERT_TRUE(pthread_join(thread, nullptr) == 0);
Christopher Ferrise2960912014-03-07 19:42:19 -08001885}
1886
1887TEST(libbacktrace, check_for_leak_remote) {
1888 pid_t pid;
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001889 CreateRemoteProcess(&pid);
Christopher Ferrise2960912014-03-07 19:42:19 -08001890
1891 CheckForLeak(pid, BACKTRACE_CURRENT_THREAD);
1892
Christopher Ferris82f3bbd2017-03-14 15:22:26 -07001893 FinishRemoteProcess(pid);
Christopher Ferrise2960912014-03-07 19:42:19 -08001894}
1895#endif