blob: 23eaf92cb3676afee4823303f4aea802e6497a70 [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
17#include <dirent.h>
18#include <errno.h>
19#include <pthread.h>
20#include <signal.h>
21#include <stdbool.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <sys/ptrace.h>
26#include <sys/types.h>
27#include <sys/wait.h>
28#include <time.h>
29#include <unistd.h>
30
Christopher Ferris20303f82014-01-10 16:33:16 -080031#include <backtrace/Backtrace.h>
Christopher Ferris46756822014-01-14 20:16:30 -080032#include <backtrace/BacktraceMap.h>
Christopher Ferris20303f82014-01-10 16:33:16 -080033#include <UniquePtr.h>
Christopher Ferris17e91d42013-10-21 13:30:52 -070034
35#include <cutils/atomic.h>
36#include <gtest/gtest.h>
37
38#include <vector>
39
40#include "thread_utils.h"
41
42// Number of microseconds per milliseconds.
43#define US_PER_MSEC 1000
44
45// Number of nanoseconds in a second.
46#define NS_PER_SEC 1000000000ULL
47
48// Number of simultaneous dumping operations to perform.
49#define NUM_THREADS 20
50
51// Number of simultaneous threads running in our forked process.
52#define NUM_PTRACE_THREADS 5
53
Christopher Ferris46756822014-01-14 20:16:30 -080054struct thread_t {
Christopher Ferris17e91d42013-10-21 13:30:52 -070055 pid_t tid;
56 int32_t state;
57 pthread_t threadId;
Christopher Ferris46756822014-01-14 20:16:30 -080058};
Christopher Ferris17e91d42013-10-21 13:30:52 -070059
Christopher Ferris46756822014-01-14 20:16:30 -080060struct dump_thread_t {
Christopher Ferris17e91d42013-10-21 13:30:52 -070061 thread_t thread;
Christopher Ferris20303f82014-01-10 16:33:16 -080062 Backtrace* backtrace;
Christopher Ferris17e91d42013-10-21 13:30:52 -070063 int32_t* now;
64 int32_t done;
Christopher Ferris46756822014-01-14 20:16:30 -080065};
Christopher Ferris17e91d42013-10-21 13:30:52 -070066
67extern "C" {
68// Prototypes for functions in the test library.
69int test_level_one(int, int, int, int, void (*)(void*), void*);
70
71int test_recursive_call(int, void (*)(void*), void*);
72}
73
74uint64_t NanoTime() {
75 struct timespec t = { 0, 0 };
76 clock_gettime(CLOCK_MONOTONIC, &t);
77 return static_cast<uint64_t>(t.tv_sec * NS_PER_SEC + t.tv_nsec);
78}
79
Christopher Ferris20303f82014-01-10 16:33:16 -080080void DumpFrames(Backtrace* backtrace) {
81 if (backtrace->NumFrames() == 0) {
Christopher Ferris17e91d42013-10-21 13:30:52 -070082 printf(" No frames to dump\n");
Christopher Ferris20303f82014-01-10 16:33:16 -080083 return;
84 }
85
86 for (size_t i = 0; i < backtrace->NumFrames(); i++) {
87 printf(" %s\n", backtrace->FormatFrameData(i).c_str());
Christopher Ferris17e91d42013-10-21 13:30:52 -070088 }
89}
90
91void WaitForStop(pid_t pid) {
92 uint64_t start = NanoTime();
93
94 siginfo_t si;
95 while (ptrace(PTRACE_GETSIGINFO, pid, 0, &si) < 0 && (errno == EINTR || errno == ESRCH)) {
96 if ((NanoTime() - start) > NS_PER_SEC) {
97 printf("The process did not get to a stopping point in 1 second.\n");
98 break;
99 }
100 usleep(US_PER_MSEC);
101 }
102}
103
Christopher Ferris20303f82014-01-10 16:33:16 -0800104bool ReadyLevelBacktrace(Backtrace* backtrace) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700105 // See if test_level_four is in the backtrace.
106 bool found = false;
Christopher Ferris46756822014-01-14 20:16:30 -0800107 for (Backtrace::const_iterator it = backtrace->begin(); it != backtrace->end(); ++it) {
108 if (it->func_name == "test_level_four") {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700109 found = true;
110 break;
111 }
112 }
113
114 return found;
115}
116
Christopher Ferris20303f82014-01-10 16:33:16 -0800117void VerifyLevelDump(Backtrace* backtrace) {
118 ASSERT_GT(backtrace->NumFrames(), static_cast<size_t>(0));
119 ASSERT_LT(backtrace->NumFrames(), static_cast<size_t>(MAX_BACKTRACE_FRAMES));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700120
121 // Look through the frames starting at the highest to find the
122 // frame we want.
123 size_t frame_num = 0;
Christopher Ferris20303f82014-01-10 16:33:16 -0800124 for (size_t i = backtrace->NumFrames()-1; i > 2; i--) {
Christopher Ferris46756822014-01-14 20:16:30 -0800125 if (backtrace->GetFrame(i)->func_name == "test_level_one") {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700126 frame_num = i;
127 break;
128 }
129 }
Christopher Ferris20303f82014-01-10 16:33:16 -0800130 ASSERT_LT(static_cast<size_t>(0), frame_num);
131 ASSERT_LE(static_cast<size_t>(3), frame_num);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700132
Christopher Ferris46756822014-01-14 20:16:30 -0800133 ASSERT_EQ(backtrace->GetFrame(frame_num)->func_name, "test_level_one");
134 ASSERT_EQ(backtrace->GetFrame(frame_num-1)->func_name, "test_level_two");
135 ASSERT_EQ(backtrace->GetFrame(frame_num-2)->func_name, "test_level_three");
136 ASSERT_EQ(backtrace->GetFrame(frame_num-3)->func_name, "test_level_four");
Christopher Ferris17e91d42013-10-21 13:30:52 -0700137}
138
139void VerifyLevelBacktrace(void*) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800140 UniquePtr<Backtrace> backtrace(
141 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
142 ASSERT_TRUE(backtrace.get() != NULL);
143 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700144
Christopher Ferris20303f82014-01-10 16:33:16 -0800145 VerifyLevelDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700146}
147
Christopher Ferris20303f82014-01-10 16:33:16 -0800148bool ReadyMaxBacktrace(Backtrace* backtrace) {
149 return (backtrace->NumFrames() == MAX_BACKTRACE_FRAMES);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700150}
151
Christopher Ferris20303f82014-01-10 16:33:16 -0800152void VerifyMaxDump(Backtrace* backtrace) {
153 ASSERT_EQ(backtrace->NumFrames(), static_cast<size_t>(MAX_BACKTRACE_FRAMES));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700154 // Verify that the last frame is our recursive call.
Christopher Ferris46756822014-01-14 20:16:30 -0800155 ASSERT_EQ(backtrace->GetFrame(MAX_BACKTRACE_FRAMES-1)->func_name,
156 "test_recursive_call");
Christopher Ferris17e91d42013-10-21 13:30:52 -0700157}
158
159void VerifyMaxBacktrace(void*) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800160 UniquePtr<Backtrace> backtrace(
161 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
162 ASSERT_TRUE(backtrace.get() != NULL);
163 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700164
Christopher Ferris20303f82014-01-10 16:33:16 -0800165 VerifyMaxDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700166}
167
168void ThreadSetState(void* data) {
169 thread_t* thread = reinterpret_cast<thread_t*>(data);
170 android_atomic_acquire_store(1, &thread->state);
171 volatile int i = 0;
172 while (thread->state) {
173 i++;
174 }
175}
176
Christopher Ferris20303f82014-01-10 16:33:16 -0800177void VerifyThreadTest(pid_t tid, void (*VerifyFunc)(Backtrace*)) {
178 UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), tid));
179 ASSERT_TRUE(backtrace.get() != NULL);
180 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700181
Christopher Ferris20303f82014-01-10 16:33:16 -0800182 VerifyFunc(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700183}
184
185bool WaitForNonZero(int32_t* value, uint64_t seconds) {
186 uint64_t start = NanoTime();
187 do {
188 if (android_atomic_acquire_load(value)) {
189 return true;
190 }
191 } while ((NanoTime() - start) < seconds * NS_PER_SEC);
192 return false;
193}
194
195TEST(libbacktrace, local_trace) {
196 ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelBacktrace, NULL), 0);
197}
198
199void VerifyIgnoreFrames(
Christopher Ferris20303f82014-01-10 16:33:16 -0800200 Backtrace* bt_all, Backtrace* bt_ign1,
201 Backtrace* bt_ign2, const char* cur_proc) {
202 EXPECT_EQ(bt_all->NumFrames(), bt_ign1->NumFrames() + 1);
203 EXPECT_EQ(bt_all->NumFrames(), bt_ign2->NumFrames() + 2);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700204
205 // Check all of the frames are the same > the current frame.
206 bool check = (cur_proc == NULL);
Christopher Ferris20303f82014-01-10 16:33:16 -0800207 for (size_t i = 0; i < bt_ign2->NumFrames(); i++) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700208 if (check) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800209 EXPECT_EQ(bt_ign2->GetFrame(i)->pc, bt_ign1->GetFrame(i+1)->pc);
210 EXPECT_EQ(bt_ign2->GetFrame(i)->sp, bt_ign1->GetFrame(i+1)->sp);
211 EXPECT_EQ(bt_ign2->GetFrame(i)->stack_size, bt_ign1->GetFrame(i+1)->stack_size);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700212
Christopher Ferris20303f82014-01-10 16:33:16 -0800213 EXPECT_EQ(bt_ign2->GetFrame(i)->pc, bt_all->GetFrame(i+2)->pc);
214 EXPECT_EQ(bt_ign2->GetFrame(i)->sp, bt_all->GetFrame(i+2)->sp);
215 EXPECT_EQ(bt_ign2->GetFrame(i)->stack_size, bt_all->GetFrame(i+2)->stack_size);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700216 }
Christopher Ferris46756822014-01-14 20:16:30 -0800217 if (!check && bt_ign2->GetFrame(i)->func_name == cur_proc) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700218 check = true;
219 }
220 }
221}
222
223void VerifyLevelIgnoreFrames(void*) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800224 UniquePtr<Backtrace> all(
225 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
226 ASSERT_TRUE(all.get() != NULL);
227 ASSERT_TRUE(all->Unwind(0));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700228
Christopher Ferris20303f82014-01-10 16:33:16 -0800229 UniquePtr<Backtrace> ign1(
230 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
231 ASSERT_TRUE(ign1.get() != NULL);
232 ASSERT_TRUE(ign1->Unwind(1));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700233
Christopher Ferris20303f82014-01-10 16:33:16 -0800234 UniquePtr<Backtrace> ign2(
235 Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
236 ASSERT_TRUE(ign2.get() != NULL);
237 ASSERT_TRUE(ign2->Unwind(2));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700238
Christopher Ferris20303f82014-01-10 16:33:16 -0800239 VerifyIgnoreFrames(all.get(), ign1.get(), ign2.get(), "VerifyLevelIgnoreFrames");
Christopher Ferris17e91d42013-10-21 13:30:52 -0700240}
241
242TEST(libbacktrace, local_trace_ignore_frames) {
243 ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelIgnoreFrames, NULL), 0);
244}
245
246TEST(libbacktrace, local_max_trace) {
247 ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, VerifyMaxBacktrace, NULL), 0);
248}
249
Christopher Ferrisdf290612014-01-22 19:21:07 -0800250void VerifyProcTest(pid_t pid, pid_t tid, bool share_map,
Christopher Ferris20303f82014-01-10 16:33:16 -0800251 bool (*ReadyFunc)(Backtrace*),
252 void (*VerifyFunc)(Backtrace*)) {
Christopher Ferris17e91d42013-10-21 13:30:52 -0700253 pid_t ptrace_tid;
254 if (tid < 0) {
255 ptrace_tid = pid;
256 } else {
257 ptrace_tid = tid;
258 }
259 uint64_t start = NanoTime();
260 bool verified = false;
261 do {
262 usleep(US_PER_MSEC);
263 if (ptrace(PTRACE_ATTACH, ptrace_tid, 0, 0) == 0) {
264 // Wait for the process to get to a stopping point.
265 WaitForStop(ptrace_tid);
266
Christopher Ferrisdf290612014-01-22 19:21:07 -0800267 UniquePtr<BacktraceMap> map;
268 if (share_map) {
269 map.reset(BacktraceMap::Create(pid));
270 }
271 UniquePtr<Backtrace> backtrace(Backtrace::Create(pid, tid, map.get()));
Christopher Ferris20303f82014-01-10 16:33:16 -0800272 ASSERT_TRUE(backtrace->Unwind(0));
273 ASSERT_TRUE(backtrace.get() != NULL);
274 if (ReadyFunc(backtrace.get())) {
275 VerifyFunc(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700276 verified = true;
277 }
Christopher Ferris20303f82014-01-10 16:33:16 -0800278
Christopher Ferris17e91d42013-10-21 13:30:52 -0700279 ASSERT_TRUE(ptrace(PTRACE_DETACH, ptrace_tid, 0, 0) == 0);
280 }
281 // If 5 seconds have passed, then we are done.
282 } while (!verified && (NanoTime() - start) <= 5 * NS_PER_SEC);
283 ASSERT_TRUE(verified);
284}
285
286TEST(libbacktrace, ptrace_trace) {
287 pid_t pid;
288 if ((pid = fork()) == 0) {
289 ASSERT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0);
290 exit(1);
291 }
Christopher Ferrisdf290612014-01-22 19:21:07 -0800292 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, false, ReadyLevelBacktrace, VerifyLevelDump);
293
294 kill(pid, SIGKILL);
295 int status;
296 ASSERT_EQ(waitpid(pid, &status, 0), pid);
297}
298
299TEST(libbacktrace, ptrace_trace_shared_map) {
300 pid_t pid;
301 if ((pid = fork()) == 0) {
302 ASSERT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0);
303 exit(1);
304 }
305
306 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, true, ReadyLevelBacktrace, VerifyLevelDump);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700307
308 kill(pid, SIGKILL);
309 int status;
310 ASSERT_EQ(waitpid(pid, &status, 0), pid);
311}
312
313TEST(libbacktrace, ptrace_max_trace) {
314 pid_t pid;
315 if ((pid = fork()) == 0) {
316 ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, NULL, NULL), 0);
317 exit(1);
318 }
Christopher Ferrisdf290612014-01-22 19:21:07 -0800319 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, false, ReadyMaxBacktrace, VerifyMaxDump);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700320
321 kill(pid, SIGKILL);
322 int status;
323 ASSERT_EQ(waitpid(pid, &status, 0), pid);
324}
325
Christopher Ferris20303f82014-01-10 16:33:16 -0800326void VerifyProcessIgnoreFrames(Backtrace* bt_all) {
327 UniquePtr<Backtrace> ign1(Backtrace::Create(bt_all->Pid(), BACKTRACE_CURRENT_THREAD));
328 ASSERT_TRUE(ign1.get() != NULL);
329 ASSERT_TRUE(ign1->Unwind(1));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700330
Christopher Ferris20303f82014-01-10 16:33:16 -0800331 UniquePtr<Backtrace> ign2(Backtrace::Create(bt_all->Pid(), BACKTRACE_CURRENT_THREAD));
332 ASSERT_TRUE(ign2.get() != NULL);
333 ASSERT_TRUE(ign2->Unwind(2));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700334
Christopher Ferris20303f82014-01-10 16:33:16 -0800335 VerifyIgnoreFrames(bt_all, ign1.get(), ign2.get(), NULL);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700336}
337
338TEST(libbacktrace, ptrace_ignore_frames) {
339 pid_t pid;
340 if ((pid = fork()) == 0) {
341 ASSERT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0);
342 exit(1);
343 }
Christopher Ferrisdf290612014-01-22 19:21:07 -0800344 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, false, ReadyLevelBacktrace, VerifyProcessIgnoreFrames);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700345
346 kill(pid, SIGKILL);
347 int status;
348 ASSERT_EQ(waitpid(pid, &status, 0), pid);
349}
350
351// Create a process with multiple threads and dump all of the threads.
352void* PtraceThreadLevelRun(void*) {
353 EXPECT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0);
354 return NULL;
355}
356
357void GetThreads(pid_t pid, std::vector<pid_t>* threads) {
358 // Get the list of tasks.
359 char task_path[128];
360 snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
361
362 DIR* tasks_dir = opendir(task_path);
363 ASSERT_TRUE(tasks_dir != NULL);
364 struct dirent* entry;
365 while ((entry = readdir(tasks_dir)) != NULL) {
366 char* end;
367 pid_t tid = strtoul(entry->d_name, &end, 10);
368 if (*end == '\0') {
369 threads->push_back(tid);
370 }
371 }
372 closedir(tasks_dir);
373}
374
375TEST(libbacktrace, ptrace_threads) {
376 pid_t pid;
377 if ((pid = fork()) == 0) {
378 for (size_t i = 0; i < NUM_PTRACE_THREADS; i++) {
379 pthread_attr_t attr;
380 pthread_attr_init(&attr);
381 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
382
383 pthread_t thread;
384 ASSERT_TRUE(pthread_create(&thread, &attr, PtraceThreadLevelRun, NULL) == 0);
385 }
386 ASSERT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0);
387 exit(1);
388 }
389
390 // Check to see that all of the threads are running before unwinding.
391 std::vector<pid_t> threads;
392 uint64_t start = NanoTime();
393 do {
394 usleep(US_PER_MSEC);
395 threads.clear();
396 GetThreads(pid, &threads);
397 } while ((threads.size() != NUM_PTRACE_THREADS + 1) &&
398 ((NanoTime() - start) <= 5 * NS_PER_SEC));
399 ASSERT_EQ(threads.size(), static_cast<size_t>(NUM_PTRACE_THREADS + 1));
400
401 ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0);
402 WaitForStop(pid);
403 for (std::vector<int>::const_iterator it = threads.begin(); it != threads.end(); ++it) {
404 // Skip the current forked process, we only care about the threads.
405 if (pid == *it) {
406 continue;
407 }
Christopher Ferrisdf290612014-01-22 19:21:07 -0800408 VerifyProcTest(pid, *it, false, ReadyLevelBacktrace, VerifyLevelDump);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700409 }
410 ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0);
411
412 kill(pid, SIGKILL);
413 int status;
414 ASSERT_EQ(waitpid(pid, &status, 0), pid);
415}
416
417void VerifyLevelThread(void*) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800418 UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), gettid()));
419 ASSERT_TRUE(backtrace.get() != NULL);
420 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700421
Christopher Ferris20303f82014-01-10 16:33:16 -0800422 VerifyLevelDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700423}
424
425TEST(libbacktrace, thread_current_level) {
426 ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelThread, NULL), 0);
427}
428
429void VerifyMaxThread(void*) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800430 UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), gettid()));
431 ASSERT_TRUE(backtrace.get() != NULL);
432 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700433
Christopher Ferris20303f82014-01-10 16:33:16 -0800434 VerifyMaxDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700435}
436
437TEST(libbacktrace, thread_current_max) {
438 ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, VerifyMaxThread, NULL), 0);
439}
440
441void* ThreadLevelRun(void* data) {
442 thread_t* thread = reinterpret_cast<thread_t*>(data);
443
444 thread->tid = gettid();
445 EXPECT_NE(test_level_one(1, 2, 3, 4, ThreadSetState, data), 0);
446 return NULL;
447}
448
449TEST(libbacktrace, thread_level_trace) {
450 pthread_attr_t attr;
451 pthread_attr_init(&attr);
452 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
453
454 thread_t thread_data = { 0, 0, 0 };
455 pthread_t thread;
456 ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0);
457
458 // Wait up to 2 seconds for the tid to be set.
459 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));
460
461 // Save the current signal action and make sure it is restored afterwards.
462 struct sigaction cur_action;
463 ASSERT_TRUE(sigaction(SIGURG, NULL, &cur_action) == 0);
464
Christopher Ferris20303f82014-01-10 16:33:16 -0800465 UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid));
466 ASSERT_TRUE(backtrace.get() != NULL);
467 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700468
Christopher Ferris20303f82014-01-10 16:33:16 -0800469 VerifyLevelDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700470
471 // Tell the thread to exit its infinite loop.
472 android_atomic_acquire_store(0, &thread_data.state);
473
474 // Verify that the old action was restored.
475 struct sigaction new_action;
476 ASSERT_TRUE(sigaction(SIGURG, NULL, &new_action) == 0);
477 EXPECT_EQ(cur_action.sa_sigaction, new_action.sa_sigaction);
478 EXPECT_EQ(cur_action.sa_flags, new_action.sa_flags);
479}
480
481TEST(libbacktrace, thread_ignore_frames) {
482 pthread_attr_t attr;
483 pthread_attr_init(&attr);
484 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
485
486 thread_t thread_data = { 0, 0, 0 };
487 pthread_t thread;
488 ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0);
489
490 // Wait up to 2 seconds for the tid to be set.
491 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));
492
Christopher Ferris20303f82014-01-10 16:33:16 -0800493 UniquePtr<Backtrace> all(Backtrace::Create(getpid(), thread_data.tid));
494 ASSERT_TRUE(all.get() != NULL);
495 ASSERT_TRUE(all->Unwind(0));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700496
Christopher Ferris20303f82014-01-10 16:33:16 -0800497 UniquePtr<Backtrace> ign1(Backtrace::Create(getpid(), thread_data.tid));
498 ASSERT_TRUE(ign1.get() != NULL);
499 ASSERT_TRUE(ign1->Unwind(1));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700500
Christopher Ferris20303f82014-01-10 16:33:16 -0800501 UniquePtr<Backtrace> ign2(Backtrace::Create(getpid(), thread_data.tid));
502 ASSERT_TRUE(ign2.get() != NULL);
503 ASSERT_TRUE(ign2->Unwind(2));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700504
Christopher Ferris20303f82014-01-10 16:33:16 -0800505 VerifyIgnoreFrames(all.get(), ign1.get(), ign2.get(), NULL);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700506
507 // Tell the thread to exit its infinite loop.
508 android_atomic_acquire_store(0, &thread_data.state);
509}
510
511void* ThreadMaxRun(void* data) {
512 thread_t* thread = reinterpret_cast<thread_t*>(data);
513
514 thread->tid = gettid();
515 EXPECT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, ThreadSetState, data), 0);
516 return NULL;
517}
518
519TEST(libbacktrace, thread_max_trace) {
520 pthread_attr_t attr;
521 pthread_attr_init(&attr);
522 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
523
524 thread_t thread_data = { 0, 0, 0 };
525 pthread_t thread;
526 ASSERT_TRUE(pthread_create(&thread, &attr, ThreadMaxRun, &thread_data) == 0);
527
528 // Wait for the tid to be set.
529 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));
530
Christopher Ferris20303f82014-01-10 16:33:16 -0800531 UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid));
532 ASSERT_TRUE(backtrace.get() != NULL);
533 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700534
Christopher Ferris20303f82014-01-10 16:33:16 -0800535 VerifyMaxDump(backtrace.get());
Christopher Ferris17e91d42013-10-21 13:30:52 -0700536
537 // Tell the thread to exit its infinite loop.
538 android_atomic_acquire_store(0, &thread_data.state);
539}
540
541void* ThreadDump(void* data) {
542 dump_thread_t* dump = reinterpret_cast<dump_thread_t*>(data);
543 while (true) {
544 if (android_atomic_acquire_load(dump->now)) {
545 break;
546 }
547 }
548
Christopher Ferris17e91d42013-10-21 13:30:52 -0700549 // The status of the actual unwind will be checked elsewhere.
Christopher Ferris20303f82014-01-10 16:33:16 -0800550 dump->backtrace = Backtrace::Create(getpid(), dump->thread.tid);
551 dump->backtrace->Unwind(0);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700552
553 android_atomic_acquire_store(1, &dump->done);
554
555 return NULL;
556}
557
558TEST(libbacktrace, thread_multiple_dump) {
559 // Dump NUM_THREADS simultaneously.
560 std::vector<thread_t> runners(NUM_THREADS);
561 std::vector<dump_thread_t> dumpers(NUM_THREADS);
562
563 pthread_attr_t attr;
564 pthread_attr_init(&attr);
565 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
566 for (size_t i = 0; i < NUM_THREADS; i++) {
567 // Launch the runners, they will spin in hard loops doing nothing.
568 runners[i].tid = 0;
569 runners[i].state = 0;
570 ASSERT_TRUE(pthread_create(&runners[i].threadId, &attr, ThreadMaxRun, &runners[i]) == 0);
571 }
572
573 // Wait for tids to be set.
574 for (std::vector<thread_t>::iterator it = runners.begin(); it != runners.end(); ++it) {
575 ASSERT_TRUE(WaitForNonZero(&it->state, 10));
576 }
577
578 // Start all of the dumpers at once, they will spin until they are signalled
579 // to begin their dump run.
580 int32_t dump_now = 0;
581 for (size_t i = 0; i < NUM_THREADS; i++) {
582 dumpers[i].thread.tid = runners[i].tid;
583 dumpers[i].thread.state = 0;
584 dumpers[i].done = 0;
585 dumpers[i].now = &dump_now;
586
587 ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0);
588 }
589
590 // Start all of the dumpers going at once.
591 android_atomic_acquire_store(1, &dump_now);
592
593 for (size_t i = 0; i < NUM_THREADS; i++) {
594 ASSERT_TRUE(WaitForNonZero(&dumpers[i].done, 10));
595
596 // Tell the runner thread to exit its infinite loop.
597 android_atomic_acquire_store(0, &runners[i].state);
598
Christopher Ferris20303f82014-01-10 16:33:16 -0800599 ASSERT_TRUE(dumpers[i].backtrace != NULL);
600 VerifyMaxDump(dumpers[i].backtrace);
601
602 delete dumpers[i].backtrace;
603 dumpers[i].backtrace = NULL;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700604 }
605}
606
Christopher Ferrisdf290612014-01-22 19:21:07 -0800607// This test is for UnwindMaps that should share the same map cursor when
608// multiple maps are created for the current process at the same time.
609TEST(libbacktrace, simultaneous_maps) {
610 BacktraceMap* map1 = BacktraceMap::Create(getpid());
611 BacktraceMap* map2 = BacktraceMap::Create(getpid());
612 BacktraceMap* map3 = BacktraceMap::Create(getpid());
613
614 Backtrace* back1 = Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD, map1);
615 EXPECT_TRUE(back1->Unwind(0));
616 delete back1;
617 delete map1;
618
619 Backtrace* back2 = Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD, map2);
620 EXPECT_TRUE(back2->Unwind(0));
621 delete back2;
622 delete map2;
623
624 Backtrace* back3 = Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD, map3);
625 EXPECT_TRUE(back3->Unwind(0));
626 delete back3;
627 delete map3;
628}
629
Christopher Ferris17e91d42013-10-21 13:30:52 -0700630TEST(libbacktrace, format_test) {
Christopher Ferris20303f82014-01-10 16:33:16 -0800631 UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD));
632 ASSERT_TRUE(backtrace.get() != NULL);
Christopher Ferris17e91d42013-10-21 13:30:52 -0700633
Christopher Ferris20303f82014-01-10 16:33:16 -0800634 backtrace_frame_data_t frame;
Christopher Ferris46756822014-01-14 20:16:30 -0800635 frame.num = 1;
636 frame.pc = 2;
637 frame.sp = 0;
638 frame.stack_size = 0;
639 frame.map = NULL;
640 frame.func_offset = 0;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700641
Christopher Ferris46756822014-01-14 20:16:30 -0800642 backtrace_map_t map;
643 map.start = 0;
644 map.end = 0;
645
646 // Check no map set.
Christopher Ferris20303f82014-01-10 16:33:16 -0800647 frame.num = 1;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700648#if defined(__LP64__)
Christopher Ferris46756822014-01-14 20:16:30 -0800649 EXPECT_EQ("#01 pc 0000000000000002 <unknown>",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700650#else
Christopher Ferris46756822014-01-14 20:16:30 -0800651 EXPECT_EQ("#01 pc 00000002 <unknown>",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700652#endif
Christopher Ferris46756822014-01-14 20:16:30 -0800653 backtrace->FormatFrameData(&frame));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700654
Christopher Ferris46756822014-01-14 20:16:30 -0800655 // Check map name empty, but exists.
656 frame.map = &map;
657 map.start = 1;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700658#if defined(__LP64__)
Christopher Ferris46756822014-01-14 20:16:30 -0800659 EXPECT_EQ("#01 pc 0000000000000001 <unknown>",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700660#else
Christopher Ferris46756822014-01-14 20:16:30 -0800661 EXPECT_EQ("#01 pc 00000001 <unknown>",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700662#endif
Christopher Ferris46756822014-01-14 20:16:30 -0800663 backtrace->FormatFrameData(&frame));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700664
Christopher Ferris46756822014-01-14 20:16:30 -0800665
666 // Check relative pc is set and map name is set.
667 frame.pc = 0x12345679;
668 frame.map = &map;
669 map.name = "MapFake";
670 map.start = 1;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700671#if defined(__LP64__)
Christopher Ferris46756822014-01-14 20:16:30 -0800672 EXPECT_EQ("#01 pc 0000000012345678 MapFake",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700673#else
Christopher Ferris46756822014-01-14 20:16:30 -0800674 EXPECT_EQ("#01 pc 12345678 MapFake",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700675#endif
Christopher Ferris46756822014-01-14 20:16:30 -0800676 backtrace->FormatFrameData(&frame));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700677
Christopher Ferris46756822014-01-14 20:16:30 -0800678 // Check func_name is set, but no func offset.
679 frame.func_name = "ProcFake";
680#if defined(__LP64__)
681 EXPECT_EQ("#01 pc 0000000012345678 MapFake (ProcFake)",
682#else
683 EXPECT_EQ("#01 pc 12345678 MapFake (ProcFake)",
684#endif
685 backtrace->FormatFrameData(&frame));
686
687 // Check func_name is set, and func offset is non-zero.
Christopher Ferris20303f82014-01-10 16:33:16 -0800688 frame.func_offset = 645;
Christopher Ferris17e91d42013-10-21 13:30:52 -0700689#if defined(__LP64__)
Christopher Ferris46756822014-01-14 20:16:30 -0800690 EXPECT_EQ("#01 pc 0000000012345678 MapFake (ProcFake+645)",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700691#else
Christopher Ferris46756822014-01-14 20:16:30 -0800692 EXPECT_EQ("#01 pc 12345678 MapFake (ProcFake+645)",
Christopher Ferris17e91d42013-10-21 13:30:52 -0700693#endif
Christopher Ferris46756822014-01-14 20:16:30 -0800694 backtrace->FormatFrameData(&frame));
Christopher Ferris17e91d42013-10-21 13:30:52 -0700695}