[go: nahoru, domu]

blob: 0ff78976239afe24b5e3f5c9b0025b66bb838f3f [file] [log] [blame]
Christopher Ferris20bc65f2013-10-29 20:56:521/*
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 Ferris737b6a12014-01-14 02:12:0431#include <backtrace/Backtrace.h>
Christopher Ferrisabf39bb2014-01-17 19:56:0432#include <backtrace/BacktraceMap.h>
Christopher Ferris737b6a12014-01-14 02:12:0433#include <UniquePtr.h>
Christopher Ferris20bc65f2013-10-29 20:56:5234
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 Ferrisabf39bb2014-01-17 19:56:0454struct thread_t {
Christopher Ferris20bc65f2013-10-29 20:56:5255 pid_t tid;
56 int32_t state;
57 pthread_t threadId;
Christopher Ferrisabf39bb2014-01-17 19:56:0458};
Christopher Ferris20bc65f2013-10-29 20:56:5259
Christopher Ferrisabf39bb2014-01-17 19:56:0460struct dump_thread_t {
Christopher Ferris20bc65f2013-10-29 20:56:5261 thread_t thread;
Christopher Ferris737b6a12014-01-14 02:12:0462 Backtrace* backtrace;
Christopher Ferris20bc65f2013-10-29 20:56:5263 int32_t* now;
64 int32_t done;
Christopher Ferrisabf39bb2014-01-17 19:56:0465};
Christopher Ferris20bc65f2013-10-29 20:56:5266
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 Ferris737b6a12014-01-14 02:12:0480void DumpFrames(Backtrace* backtrace) {
81 if (backtrace->NumFrames() == 0) {
Christopher Ferris20bc65f2013-10-29 20:56:5282 printf(" No frames to dump\n");
Christopher Ferris737b6a12014-01-14 02:12:0483 return;
84 }
85
86 for (size_t i = 0; i < backtrace->NumFrames(); i++) {
87 printf(" %s\n", backtrace->FormatFrameData(i).c_str());
Christopher Ferris20bc65f2013-10-29 20:56:5288 }
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 Ferris737b6a12014-01-14 02:12:04104bool ReadyLevelBacktrace(Backtrace* backtrace) {
Christopher Ferris20bc65f2013-10-29 20:56:52105 // See if test_level_four is in the backtrace.
106 bool found = false;
Christopher Ferrisabf39bb2014-01-17 19:56:04107 for (Backtrace::const_iterator it = backtrace->begin(); it != backtrace->end(); ++it) {
108 if (it->func_name == "test_level_four") {
Christopher Ferris20bc65f2013-10-29 20:56:52109 found = true;
110 break;
111 }
112 }
113
114 return found;
115}
116
Christopher Ferris737b6a12014-01-14 02:12:04117void 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 Ferris20bc65f2013-10-29 20:56:52120
121 // Look through the frames starting at the highest to find the
122 // frame we want.
123 size_t frame_num = 0;
Christopher Ferris737b6a12014-01-14 02:12:04124 for (size_t i = backtrace->NumFrames()-1; i > 2; i--) {
Christopher Ferrisabf39bb2014-01-17 19:56:04125 if (backtrace->GetFrame(i)->func_name == "test_level_one") {
Christopher Ferris20bc65f2013-10-29 20:56:52126 frame_num = i;
127 break;
128 }
129 }
Christopher Ferris737b6a12014-01-14 02:12:04130 ASSERT_LT(static_cast<size_t>(0), frame_num);
131 ASSERT_LE(static_cast<size_t>(3), frame_num);
Christopher Ferris20bc65f2013-10-29 20:56:52132
Christopher Ferrisabf39bb2014-01-17 19:56:04133 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 Ferris20bc65f2013-10-29 20:56:52137}
138
139void VerifyLevelBacktrace(void*) {
Christopher Ferris737b6a12014-01-14 02:12:04140 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 Ferris20bc65f2013-10-29 20:56:52144
Christopher Ferris737b6a12014-01-14 02:12:04145 VerifyLevelDump(backtrace.get());
Christopher Ferris20bc65f2013-10-29 20:56:52146}
147
Christopher Ferris737b6a12014-01-14 02:12:04148bool ReadyMaxBacktrace(Backtrace* backtrace) {
149 return (backtrace->NumFrames() == MAX_BACKTRACE_FRAMES);
Christopher Ferris20bc65f2013-10-29 20:56:52150}
151
Christopher Ferris737b6a12014-01-14 02:12:04152void VerifyMaxDump(Backtrace* backtrace) {
153 ASSERT_EQ(backtrace->NumFrames(), static_cast<size_t>(MAX_BACKTRACE_FRAMES));
Christopher Ferris20bc65f2013-10-29 20:56:52154 // Verify that the last frame is our recursive call.
Christopher Ferrisabf39bb2014-01-17 19:56:04155 ASSERT_EQ(backtrace->GetFrame(MAX_BACKTRACE_FRAMES-1)->func_name,
156 "test_recursive_call");
Christopher Ferris20bc65f2013-10-29 20:56:52157}
158
159void VerifyMaxBacktrace(void*) {
Christopher Ferris737b6a12014-01-14 02:12:04160 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 Ferris20bc65f2013-10-29 20:56:52164
Christopher Ferris737b6a12014-01-14 02:12:04165 VerifyMaxDump(backtrace.get());
Christopher Ferris20bc65f2013-10-29 20:56:52166}
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 Ferris737b6a12014-01-14 02:12:04177void 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 Ferris20bc65f2013-10-29 20:56:52181
Christopher Ferris737b6a12014-01-14 02:12:04182 VerifyFunc(backtrace.get());
Christopher Ferris20bc65f2013-10-29 20:56:52183}
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 Ferris737b6a12014-01-14 02:12:04200 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 Ferris20bc65f2013-10-29 20:56:52204
205 // Check all of the frames are the same > the current frame.
206 bool check = (cur_proc == NULL);
Christopher Ferris737b6a12014-01-14 02:12:04207 for (size_t i = 0; i < bt_ign2->NumFrames(); i++) {
Christopher Ferris20bc65f2013-10-29 20:56:52208 if (check) {
Christopher Ferris737b6a12014-01-14 02:12:04209 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 Ferris20bc65f2013-10-29 20:56:52212
Christopher Ferris737b6a12014-01-14 02:12:04213 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 Ferris20bc65f2013-10-29 20:56:52216 }
Christopher Ferrisabf39bb2014-01-17 19:56:04217 if (!check && bt_ign2->GetFrame(i)->func_name == cur_proc) {
Christopher Ferris20bc65f2013-10-29 20:56:52218 check = true;
219 }
220 }
221}
222
223void VerifyLevelIgnoreFrames(void*) {
Christopher Ferris737b6a12014-01-14 02:12:04224 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 Ferris20bc65f2013-10-29 20:56:52228
Christopher Ferris737b6a12014-01-14 02:12:04229 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 Ferris20bc65f2013-10-29 20:56:52233
Christopher Ferris737b6a12014-01-14 02:12:04234 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 Ferris20bc65f2013-10-29 20:56:52238
Christopher Ferris737b6a12014-01-14 02:12:04239 VerifyIgnoreFrames(all.get(), ign1.get(), ign2.get(), "VerifyLevelIgnoreFrames");
Christopher Ferris20bc65f2013-10-29 20:56:52240}
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
250void VerifyProcTest(pid_t pid, pid_t tid,
Christopher Ferris737b6a12014-01-14 02:12:04251 bool (*ReadyFunc)(Backtrace*),
252 void (*VerifyFunc)(Backtrace*)) {
Christopher Ferris20bc65f2013-10-29 20:56:52253 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 Ferris737b6a12014-01-14 02:12:04267 UniquePtr<Backtrace> backtrace(Backtrace::Create(pid, tid));
268 ASSERT_TRUE(backtrace->Unwind(0));
269 ASSERT_TRUE(backtrace.get() != NULL);
270 if (ReadyFunc(backtrace.get())) {
271 VerifyFunc(backtrace.get());
Christopher Ferris20bc65f2013-10-29 20:56:52272 verified = true;
273 }
Christopher Ferris737b6a12014-01-14 02:12:04274
Christopher Ferris20bc65f2013-10-29 20:56:52275 ASSERT_TRUE(ptrace(PTRACE_DETACH, ptrace_tid, 0, 0) == 0);
276 }
277 // If 5 seconds have passed, then we are done.
278 } while (!verified && (NanoTime() - start) <= 5 * NS_PER_SEC);
279 ASSERT_TRUE(verified);
280}
281
282TEST(libbacktrace, ptrace_trace) {
283 pid_t pid;
284 if ((pid = fork()) == 0) {
285 ASSERT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0);
286 exit(1);
287 }
Christopher Ferrisd3823fd2013-11-12 18:54:16288 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyLevelBacktrace, VerifyLevelDump);
Christopher Ferris20bc65f2013-10-29 20:56:52289
290 kill(pid, SIGKILL);
291 int status;
292 ASSERT_EQ(waitpid(pid, &status, 0), pid);
293}
294
295TEST(libbacktrace, ptrace_max_trace) {
296 pid_t pid;
297 if ((pid = fork()) == 0) {
298 ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, NULL, NULL), 0);
299 exit(1);
300 }
Christopher Ferrisd3823fd2013-11-12 18:54:16301 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyMaxBacktrace, VerifyMaxDump);
Christopher Ferris20bc65f2013-10-29 20:56:52302
303 kill(pid, SIGKILL);
304 int status;
305 ASSERT_EQ(waitpid(pid, &status, 0), pid);
306}
307
Christopher Ferris737b6a12014-01-14 02:12:04308void VerifyProcessIgnoreFrames(Backtrace* bt_all) {
309 UniquePtr<Backtrace> ign1(Backtrace::Create(bt_all->Pid(), BACKTRACE_CURRENT_THREAD));
310 ASSERT_TRUE(ign1.get() != NULL);
311 ASSERT_TRUE(ign1->Unwind(1));
Christopher Ferris20bc65f2013-10-29 20:56:52312
Christopher Ferris737b6a12014-01-14 02:12:04313 UniquePtr<Backtrace> ign2(Backtrace::Create(bt_all->Pid(), BACKTRACE_CURRENT_THREAD));
314 ASSERT_TRUE(ign2.get() != NULL);
315 ASSERT_TRUE(ign2->Unwind(2));
Christopher Ferris20bc65f2013-10-29 20:56:52316
Christopher Ferris737b6a12014-01-14 02:12:04317 VerifyIgnoreFrames(bt_all, ign1.get(), ign2.get(), NULL);
Christopher Ferris20bc65f2013-10-29 20:56:52318}
319
320TEST(libbacktrace, ptrace_ignore_frames) {
321 pid_t pid;
322 if ((pid = fork()) == 0) {
323 ASSERT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0);
324 exit(1);
325 }
Christopher Ferrisd3823fd2013-11-12 18:54:16326 VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, ReadyLevelBacktrace, VerifyProcessIgnoreFrames);
Christopher Ferris20bc65f2013-10-29 20:56:52327
328 kill(pid, SIGKILL);
329 int status;
330 ASSERT_EQ(waitpid(pid, &status, 0), pid);
331}
332
333// Create a process with multiple threads and dump all of the threads.
334void* PtraceThreadLevelRun(void*) {
335 EXPECT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0);
336 return NULL;
337}
338
339void GetThreads(pid_t pid, std::vector<pid_t>* threads) {
340 // Get the list of tasks.
341 char task_path[128];
342 snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
343
344 DIR* tasks_dir = opendir(task_path);
345 ASSERT_TRUE(tasks_dir != NULL);
346 struct dirent* entry;
347 while ((entry = readdir(tasks_dir)) != NULL) {
348 char* end;
349 pid_t tid = strtoul(entry->d_name, &end, 10);
350 if (*end == '\0') {
351 threads->push_back(tid);
352 }
353 }
354 closedir(tasks_dir);
355}
356
357TEST(libbacktrace, ptrace_threads) {
358 pid_t pid;
359 if ((pid = fork()) == 0) {
360 for (size_t i = 0; i < NUM_PTRACE_THREADS; i++) {
361 pthread_attr_t attr;
362 pthread_attr_init(&attr);
363 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
364
365 pthread_t thread;
366 ASSERT_TRUE(pthread_create(&thread, &attr, PtraceThreadLevelRun, NULL) == 0);
367 }
368 ASSERT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0);
369 exit(1);
370 }
371
372 // Check to see that all of the threads are running before unwinding.
373 std::vector<pid_t> threads;
374 uint64_t start = NanoTime();
375 do {
376 usleep(US_PER_MSEC);
377 threads.clear();
378 GetThreads(pid, &threads);
379 } while ((threads.size() != NUM_PTRACE_THREADS + 1) &&
380 ((NanoTime() - start) <= 5 * NS_PER_SEC));
381 ASSERT_EQ(threads.size(), static_cast<size_t>(NUM_PTRACE_THREADS + 1));
382
383 ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0);
384 WaitForStop(pid);
385 for (std::vector<int>::const_iterator it = threads.begin(); it != threads.end(); ++it) {
386 // Skip the current forked process, we only care about the threads.
387 if (pid == *it) {
388 continue;
389 }
390 VerifyProcTest(pid, *it, ReadyLevelBacktrace, VerifyLevelDump);
391 }
392 ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0);
393
394 kill(pid, SIGKILL);
395 int status;
396 ASSERT_EQ(waitpid(pid, &status, 0), pid);
397}
398
399void VerifyLevelThread(void*) {
Christopher Ferris737b6a12014-01-14 02:12:04400 UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), gettid()));
401 ASSERT_TRUE(backtrace.get() != NULL);
402 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris20bc65f2013-10-29 20:56:52403
Christopher Ferris737b6a12014-01-14 02:12:04404 VerifyLevelDump(backtrace.get());
Christopher Ferris20bc65f2013-10-29 20:56:52405}
406
407TEST(libbacktrace, thread_current_level) {
408 ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelThread, NULL), 0);
409}
410
411void VerifyMaxThread(void*) {
Christopher Ferris737b6a12014-01-14 02:12:04412 UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), gettid()));
413 ASSERT_TRUE(backtrace.get() != NULL);
414 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris20bc65f2013-10-29 20:56:52415
Christopher Ferris737b6a12014-01-14 02:12:04416 VerifyMaxDump(backtrace.get());
Christopher Ferris20bc65f2013-10-29 20:56:52417}
418
419TEST(libbacktrace, thread_current_max) {
420 ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, VerifyMaxThread, NULL), 0);
421}
422
423void* ThreadLevelRun(void* data) {
424 thread_t* thread = reinterpret_cast<thread_t*>(data);
425
426 thread->tid = gettid();
427 EXPECT_NE(test_level_one(1, 2, 3, 4, ThreadSetState, data), 0);
428 return NULL;
429}
430
431TEST(libbacktrace, thread_level_trace) {
432 pthread_attr_t attr;
433 pthread_attr_init(&attr);
434 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
435
436 thread_t thread_data = { 0, 0, 0 };
437 pthread_t thread;
438 ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0);
439
440 // Wait up to 2 seconds for the tid to be set.
441 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));
442
443 // Save the current signal action and make sure it is restored afterwards.
444 struct sigaction cur_action;
445 ASSERT_TRUE(sigaction(SIGURG, NULL, &cur_action) == 0);
446
Christopher Ferris737b6a12014-01-14 02:12:04447 UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid));
448 ASSERT_TRUE(backtrace.get() != NULL);
449 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris20bc65f2013-10-29 20:56:52450
Christopher Ferris737b6a12014-01-14 02:12:04451 VerifyLevelDump(backtrace.get());
Christopher Ferris20bc65f2013-10-29 20:56:52452
453 // Tell the thread to exit its infinite loop.
454 android_atomic_acquire_store(0, &thread_data.state);
455
456 // Verify that the old action was restored.
457 struct sigaction new_action;
458 ASSERT_TRUE(sigaction(SIGURG, NULL, &new_action) == 0);
459 EXPECT_EQ(cur_action.sa_sigaction, new_action.sa_sigaction);
460 EXPECT_EQ(cur_action.sa_flags, new_action.sa_flags);
461}
462
463TEST(libbacktrace, thread_ignore_frames) {
464 pthread_attr_t attr;
465 pthread_attr_init(&attr);
466 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
467
468 thread_t thread_data = { 0, 0, 0 };
469 pthread_t thread;
470 ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0);
471
472 // Wait up to 2 seconds for the tid to be set.
473 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));
474
Christopher Ferris737b6a12014-01-14 02:12:04475 UniquePtr<Backtrace> all(Backtrace::Create(getpid(), thread_data.tid));
476 ASSERT_TRUE(all.get() != NULL);
477 ASSERT_TRUE(all->Unwind(0));
Christopher Ferris20bc65f2013-10-29 20:56:52478
Christopher Ferris737b6a12014-01-14 02:12:04479 UniquePtr<Backtrace> ign1(Backtrace::Create(getpid(), thread_data.tid));
480 ASSERT_TRUE(ign1.get() != NULL);
481 ASSERT_TRUE(ign1->Unwind(1));
Christopher Ferris20bc65f2013-10-29 20:56:52482
Christopher Ferris737b6a12014-01-14 02:12:04483 UniquePtr<Backtrace> ign2(Backtrace::Create(getpid(), thread_data.tid));
484 ASSERT_TRUE(ign2.get() != NULL);
485 ASSERT_TRUE(ign2->Unwind(2));
Christopher Ferris20bc65f2013-10-29 20:56:52486
Christopher Ferris737b6a12014-01-14 02:12:04487 VerifyIgnoreFrames(all.get(), ign1.get(), ign2.get(), NULL);
Christopher Ferris20bc65f2013-10-29 20:56:52488
489 // Tell the thread to exit its infinite loop.
490 android_atomic_acquire_store(0, &thread_data.state);
491}
492
493void* ThreadMaxRun(void* data) {
494 thread_t* thread = reinterpret_cast<thread_t*>(data);
495
496 thread->tid = gettid();
497 EXPECT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, ThreadSetState, data), 0);
498 return NULL;
499}
500
501TEST(libbacktrace, thread_max_trace) {
502 pthread_attr_t attr;
503 pthread_attr_init(&attr);
504 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
505
506 thread_t thread_data = { 0, 0, 0 };
507 pthread_t thread;
508 ASSERT_TRUE(pthread_create(&thread, &attr, ThreadMaxRun, &thread_data) == 0);
509
510 // Wait for the tid to be set.
511 ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));
512
Christopher Ferris737b6a12014-01-14 02:12:04513 UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid));
514 ASSERT_TRUE(backtrace.get() != NULL);
515 ASSERT_TRUE(backtrace->Unwind(0));
Christopher Ferris20bc65f2013-10-29 20:56:52516
Christopher Ferris737b6a12014-01-14 02:12:04517 VerifyMaxDump(backtrace.get());
Christopher Ferris20bc65f2013-10-29 20:56:52518
519 // Tell the thread to exit its infinite loop.
520 android_atomic_acquire_store(0, &thread_data.state);
521}
522
523void* ThreadDump(void* data) {
524 dump_thread_t* dump = reinterpret_cast<dump_thread_t*>(data);
525 while (true) {
526 if (android_atomic_acquire_load(dump->now)) {
527 break;
528 }
529 }
530
Christopher Ferris20bc65f2013-10-29 20:56:52531 // The status of the actual unwind will be checked elsewhere.
Christopher Ferris737b6a12014-01-14 02:12:04532 dump->backtrace = Backtrace::Create(getpid(), dump->thread.tid);
533 dump->backtrace->Unwind(0);
Christopher Ferris20bc65f2013-10-29 20:56:52534
535 android_atomic_acquire_store(1, &dump->done);
536
537 return NULL;
538}
539
540TEST(libbacktrace, thread_multiple_dump) {
541 // Dump NUM_THREADS simultaneously.
542 std::vector<thread_t> runners(NUM_THREADS);
543 std::vector<dump_thread_t> dumpers(NUM_THREADS);
544
545 pthread_attr_t attr;
546 pthread_attr_init(&attr);
547 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
548 for (size_t i = 0; i < NUM_THREADS; i++) {
549 // Launch the runners, they will spin in hard loops doing nothing.
550 runners[i].tid = 0;
551 runners[i].state = 0;
552 ASSERT_TRUE(pthread_create(&runners[i].threadId, &attr, ThreadMaxRun, &runners[i]) == 0);
553 }
554
555 // Wait for tids to be set.
556 for (std::vector<thread_t>::iterator it = runners.begin(); it != runners.end(); ++it) {
557 ASSERT_TRUE(WaitForNonZero(&it->state, 10));
558 }
559
560 // Start all of the dumpers at once, they will spin until they are signalled
561 // to begin their dump run.
562 int32_t dump_now = 0;
563 for (size_t i = 0; i < NUM_THREADS; i++) {
564 dumpers[i].thread.tid = runners[i].tid;
565 dumpers[i].thread.state = 0;
566 dumpers[i].done = 0;
567 dumpers[i].now = &dump_now;
568
569 ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0);
570 }
571
572 // Start all of the dumpers going at once.
573 android_atomic_acquire_store(1, &dump_now);
574
575 for (size_t i = 0; i < NUM_THREADS; i++) {
576 ASSERT_TRUE(WaitForNonZero(&dumpers[i].done, 10));
577
578 // Tell the runner thread to exit its infinite loop.
579 android_atomic_acquire_store(0, &runners[i].state);
580
Christopher Ferris737b6a12014-01-14 02:12:04581 ASSERT_TRUE(dumpers[i].backtrace != NULL);
582 VerifyMaxDump(dumpers[i].backtrace);
583
584 delete dumpers[i].backtrace;
585 dumpers[i].backtrace = NULL;
Christopher Ferris20bc65f2013-10-29 20:56:52586 }
587}
588
589TEST(libbacktrace, format_test) {
Christopher Ferris737b6a12014-01-14 02:12:04590 UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD));
591 ASSERT_TRUE(backtrace.get() != NULL);
Christopher Ferris20bc65f2013-10-29 20:56:52592
Christopher Ferris737b6a12014-01-14 02:12:04593 backtrace_frame_data_t frame;
Christopher Ferrisabf39bb2014-01-17 19:56:04594 frame.num = 1;
595 frame.pc = 2;
596 frame.sp = 0;
597 frame.stack_size = 0;
598 frame.map = NULL;
599 frame.func_offset = 0;
Christopher Ferris20bc65f2013-10-29 20:56:52600
Christopher Ferrisabf39bb2014-01-17 19:56:04601 backtrace_map_t map;
602 map.start = 0;
603 map.end = 0;
604
605 // Check no map set.
Christopher Ferris737b6a12014-01-14 02:12:04606 frame.num = 1;
Christopher Ferris20bc65f2013-10-29 20:56:52607#if defined(__LP64__)
Christopher Ferrisabf39bb2014-01-17 19:56:04608 EXPECT_EQ("#01 pc 0000000000000002 <unknown>",
Christopher Ferris20bc65f2013-10-29 20:56:52609#else
Christopher Ferrisabf39bb2014-01-17 19:56:04610 EXPECT_EQ("#01 pc 00000002 <unknown>",
Christopher Ferris20bc65f2013-10-29 20:56:52611#endif
Christopher Ferrisabf39bb2014-01-17 19:56:04612 backtrace->FormatFrameData(&frame));
Christopher Ferris20bc65f2013-10-29 20:56:52613
Christopher Ferrisabf39bb2014-01-17 19:56:04614 // Check map name empty, but exists.
615 frame.map = &map;
616 map.start = 1;
Christopher Ferris20bc65f2013-10-29 20:56:52617#if defined(__LP64__)
Christopher Ferrisabf39bb2014-01-17 19:56:04618 EXPECT_EQ("#01 pc 0000000000000001 <unknown>",
Christopher Ferris20bc65f2013-10-29 20:56:52619#else
Christopher Ferrisabf39bb2014-01-17 19:56:04620 EXPECT_EQ("#01 pc 00000001 <unknown>",
Christopher Ferris20bc65f2013-10-29 20:56:52621#endif
Christopher Ferrisabf39bb2014-01-17 19:56:04622 backtrace->FormatFrameData(&frame));
Christopher Ferris20bc65f2013-10-29 20:56:52623
Christopher Ferrisabf39bb2014-01-17 19:56:04624
625 // Check relative pc is set and map name is set.
626 frame.pc = 0x12345679;
627 frame.map = &map;
628 map.name = "MapFake";
629 map.start = 1;
Christopher Ferris20bc65f2013-10-29 20:56:52630#if defined(__LP64__)
Christopher Ferrisabf39bb2014-01-17 19:56:04631 EXPECT_EQ("#01 pc 0000000012345678 MapFake",
Christopher Ferris20bc65f2013-10-29 20:56:52632#else
Christopher Ferrisabf39bb2014-01-17 19:56:04633 EXPECT_EQ("#01 pc 12345678 MapFake",
Christopher Ferris20bc65f2013-10-29 20:56:52634#endif
Christopher Ferrisabf39bb2014-01-17 19:56:04635 backtrace->FormatFrameData(&frame));
Christopher Ferris20bc65f2013-10-29 20:56:52636
Christopher Ferrisabf39bb2014-01-17 19:56:04637 // Check func_name is set, but no func offset.
638 frame.func_name = "ProcFake";
639#if defined(__LP64__)
640 EXPECT_EQ("#01 pc 0000000012345678 MapFake (ProcFake)",
641#else
642 EXPECT_EQ("#01 pc 12345678 MapFake (ProcFake)",
643#endif
644 backtrace->FormatFrameData(&frame));
645
646 // Check func_name is set, and func offset is non-zero.
Christopher Ferris737b6a12014-01-14 02:12:04647 frame.func_offset = 645;
Christopher Ferris20bc65f2013-10-29 20:56:52648#if defined(__LP64__)
Christopher Ferrisabf39bb2014-01-17 19:56:04649 EXPECT_EQ("#01 pc 0000000012345678 MapFake (ProcFake+645)",
Christopher Ferris20bc65f2013-10-29 20:56:52650#else
Christopher Ferrisabf39bb2014-01-17 19:56:04651 EXPECT_EQ("#01 pc 12345678 MapFake (ProcFake+645)",
Christopher Ferris20bc65f2013-10-29 20:56:52652#endif
Christopher Ferrisabf39bb2014-01-17 19:56:04653 backtrace->FormatFrameData(&frame));
Christopher Ferris20bc65f2013-10-29 20:56:52654}