117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris/* 217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * Copyright (C) 2013 The Android Open Source Project 317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * 417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * Licensed under the Apache License, Version 2.0 (the "License"); 517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * you may not use this file except in compliance with the License. 617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * You may obtain a copy of the License at 717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * 817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * http://www.apache.org/licenses/LICENSE-2.0 917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * 1017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * Unless required by applicable law or agreed to in writing, software 1117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * distributed under the License is distributed on an "AS IS" BASIS, 1217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * See the License for the specific language governing permissions and 1417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris * limitations under the License. 1517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris */ 1617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 17ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris#define _GNU_SOURCE 1 1817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <dirent.h> 19684fb77c82affca723910e26e8c219c804e00354Christopher Ferris#include <dlfcn.h> 2017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <errno.h> 21684fb77c82affca723910e26e8c219c804e00354Christopher Ferris#include <fcntl.h> 22e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris#include <inttypes.h> 2317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <pthread.h> 2417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <signal.h> 25e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris#include <stdint.h> 2617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <stdio.h> 2717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <stdlib.h> 2817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <string.h> 2917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <sys/ptrace.h> 30684fb77c82affca723910e26e8c219c804e00354Christopher Ferris#include <sys/stat.h> 3117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <sys/types.h> 3217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <sys/wait.h> 3317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <time.h> 3417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <unistd.h> 3517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 36428fad97a0c9c3def1489b16f0257a9cbcfd43f8Dan Albert#include <algorithm> 37684fb77c82affca723910e26e8c219c804e00354Christopher Ferris#include <list> 38428fad97a0c9c3def1489b16f0257a9cbcfd43f8Dan Albert#include <memory> 39428fad97a0c9c3def1489b16f0257a9cbcfd43f8Dan Albert#include <string> 40428fad97a0c9c3def1489b16f0257a9cbcfd43f8Dan Albert#include <vector> 41428fad97a0c9c3def1489b16f0257a9cbcfd43f8Dan Albert 4220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris#include <backtrace/Backtrace.h> 4346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris#include <backtrace/BacktraceMap.h> 4417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 45684fb77c82affca723910e26e8c219c804e00354Christopher Ferris#include <base/stringprintf.h> 4617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include <cutils/atomic.h> 47428fad97a0c9c3def1489b16f0257a9cbcfd43f8Dan Albert#include <cutils/threads.h> 4817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 49428fad97a0c9c3def1489b16f0257a9cbcfd43f8Dan Albert#include <gtest/gtest.h> 5017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 51428fad97a0c9c3def1489b16f0257a9cbcfd43f8Dan Albert// For the THREAD_SIGNAL definition. 52428fad97a0c9c3def1489b16f0257a9cbcfd43f8Dan Albert#include "BacktraceCurrent.h" 5317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#include "thread_utils.h" 5417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 5517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris// Number of microseconds per milliseconds. 5617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#define US_PER_MSEC 1000 5717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 5817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris// Number of nanoseconds in a second. 5917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#define NS_PER_SEC 1000000000ULL 6017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 6117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris// Number of simultaneous dumping operations to perform. 623cdbfdce6a38cd23968d27d6e9e8d3ee65c3cf98Christopher Ferris#define NUM_THREADS 40 6317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 6417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris// Number of simultaneous threads running in our forked process. 6517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#define NUM_PTRACE_THREADS 5 6617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 6746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferrisstruct thread_t { 6817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pid_t tid; 6917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris int32_t state; 7017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_t threadId; 712b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris void* data; 7246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris}; 7317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 7446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferrisstruct dump_thread_t { 7517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris thread_t thread; 7620303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris Backtrace* backtrace; 7717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris int32_t* now; 7817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris int32_t done; 7946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris}; 8017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 8117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisextern "C" { 8217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris// Prototypes for functions in the test library. 8317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisint test_level_one(int, int, int, int, void (*)(void*), void*); 8417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 8517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisint test_recursive_call(int, void (*)(void*), void*); 8617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 8717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 8817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisuint64_t NanoTime() { 8917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris struct timespec t = { 0, 0 }; 9017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris clock_gettime(CLOCK_MONOTONIC, &t); 9117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return static_cast<uint64_t>(t.tv_sec * NS_PER_SEC + t.tv_nsec); 9217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 9317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 942c43cff01d1271be451671567955158629b23670Christopher Ferrisstd::string DumpFrames(Backtrace* backtrace) { 9520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris if (backtrace->NumFrames() == 0) { 9697e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris return " No frames to dump.\n"; 9720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris } 9820303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris 992c43cff01d1271be451671567955158629b23670Christopher Ferris std::string frame; 10020303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris for (size_t i = 0; i < backtrace->NumFrames(); i++) { 1012c43cff01d1271be451671567955158629b23670Christopher Ferris frame += " " + backtrace->FormatFrameData(i) + '\n'; 10217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 1032c43cff01d1271be451671567955158629b23670Christopher Ferris return frame; 10417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 10517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 10617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid WaitForStop(pid_t pid) { 10717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris uint64_t start = NanoTime(); 10817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 10917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris siginfo_t si; 11017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris while (ptrace(PTRACE_GETSIGINFO, pid, 0, &si) < 0 && (errno == EINTR || errno == ESRCH)) { 11117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if ((NanoTime() - start) > NS_PER_SEC) { 11217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris printf("The process did not get to a stopping point in 1 second.\n"); 11317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris break; 11417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 11517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris usleep(US_PER_MSEC); 11617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 11717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 11817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 11920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferrisbool ReadyLevelBacktrace(Backtrace* backtrace) { 12017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // See if test_level_four is in the backtrace. 12117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris bool found = false; 12246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris for (Backtrace::const_iterator it = backtrace->begin(); it != backtrace->end(); ++it) { 12346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris if (it->func_name == "test_level_four") { 12417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris found = true; 12517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris break; 12617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 12717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 12817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 12917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return found; 13017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 13117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 13220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferrisvoid VerifyLevelDump(Backtrace* backtrace) { 13397e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_GT(backtrace->NumFrames(), static_cast<size_t>(0)) 13497e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris << DumpFrames(backtrace); 13597e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_LT(backtrace->NumFrames(), static_cast<size_t>(MAX_BACKTRACE_FRAMES)) 13697e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris << DumpFrames(backtrace); 13717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 13817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Look through the frames starting at the highest to find the 13917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // frame we want. 14017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris size_t frame_num = 0; 14120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris for (size_t i = backtrace->NumFrames()-1; i > 2; i--) { 14246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris if (backtrace->GetFrame(i)->func_name == "test_level_one") { 14317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris frame_num = i; 14417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris break; 14517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 14617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 1472c43cff01d1271be451671567955158629b23670Christopher Ferris ASSERT_LT(static_cast<size_t>(0), frame_num) << DumpFrames(backtrace); 1482c43cff01d1271be451671567955158629b23670Christopher Ferris ASSERT_LE(static_cast<size_t>(3), frame_num) << DumpFrames(backtrace); 14917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 15097e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_EQ(backtrace->GetFrame(frame_num)->func_name, "test_level_one") 15197e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris << DumpFrames(backtrace); 15297e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_EQ(backtrace->GetFrame(frame_num-1)->func_name, "test_level_two") 15397e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris << DumpFrames(backtrace); 15497e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_EQ(backtrace->GetFrame(frame_num-2)->func_name, "test_level_three") 15597e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris << DumpFrames(backtrace); 15697e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_EQ(backtrace->GetFrame(frame_num-3)->func_name, "test_level_four") 15797e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris << DumpFrames(backtrace); 15817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 15917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 16017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid VerifyLevelBacktrace(void*) { 1612b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> backtrace( 16220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD)); 1632b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 16420303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 16517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 16620303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris VerifyLevelDump(backtrace.get()); 16717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 16817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 16920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferrisbool ReadyMaxBacktrace(Backtrace* backtrace) { 17020303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris return (backtrace->NumFrames() == MAX_BACKTRACE_FRAMES); 17117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 17217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 17320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferrisvoid VerifyMaxDump(Backtrace* backtrace) { 17497e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_EQ(backtrace->NumFrames(), static_cast<size_t>(MAX_BACKTRACE_FRAMES)) 17597e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris << DumpFrames(backtrace); 17617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Verify that the last frame is our recursive call. 17797e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_EQ(backtrace->GetFrame(MAX_BACKTRACE_FRAMES-1)->func_name, "test_recursive_call") 17897e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris << DumpFrames(backtrace); 17917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 18017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 18117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid VerifyMaxBacktrace(void*) { 1822b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> backtrace( 18320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD)); 1842b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 18520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 18617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 18720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris VerifyMaxDump(backtrace.get()); 18817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 18917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 19017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid ThreadSetState(void* data) { 19117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris thread_t* thread = reinterpret_cast<thread_t*>(data); 19217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris android_atomic_acquire_store(1, &thread->state); 19317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris volatile int i = 0; 19417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris while (thread->state) { 19517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris i++; 19617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 19717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 19817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 19920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferrisvoid VerifyThreadTest(pid_t tid, void (*VerifyFunc)(Backtrace*)) { 2002b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), tid)); 2012b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 20220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 20317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 20420303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris VerifyFunc(backtrace.get()); 20517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 20617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 20717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisbool WaitForNonZero(int32_t* value, uint64_t seconds) { 20817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris uint64_t start = NanoTime(); 20917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris do { 21017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (android_atomic_acquire_load(value)) { 21117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return true; 21217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 21317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } while ((NanoTime() - start) < seconds * NS_PER_SEC); 21417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris return false; 21517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 21617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 217ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher FerrisTEST(libbacktrace, local_no_unwind_frames) { 218ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris // Verify that a local unwind does not include any frames within 219ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris // libunwind or libbacktrace. 220ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), getpid())); 22197e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 222ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 223ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris 224ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris ASSERT_TRUE(backtrace->NumFrames() != 0); 225ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris for (const auto& frame : *backtrace ) { 226ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris if (BacktraceMap::IsValid(frame.map)) { 227ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris const std::string name = basename(frame.map.name.c_str()); 228ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris ASSERT_TRUE(name != "libunwind.so" && name != "libbacktrace.so") 229ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris << DumpFrames(backtrace.get()); 230ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris } 231ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris break; 232ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris } 233ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris} 234ca09ce902c17c2bffc02bfafaf0844204ac13333Christopher Ferris 23517e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, local_trace) { 2362b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelBacktrace, nullptr), 0); 23717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 23817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 23917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid VerifyIgnoreFrames( 24020303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris Backtrace* bt_all, Backtrace* bt_ign1, 24120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris Backtrace* bt_ign2, const char* cur_proc) { 24297e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris EXPECT_EQ(bt_all->NumFrames(), bt_ign1->NumFrames() + 1) 24397e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris << "All backtrace:\n" << DumpFrames(bt_all) << "Ignore 1 backtrace:\n" << DumpFrames(bt_ign1); 24497e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris EXPECT_EQ(bt_all->NumFrames(), bt_ign2->NumFrames() + 2) 24597e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris << "All backtrace:\n" << DumpFrames(bt_all) << "Ignore 2 backtrace:\n" << DumpFrames(bt_ign2); 24617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 24717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Check all of the frames are the same > the current frame. 2482b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris bool check = (cur_proc == nullptr); 24920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris for (size_t i = 0; i < bt_ign2->NumFrames(); i++) { 25017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (check) { 25120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris EXPECT_EQ(bt_ign2->GetFrame(i)->pc, bt_ign1->GetFrame(i+1)->pc); 25220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris EXPECT_EQ(bt_ign2->GetFrame(i)->sp, bt_ign1->GetFrame(i+1)->sp); 25320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris EXPECT_EQ(bt_ign2->GetFrame(i)->stack_size, bt_ign1->GetFrame(i+1)->stack_size); 25417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 25520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris EXPECT_EQ(bt_ign2->GetFrame(i)->pc, bt_all->GetFrame(i+2)->pc); 25620303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris EXPECT_EQ(bt_ign2->GetFrame(i)->sp, bt_all->GetFrame(i+2)->sp); 25720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris EXPECT_EQ(bt_ign2->GetFrame(i)->stack_size, bt_all->GetFrame(i+2)->stack_size); 25817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 25946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris if (!check && bt_ign2->GetFrame(i)->func_name == cur_proc) { 26017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris check = true; 26117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 26217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 26317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 26417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 26517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid VerifyLevelIgnoreFrames(void*) { 2662b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> all( 26720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD)); 2682b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(all.get() != nullptr); 26920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(all->Unwind(0)); 27017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 2712b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> ign1( 27220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD)); 2732b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(ign1.get() != nullptr); 27420303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(ign1->Unwind(1)); 27517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 2762b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> ign2( 27720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD)); 2782b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(ign2.get() != nullptr); 27920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(ign2->Unwind(2)); 28017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 28120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris VerifyIgnoreFrames(all.get(), ign1.get(), ign2.get(), "VerifyLevelIgnoreFrames"); 28217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 28317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 28417e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, local_trace_ignore_frames) { 2852b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelIgnoreFrames, nullptr), 0); 28617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 28717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 28817e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, local_max_trace) { 2892b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, VerifyMaxBacktrace, nullptr), 0); 29017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 29117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 292df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferrisvoid VerifyProcTest(pid_t pid, pid_t tid, bool share_map, 29320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris bool (*ReadyFunc)(Backtrace*), 29420303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris void (*VerifyFunc)(Backtrace*)) { 29517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pid_t ptrace_tid; 29617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (tid < 0) { 29717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ptrace_tid = pid; 29817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } else { 29917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ptrace_tid = tid; 30017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 30117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris uint64_t start = NanoTime(); 30217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris bool verified = false; 30397e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris std::string last_dump; 30417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris do { 30517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris usleep(US_PER_MSEC); 30617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (ptrace(PTRACE_ATTACH, ptrace_tid, 0, 0) == 0) { 30717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Wait for the process to get to a stopping point. 30817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris WaitForStop(ptrace_tid); 30917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 3102b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<BacktraceMap> map; 311df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris if (share_map) { 312df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris map.reset(BacktraceMap::Create(pid)); 313df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris } 3142b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map.get())); 3152b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 31697e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 31720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris if (ReadyFunc(backtrace.get())) { 31820303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris VerifyFunc(backtrace.get()); 31917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris verified = true; 32097e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris } else { 32197e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris last_dump = DumpFrames(backtrace.get()); 32217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 32320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris 32417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_TRUE(ptrace(PTRACE_DETACH, ptrace_tid, 0, 0) == 0); 32517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 32617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // If 5 seconds have passed, then we are done. 32717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } while (!verified && (NanoTime() - start) <= 5 * NS_PER_SEC); 32897e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_TRUE(verified) << "Last backtrace:\n" << last_dump; 32917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 33017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 33117e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, ptrace_trace) { 33217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pid_t pid; 33317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if ((pid = fork()) == 0) { 3342b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0); 335e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris _exit(1); 33617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 337df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, false, ReadyLevelBacktrace, VerifyLevelDump); 338df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris 339df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris kill(pid, SIGKILL); 340df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris int status; 341df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris ASSERT_EQ(waitpid(pid, &status, 0), pid); 342df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris} 343df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris 344df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher FerrisTEST(libbacktrace, ptrace_trace_shared_map) { 345df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris pid_t pid; 346df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris if ((pid = fork()) == 0) { 3472b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0); 348e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris _exit(1); 349df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris } 350df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris 351df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, true, ReadyLevelBacktrace, VerifyLevelDump); 35217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 35317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris kill(pid, SIGKILL); 35417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris int status; 35517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_EQ(waitpid(pid, &status, 0), pid); 35617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 35717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 35817e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, ptrace_max_trace) { 35917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pid_t pid; 36017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if ((pid = fork()) == 0) { 3612b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, nullptr, nullptr), 0); 362e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris _exit(1); 36317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 364df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, false, ReadyMaxBacktrace, VerifyMaxDump); 36517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 36617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris kill(pid, SIGKILL); 36717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris int status; 36817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_EQ(waitpid(pid, &status, 0), pid); 36917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 37017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 37120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferrisvoid VerifyProcessIgnoreFrames(Backtrace* bt_all) { 3722b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> ign1(Backtrace::Create(bt_all->Pid(), BACKTRACE_CURRENT_THREAD)); 3732b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(ign1.get() != nullptr); 37420303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(ign1->Unwind(1)); 37517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 3762b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> ign2(Backtrace::Create(bt_all->Pid(), BACKTRACE_CURRENT_THREAD)); 3772b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(ign2.get() != nullptr); 37820303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(ign2->Unwind(2)); 37917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 3802b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris VerifyIgnoreFrames(bt_all, ign1.get(), ign2.get(), nullptr); 38117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 38217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 38317e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, ptrace_ignore_frames) { 38417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pid_t pid; 38517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if ((pid = fork()) == 0) { 3862b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0); 387e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris _exit(1); 38817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 389df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris VerifyProcTest(pid, BACKTRACE_CURRENT_THREAD, false, ReadyLevelBacktrace, VerifyProcessIgnoreFrames); 39017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 39117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris kill(pid, SIGKILL); 39217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris int status; 39317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_EQ(waitpid(pid, &status, 0), pid); 39417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 39517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 39617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris// Create a process with multiple threads and dump all of the threads. 39717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid* PtraceThreadLevelRun(void*) { 3982b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris EXPECT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0); 3992b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris return nullptr; 40017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 40117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 40217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid GetThreads(pid_t pid, std::vector<pid_t>* threads) { 40317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Get the list of tasks. 40417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris char task_path[128]; 40517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid); 40617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 40717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris DIR* tasks_dir = opendir(task_path); 4082b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(tasks_dir != nullptr); 40917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris struct dirent* entry; 4102b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris while ((entry = readdir(tasks_dir)) != nullptr) { 41117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris char* end; 41217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pid_t tid = strtoul(entry->d_name, &end, 10); 41317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (*end == '\0') { 41417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris threads->push_back(tid); 41517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 41617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 41717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris closedir(tasks_dir); 41817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 41917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 42017e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, ptrace_threads) { 42117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pid_t pid; 42217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if ((pid = fork()) == 0) { 42317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris for (size_t i = 0; i < NUM_PTRACE_THREADS; i++) { 42417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_t attr; 42517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_init(&attr); 42617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 42717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 42817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_t thread; 4292b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(pthread_create(&thread, &attr, PtraceThreadLevelRun, nullptr) == 0); 43017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 4312b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_NE(test_level_one(1, 2, 3, 4, nullptr, nullptr), 0); 432e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris _exit(1); 43317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 43417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 43517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Check to see that all of the threads are running before unwinding. 43617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris std::vector<pid_t> threads; 43717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris uint64_t start = NanoTime(); 43817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris do { 43917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris usleep(US_PER_MSEC); 44017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris threads.clear(); 44117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris GetThreads(pid, &threads); 44217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } while ((threads.size() != NUM_PTRACE_THREADS + 1) && 44317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ((NanoTime() - start) <= 5 * NS_PER_SEC)); 44417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_EQ(threads.size(), static_cast<size_t>(NUM_PTRACE_THREADS + 1)); 44517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 44617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0); 44717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris WaitForStop(pid); 44817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris for (std::vector<int>::const_iterator it = threads.begin(); it != threads.end(); ++it) { 44917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Skip the current forked process, we only care about the threads. 45017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (pid == *it) { 45117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris continue; 45217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 453df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris VerifyProcTest(pid, *it, false, ReadyLevelBacktrace, VerifyLevelDump); 45417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 45517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0); 45617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 45717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris kill(pid, SIGKILL); 45817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris int status; 45917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_EQ(waitpid(pid, &status, 0), pid); 46017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 46117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 46217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid VerifyLevelThread(void*) { 4632b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), gettid())); 4642b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 46520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 46617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 46720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris VerifyLevelDump(backtrace.get()); 46817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 46917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 47017e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, thread_current_level) { 4712b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_NE(test_level_one(1, 2, 3, 4, VerifyLevelThread, nullptr), 0); 47217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 47317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 47417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid VerifyMaxThread(void*) { 4752b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), gettid())); 4762b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 47720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 47817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 47920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris VerifyMaxDump(backtrace.get()); 48017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 48117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 48217e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, thread_current_max) { 4832b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, VerifyMaxThread, nullptr), 0); 48417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 48517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 48617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid* ThreadLevelRun(void* data) { 48717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris thread_t* thread = reinterpret_cast<thread_t*>(data); 48817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 48917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris thread->tid = gettid(); 49017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris EXPECT_NE(test_level_one(1, 2, 3, 4, ThreadSetState, data), 0); 4912b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris return nullptr; 49217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 49317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 49417e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, thread_level_trace) { 49517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_t attr; 49617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_init(&attr); 49717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 49817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 4992b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris thread_t thread_data = { 0, 0, 0, nullptr }; 50017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_t thread; 50117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0); 50217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 50317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Wait up to 2 seconds for the tid to be set. 50417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2)); 50517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 506aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris // Make sure that the thread signal used is not visible when compiled for 507aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris // the target. 508aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris#if !defined(__GLIBC__) 509aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris ASSERT_LT(THREAD_SIGNAL, SIGRTMIN); 510aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris#endif 511aa63d9f980f95718fc28ca7e222c1e8d7ca9e778Christopher Ferris 51217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Save the current signal action and make sure it is restored afterwards. 51317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris struct sigaction cur_action; 5142b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(sigaction(THREAD_SIGNAL, nullptr, &cur_action) == 0); 51517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 5162b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid)); 5172b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 51820303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 51917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 52020303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris VerifyLevelDump(backtrace.get()); 52117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 52217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Tell the thread to exit its infinite loop. 52317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris android_atomic_acquire_store(0, &thread_data.state); 52417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 52517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Verify that the old action was restored. 52617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris struct sigaction new_action; 5272b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(sigaction(THREAD_SIGNAL, nullptr, &new_action) == 0); 52817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris EXPECT_EQ(cur_action.sa_sigaction, new_action.sa_sigaction); 5293cdbfdce6a38cd23968d27d6e9e8d3ee65c3cf98Christopher Ferris // The SA_RESTORER flag gets set behind our back, so a direct comparison 5303cdbfdce6a38cd23968d27d6e9e8d3ee65c3cf98Christopher Ferris // doesn't work unless we mask the value off. Mips doesn't have this 5313cdbfdce6a38cd23968d27d6e9e8d3ee65c3cf98Christopher Ferris // flag, so skip this on that platform. 5322c43cff01d1271be451671567955158629b23670Christopher Ferris#if defined(SA_RESTORER) 5333cdbfdce6a38cd23968d27d6e9e8d3ee65c3cf98Christopher Ferris cur_action.sa_flags &= ~SA_RESTORER; 5343cdbfdce6a38cd23968d27d6e9e8d3ee65c3cf98Christopher Ferris new_action.sa_flags &= ~SA_RESTORER; 5352c43cff01d1271be451671567955158629b23670Christopher Ferris#elif defined(__GLIBC__) 5362c43cff01d1271be451671567955158629b23670Christopher Ferris // Our host compiler doesn't appear to define this flag for some reason. 5372c43cff01d1271be451671567955158629b23670Christopher Ferris cur_action.sa_flags &= ~0x04000000; 5382c43cff01d1271be451671567955158629b23670Christopher Ferris new_action.sa_flags &= ~0x04000000; 5393cdbfdce6a38cd23968d27d6e9e8d3ee65c3cf98Christopher Ferris#endif 54017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris EXPECT_EQ(cur_action.sa_flags, new_action.sa_flags); 54117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 54217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 54317e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, thread_ignore_frames) { 54417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_t attr; 54517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_init(&attr); 54617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 54717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 5482b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris thread_t thread_data = { 0, 0, 0, nullptr }; 54917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_t thread; 55017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0); 55117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 55217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Wait up to 2 seconds for the tid to be set. 55317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2)); 55417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 5552b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> all(Backtrace::Create(getpid(), thread_data.tid)); 5562b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(all.get() != nullptr); 55720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(all->Unwind(0)); 55817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 5592b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> ign1(Backtrace::Create(getpid(), thread_data.tid)); 5602b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(ign1.get() != nullptr); 56120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(ign1->Unwind(1)); 56217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 5632b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> ign2(Backtrace::Create(getpid(), thread_data.tid)); 5642b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(ign2.get() != nullptr); 56520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(ign2->Unwind(2)); 56617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 5672b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris VerifyIgnoreFrames(all.get(), ign1.get(), ign2.get(), nullptr); 56817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 56917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Tell the thread to exit its infinite loop. 57017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris android_atomic_acquire_store(0, &thread_data.state); 57117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 57217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 57317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid* ThreadMaxRun(void* data) { 57417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris thread_t* thread = reinterpret_cast<thread_t*>(data); 57517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 57617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris thread->tid = gettid(); 57717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris EXPECT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, ThreadSetState, data), 0); 5782b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris return nullptr; 57917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 58017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 58117e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, thread_max_trace) { 58217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_t attr; 58317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_init(&attr); 58417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 58517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 5862b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris thread_t thread_data = { 0, 0, 0, nullptr }; 58717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_t thread; 58817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_TRUE(pthread_create(&thread, &attr, ThreadMaxRun, &thread_data) == 0); 58917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 59017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Wait for the tid to be set. 59117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2)); 59217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 5932b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid)); 5942b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 59520303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 59617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 59720303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris VerifyMaxDump(backtrace.get()); 59817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 59917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Tell the thread to exit its infinite loop. 60017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris android_atomic_acquire_store(0, &thread_data.state); 60117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 60217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 60317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferrisvoid* ThreadDump(void* data) { 60417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris dump_thread_t* dump = reinterpret_cast<dump_thread_t*>(data); 60517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris while (true) { 60617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris if (android_atomic_acquire_load(dump->now)) { 60717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris break; 60817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 60917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 61017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 61117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // The status of the actual unwind will be checked elsewhere. 61220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris dump->backtrace = Backtrace::Create(getpid(), dump->thread.tid); 61320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris dump->backtrace->Unwind(0); 61417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 61517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris android_atomic_acquire_store(1, &dump->done); 61617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 6172b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris return nullptr; 61817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 61917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 62017e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, thread_multiple_dump) { 62117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Dump NUM_THREADS simultaneously. 62217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris std::vector<thread_t> runners(NUM_THREADS); 62317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris std::vector<dump_thread_t> dumpers(NUM_THREADS); 62417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 62517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_t attr; 62617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_init(&attr); 62717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 62817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris for (size_t i = 0; i < NUM_THREADS; i++) { 62917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Launch the runners, they will spin in hard loops doing nothing. 63017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris runners[i].tid = 0; 63117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris runners[i].state = 0; 63217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_TRUE(pthread_create(&runners[i].threadId, &attr, ThreadMaxRun, &runners[i]) == 0); 63317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 63417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 63517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Wait for tids to be set. 63617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris for (std::vector<thread_t>::iterator it = runners.begin(); it != runners.end(); ++it) { 6373cdbfdce6a38cd23968d27d6e9e8d3ee65c3cf98Christopher Ferris ASSERT_TRUE(WaitForNonZero(&it->state, 30)); 63817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 63917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 64017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Start all of the dumpers at once, they will spin until they are signalled 64117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // to begin their dump run. 64217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris int32_t dump_now = 0; 64317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris for (size_t i = 0; i < NUM_THREADS; i++) { 64417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris dumpers[i].thread.tid = runners[i].tid; 64517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris dumpers[i].thread.state = 0; 64617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris dumpers[i].done = 0; 64717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris dumpers[i].now = &dump_now; 64817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 64917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0); 65017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 65117e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 65217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Start all of the dumpers going at once. 65317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris android_atomic_acquire_store(1, &dump_now); 65417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 65517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris for (size_t i = 0; i < NUM_THREADS; i++) { 6563cdbfdce6a38cd23968d27d6e9e8d3ee65c3cf98Christopher Ferris ASSERT_TRUE(WaitForNonZero(&dumpers[i].done, 30)); 65717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 65817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris // Tell the runner thread to exit its infinite loop. 65917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris android_atomic_acquire_store(0, &runners[i].state); 66017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 6612b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(dumpers[i].backtrace != nullptr); 66220303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris VerifyMaxDump(dumpers[i].backtrace); 66320303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris 66420303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris delete dumpers[i].backtrace; 6652b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris dumpers[i].backtrace = nullptr; 66617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris } 66717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 66817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 669a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher FerrisTEST(libbacktrace, thread_multiple_dump_same_thread) { 670a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_attr_t attr; 671a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_attr_init(&attr); 672a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 673a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris thread_t runner; 674a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris runner.tid = 0; 675a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris runner.state = 0; 676a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ASSERT_TRUE(pthread_create(&runner.threadId, &attr, ThreadMaxRun, &runner) == 0); 677a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 678a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Wait for tids to be set. 6793cdbfdce6a38cd23968d27d6e9e8d3ee65c3cf98Christopher Ferris ASSERT_TRUE(WaitForNonZero(&runner.state, 30)); 680a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 681a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Start all of the dumpers at once, they will spin until they are signalled 682a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // to begin their dump run. 683a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris int32_t dump_now = 0; 684a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Dump the same thread NUM_THREADS simultaneously. 685a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris std::vector<dump_thread_t> dumpers(NUM_THREADS); 686a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris for (size_t i = 0; i < NUM_THREADS; i++) { 687a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris dumpers[i].thread.tid = runner.tid; 688a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris dumpers[i].thread.state = 0; 689a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris dumpers[i].done = 0; 690a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris dumpers[i].now = &dump_now; 691a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 692a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0); 693a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris } 694a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 695a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Start all of the dumpers going at once. 696a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris android_atomic_acquire_store(1, &dump_now); 697a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 698a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris for (size_t i = 0; i < NUM_THREADS; i++) { 6993cdbfdce6a38cd23968d27d6e9e8d3ee65c3cf98Christopher Ferris ASSERT_TRUE(WaitForNonZero(&dumpers[i].done, 30)); 700a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 7012b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(dumpers[i].backtrace != nullptr); 702a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris VerifyMaxDump(dumpers[i].backtrace); 703a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 704a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris delete dumpers[i].backtrace; 7052b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris dumpers[i].backtrace = nullptr; 706a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris } 707a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 708a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris // Tell the runner thread to exit its infinite loop. 709a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris android_atomic_acquire_store(0, &runner.state); 710a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris} 711a2efd3ac7abe223aa7a8ba8b5ba448216c4953b4Christopher Ferris 712df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris// This test is for UnwindMaps that should share the same map cursor when 713df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris// multiple maps are created for the current process at the same time. 714df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher FerrisTEST(libbacktrace, simultaneous_maps) { 715df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris BacktraceMap* map1 = BacktraceMap::Create(getpid()); 716df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris BacktraceMap* map2 = BacktraceMap::Create(getpid()); 717df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris BacktraceMap* map3 = BacktraceMap::Create(getpid()); 718df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris 719df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris Backtrace* back1 = Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD, map1); 72097e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_TRUE(back1 != nullptr); 721df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris EXPECT_TRUE(back1->Unwind(0)); 722df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris delete back1; 723df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris delete map1; 724df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris 725df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris Backtrace* back2 = Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD, map2); 72697e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_TRUE(back2 != nullptr); 727df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris EXPECT_TRUE(back2->Unwind(0)); 728df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris delete back2; 729df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris delete map2; 730df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris 731df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris Backtrace* back3 = Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD, map3); 73297e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_TRUE(back3 != nullptr); 733df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris EXPECT_TRUE(back3->Unwind(0)); 734df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris delete back3; 735df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris delete map3; 736df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris} 737df2906186b6952c57b1f662bfef0b65c9f8c2e0dChristopher Ferris 73812385e3ad085aa1ac06c26529b32b688503a9fcfChristopher FerrisTEST(libbacktrace, fillin_erases) { 73912385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris BacktraceMap* back_map = BacktraceMap::Create(getpid()); 74012385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris 74112385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris backtrace_map_t map; 74212385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris 74312385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris map.start = 1; 74412385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris map.end = 3; 74512385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris map.flags = 1; 74612385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris map.name = "Initialized"; 74712385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris back_map->FillIn(0, &map); 74812385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris delete back_map; 74912385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris 75012385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris ASSERT_FALSE(BacktraceMap::IsValid(map)); 75112385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris ASSERT_EQ(static_cast<uintptr_t>(0), map.start); 75212385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris ASSERT_EQ(static_cast<uintptr_t>(0), map.end); 75312385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris ASSERT_EQ(0, map.flags); 75412385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris ASSERT_EQ("", map.name); 75512385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris} 75612385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris 75717e91d44edf5e6476a477a200bcd89d4327358a3Christopher FerrisTEST(libbacktrace, format_test) { 7582b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD)); 7592b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 76017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 76120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris backtrace_frame_data_t frame; 76246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris frame.num = 1; 76346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris frame.pc = 2; 76446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris frame.sp = 0; 76546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris frame.stack_size = 0; 76646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris frame.func_offset = 0; 76717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 76846756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris // Check no map set. 76920303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris frame.num = 1; 77017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#if defined(__LP64__) 77146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris EXPECT_EQ("#01 pc 0000000000000002 <unknown>", 77246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris#else 77346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris EXPECT_EQ("#01 pc 00000002 <unknown>", 77446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris#endif 77546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris backtrace->FormatFrameData(&frame)); 77646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 77746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris // Check map name empty, but exists. 77812385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris frame.map.start = 1; 77912385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris frame.map.end = 1; 780329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris frame.map.load_base = 0; 78146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris#if defined(__LP64__) 78246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris EXPECT_EQ("#01 pc 0000000000000001 <unknown>", 78317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#else 78446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris EXPECT_EQ("#01 pc 00000001 <unknown>", 78517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#endif 78646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris backtrace->FormatFrameData(&frame)); 78746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris 78817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 78946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris // Check relative pc is set and map name is set. 79046756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris frame.pc = 0x12345679; 79112385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris frame.map.name = "MapFake"; 79212385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris frame.map.start = 1; 79312385e3ad085aa1ac06c26529b32b688503a9fcfChristopher Ferris frame.map.end = 1; 79417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#if defined(__LP64__) 79546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris EXPECT_EQ("#01 pc 0000000012345678 MapFake", 79617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#else 79746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris EXPECT_EQ("#01 pc 12345678 MapFake", 79817e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#endif 79946756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris backtrace->FormatFrameData(&frame)); 80017e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 80146756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris // Check func_name is set, but no func offset. 80246756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris frame.func_name = "ProcFake"; 80317e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#if defined(__LP64__) 80446756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris EXPECT_EQ("#01 pc 0000000012345678 MapFake (ProcFake)", 80517e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#else 80646756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris EXPECT_EQ("#01 pc 12345678 MapFake (ProcFake)", 80717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#endif 80846756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris backtrace->FormatFrameData(&frame)); 80917e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris 81046756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris // Check func_name is set, and func offset is non-zero. 81120303f856f1f1cdb5af58af0b116b8c598f0ea5cChristopher Ferris frame.func_offset = 645; 81217e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#if defined(__LP64__) 81346756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris EXPECT_EQ("#01 pc 0000000012345678 MapFake (ProcFake+645)", 81417e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#else 81546756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris EXPECT_EQ("#01 pc 12345678 MapFake (ProcFake+645)", 81617e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris#endif 81746756821c4fe238f12a6e5ea18c356398f8d8795Christopher Ferris backtrace->FormatFrameData(&frame)); 818329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris 819329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris // Check func_name is set, func offset is non-zero, and load_base is non-zero. 820329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris frame.func_offset = 645; 821329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris frame.map.load_base = 100; 822329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris#if defined(__LP64__) 823329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris EXPECT_EQ("#01 pc 00000000123456dc MapFake (ProcFake+645)", 824329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris#else 825329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris EXPECT_EQ("#01 pc 123456dc MapFake (ProcFake+645)", 826329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris#endif 827329ed7dae49eba09bdf865dd999d1a7e73bb9687Christopher Ferris backtrace->FormatFrameData(&frame)); 828e0ab23223a1c3110c9550136b8a119b4c30ec066Christopher Ferris 829e0ab23223a1c3110c9550136b8a119b4c30ec066Christopher Ferris // Check a non-zero map offset. 830e0ab23223a1c3110c9550136b8a119b4c30ec066Christopher Ferris frame.map.offset = 0x1000; 831e0ab23223a1c3110c9550136b8a119b4c30ec066Christopher Ferris#if defined(__LP64__) 832e0ab23223a1c3110c9550136b8a119b4c30ec066Christopher Ferris EXPECT_EQ("#01 pc 00000000123456dc MapFake (offset 0x1000) (ProcFake+645)", 833e0ab23223a1c3110c9550136b8a119b4c30ec066Christopher Ferris#else 834e0ab23223a1c3110c9550136b8a119b4c30ec066Christopher Ferris EXPECT_EQ("#01 pc 123456dc MapFake (offset 0x1000) (ProcFake+645)", 835e0ab23223a1c3110c9550136b8a119b4c30ec066Christopher Ferris#endif 836e0ab23223a1c3110c9550136b8a119b4c30ec066Christopher Ferris backtrace->FormatFrameData(&frame)); 83717e91d44edf5e6476a477a200bcd89d4327358a3Christopher Ferris} 838e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 839e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferrisstruct map_test_t { 840e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris uintptr_t start; 841e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris uintptr_t end; 842e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris}; 843e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 844e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferrisbool map_sort(map_test_t i, map_test_t j) { 845e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris return i.start < j.start; 846e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris} 847e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 8482b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferrisvoid VerifyMap(pid_t pid) { 849e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris char buffer[4096]; 850e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris snprintf(buffer, sizeof(buffer), "/proc/%d/maps", pid); 851e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 852e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris FILE* map_file = fopen(buffer, "r"); 8532b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(map_file != nullptr); 854e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris std::vector<map_test_t> test_maps; 855e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris while (fgets(buffer, sizeof(buffer), map_file)) { 856e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris map_test_t map; 857e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_EQ(2, sscanf(buffer, "%" SCNxPTR "-%" SCNxPTR " ", &map.start, &map.end)); 858e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris test_maps.push_back(map); 859e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris } 860e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris fclose(map_file); 861e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris std::sort(test_maps.begin(), test_maps.end(), map_sort); 862e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 8632b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(pid)); 864e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 865e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris // Basic test that verifies that the map is in the expected order. 866e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris std::vector<map_test_t>::const_iterator test_it = test_maps.begin(); 867e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) { 868e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_TRUE(test_it != test_maps.end()); 869e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_EQ(test_it->start, it->start); 870e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_EQ(test_it->end, it->end); 871e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ++test_it; 872e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris } 873e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_TRUE(test_it == test_maps.end()); 874e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris} 875e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 876e29609106033a48a6128664668d22bf4fb42a7eeChristopher FerrisTEST(libbacktrace, verify_map_remote) { 877e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris pid_t pid; 878e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 879e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris if ((pid = fork()) == 0) { 880e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris while (true) { 881e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris } 882e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris _exit(0); 883e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris } 884e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_LT(0, pid); 885e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 886e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0); 887e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 888e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris // Wait for the process to get to a stopping point. 889e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris WaitForStop(pid); 890e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 891e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris // The maps should match exactly since the forked process has been paused. 892e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris VerifyMap(pid); 893e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 894e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0); 895e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 896e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris kill(pid, SIGKILL); 8972b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_EQ(waitpid(pid, nullptr, 0), pid); 8982b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris} 8992b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9008bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferrisvoid InitMemory(uint8_t* memory, size_t bytes) { 9018bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris for (size_t i = 0; i < bytes; i++) { 9028bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris memory[i] = i; 9038bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris if (memory[i] == '\0') { 9048bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris // Don't use '\0' in our data so we can verify that an overread doesn't 9058bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris // occur by using a '\0' as the character after the read data. 9068bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris memory[i] = 23; 9078bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris } 9088bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris } 9098bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris} 9108bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris 9112b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferrisvoid* ThreadReadTest(void* data) { 9122b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris thread_t* thread_data = reinterpret_cast<thread_t*>(data); 9132b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9142b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris thread_data->tid = gettid(); 9152b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9162b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris // Create two map pages. 9172b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris // Mark the second page as not-readable. 9182b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris size_t pagesize = static_cast<size_t>(sysconf(_SC_PAGE_SIZE)); 9192b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris uint8_t* memory; 9202b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris if (posix_memalign(reinterpret_cast<void**>(&memory), pagesize, 2 * pagesize) != 0) { 9212b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris return reinterpret_cast<void*>(-1); 9222b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 9232b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9242b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris if (mprotect(&memory[pagesize], pagesize, PROT_NONE) != 0) { 9252b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris return reinterpret_cast<void*>(-1); 9262b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 9272b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9282b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris // Set up a simple pattern in memory. 9298bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris InitMemory(memory, pagesize); 9302b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9312b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris thread_data->data = memory; 9322b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9332b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris // Tell the caller it's okay to start reading memory. 9342b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris android_atomic_acquire_store(1, &thread_data->state); 9352b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9362c43cff01d1271be451671567955158629b23670Christopher Ferris // Loop waiting for the caller to finish reading the memory. 9372b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris while (thread_data->state) { 9382b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 9392b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9402c43cff01d1271be451671567955158629b23670Christopher Ferris // Re-enable read-write on the page so that we don't crash if we try 9412c43cff01d1271be451671567955158629b23670Christopher Ferris // and access data on this page when freeing the memory. 9422c43cff01d1271be451671567955158629b23670Christopher Ferris if (mprotect(&memory[pagesize], pagesize, PROT_READ | PROT_WRITE) != 0) { 9432c43cff01d1271be451671567955158629b23670Christopher Ferris return reinterpret_cast<void*>(-1); 9442c43cff01d1271be451671567955158629b23670Christopher Ferris } 9452b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris free(memory); 9462b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9472b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris android_atomic_acquire_store(1, &thread_data->state); 9482b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9492b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris return nullptr; 9502b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris} 9512b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9522b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferrisvoid RunReadTest(Backtrace* backtrace, uintptr_t read_addr) { 9532b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris size_t pagesize = static_cast<size_t>(sysconf(_SC_PAGE_SIZE)); 9542b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9552b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris // Create a page of data to use to do quick compares. 9562b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris uint8_t* expected = new uint8_t[pagesize]; 9578bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris InitMemory(expected, pagesize); 9588bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris 9592b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris uint8_t* data = new uint8_t[2*pagesize]; 9602b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris // Verify that we can only read one page worth of data. 9612b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris size_t bytes_read = backtrace->Read(read_addr, data, 2 * pagesize); 9622b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_EQ(pagesize, bytes_read); 9632b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(memcmp(data, expected, pagesize) == 0); 9642b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9652b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris // Verify unaligned reads. 9662b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris for (size_t i = 1; i < sizeof(word_t); i++) { 9672b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris bytes_read = backtrace->Read(read_addr + i, data, 2 * sizeof(word_t)); 9682b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_EQ(2 * sizeof(word_t), bytes_read); 9692b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(memcmp(data, &expected[i], 2 * sizeof(word_t)) == 0) 9702b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris << "Offset at " << i << " failed"; 9712b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 9728bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris 9738bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris // Verify small unaligned reads. 9748bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris for (size_t i = 1; i < sizeof(word_t); i++) { 9758bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris for (size_t j = 1; j < sizeof(word_t); j++) { 9768bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris // Set one byte past what we expect to read, to guarantee we don't overread. 9778bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris data[j] = '\0'; 9788bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris bytes_read = backtrace->Read(read_addr + i, data, j); 9798bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris ASSERT_EQ(j, bytes_read); 9808bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris ASSERT_TRUE(memcmp(data, &expected[i], j) == 0) 9818bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris << "Offset at " << i << " length " << j << " miscompared"; 9828bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris ASSERT_EQ('\0', data[j]) 9838bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris << "Offset at " << i << " length " << j << " wrote too much data"; 9848bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris } 9858bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris } 9862b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris delete data; 9872b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris delete expected; 9882b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris} 9892b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9902b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher FerrisTEST(libbacktrace, thread_read) { 9912b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris pthread_attr_t attr; 9922b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris pthread_attr_init(&attr); 9932b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 9942b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris pthread_t thread; 9952b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris thread_t thread_data = { 0, 0, 0, nullptr }; 9962b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(pthread_create(&thread, &attr, ThreadReadTest, &thread_data) == 0); 9972b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 9982b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(WaitForNonZero(&thread_data.state, 10)); 9992b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10002b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid)); 10012b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 10022b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10032b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris RunReadTest(backtrace.get(), reinterpret_cast<uintptr_t>(thread_data.data)); 10042b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10052b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris android_atomic_acquire_store(0, &thread_data.state); 10062b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10072b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(WaitForNonZero(&thread_data.state, 10)); 10082b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris} 10092b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10102b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferrisvolatile uintptr_t g_ready = 0; 10112b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferrisvolatile uintptr_t g_addr = 0; 10122b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10132b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferrisvoid ForkedReadTest() { 10142b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris // Create two map pages. 10152b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris size_t pagesize = static_cast<size_t>(sysconf(_SC_PAGE_SIZE)); 10162b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris uint8_t* memory; 10172b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris if (posix_memalign(reinterpret_cast<void**>(&memory), pagesize, 2 * pagesize) != 0) { 10182b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris perror("Failed to allocate memory\n"); 10192b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris exit(1); 10202b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 10212b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10222b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris // Mark the second page as not-readable. 10232b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris if (mprotect(&memory[pagesize], pagesize, PROT_NONE) != 0) { 10242b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris perror("Failed to mprotect memory\n"); 10252b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris exit(1); 10262b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 10272b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10282b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris // Set up a simple pattern in memory. 10298bd4a4ecdc48ead03ca4e90ad585324bcd63b9f0Christopher Ferris InitMemory(memory, pagesize); 10302b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10312b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris g_addr = reinterpret_cast<uintptr_t>(memory); 10322b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris g_ready = 1; 10332b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10342b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris while (1) { 10352b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris usleep(US_PER_MSEC); 10362b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 10372b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris} 10382b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10392b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher FerrisTEST(libbacktrace, process_read) { 1040684fb77c82affca723910e26e8c219c804e00354Christopher Ferris g_ready = 0; 10412b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris pid_t pid; 10422b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris if ((pid = fork()) == 0) { 10432b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ForkedReadTest(); 10442b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris exit(0); 10452b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 10462b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_NE(-1, pid); 10472b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10482b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris bool test_executed = false; 10492b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris uint64_t start = NanoTime(); 10502b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris while (1) { 10512b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris if (ptrace(PTRACE_ATTACH, pid, 0, 0) == 0) { 10522b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris WaitForStop(pid); 10532b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10542b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, pid)); 105597e00bb25a016edfd0c7efce90c81d63a357b2e3Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 10562b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10572b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris uintptr_t read_addr; 10582b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris size_t bytes_read = backtrace->Read(reinterpret_cast<uintptr_t>(&g_ready), 10592b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris reinterpret_cast<uint8_t*>(&read_addr), 10602b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris sizeof(uintptr_t)); 10612b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_EQ(sizeof(uintptr_t), bytes_read); 10622b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris if (read_addr) { 10632b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris // The forked process is ready to be read. 10642b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris bytes_read = backtrace->Read(reinterpret_cast<uintptr_t>(&g_addr), 10652b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris reinterpret_cast<uint8_t*>(&read_addr), 10662b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris sizeof(uintptr_t)); 10672b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_EQ(sizeof(uintptr_t), bytes_read); 10682b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10692b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris RunReadTest(backtrace.get(), read_addr); 10702b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10712b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris test_executed = true; 10722b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris break; 10732b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 10742b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0); 10752b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 10762b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris if ((NanoTime() - start) > 5 * NS_PER_SEC) { 10772b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris break; 10782b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 10792b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris usleep(US_PER_MSEC); 10802b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris } 10812b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris kill(pid, SIGKILL); 10822b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_EQ(waitpid(pid, nullptr, 0), pid); 10832b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris 10842b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(test_executed); 1085e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris} 1086e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1087684fb77c82affca723910e26e8c219c804e00354Christopher Ferrisvoid VerifyFunctionsFound(const std::vector<std::string>& found_functions) { 1088684fb77c82affca723910e26e8c219c804e00354Christopher Ferris // We expect to find these functions in libbacktrace_test. If we don't 1089684fb77c82affca723910e26e8c219c804e00354Christopher Ferris // find them, that's a bug in the memory read handling code in libunwind. 1090684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::list<std::string> expected_functions; 1091684fb77c82affca723910e26e8c219c804e00354Christopher Ferris expected_functions.push_back("test_recursive_call"); 1092684fb77c82affca723910e26e8c219c804e00354Christopher Ferris expected_functions.push_back("test_level_one"); 1093684fb77c82affca723910e26e8c219c804e00354Christopher Ferris expected_functions.push_back("test_level_two"); 1094684fb77c82affca723910e26e8c219c804e00354Christopher Ferris expected_functions.push_back("test_level_three"); 1095684fb77c82affca723910e26e8c219c804e00354Christopher Ferris expected_functions.push_back("test_level_four"); 1096684fb77c82affca723910e26e8c219c804e00354Christopher Ferris for (const auto& found_function : found_functions) { 1097684fb77c82affca723910e26e8c219c804e00354Christopher Ferris for (const auto& expected_function : expected_functions) { 1098684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if (found_function == expected_function) { 1099684fb77c82affca723910e26e8c219c804e00354Christopher Ferris expected_functions.remove(found_function); 1100684fb77c82affca723910e26e8c219c804e00354Christopher Ferris break; 1101684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1102684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1103684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1104684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(expected_functions.empty()) << "Not all functions found in shared library."; 1105684fb77c82affca723910e26e8c219c804e00354Christopher Ferris} 1106684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1107684fb77c82affca723910e26e8c219c804e00354Christopher Ferrisconst char* CopySharedLibrary() { 1108684fb77c82affca723910e26e8c219c804e00354Christopher Ferris#if defined(__LP64__) 1109684fb77c82affca723910e26e8c219c804e00354Christopher Ferris const char* lib_name = "lib64"; 1110684fb77c82affca723910e26e8c219c804e00354Christopher Ferris#else 1111684fb77c82affca723910e26e8c219c804e00354Christopher Ferris const char* lib_name = "lib"; 1112684fb77c82affca723910e26e8c219c804e00354Christopher Ferris#endif 1113684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1114684fb77c82affca723910e26e8c219c804e00354Christopher Ferris#if defined(__BIONIC__) 1115684fb77c82affca723910e26e8c219c804e00354Christopher Ferris const char* tmp_so_name = "/data/local/tmp/libbacktrace_test.so"; 1116684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::string cp_cmd = android::base::StringPrintf("cp /system/%s/libbacktrace_test.so %s", 1117684fb77c82affca723910e26e8c219c804e00354Christopher Ferris lib_name, tmp_so_name); 1118684fb77c82affca723910e26e8c219c804e00354Christopher Ferris#else 1119684fb77c82affca723910e26e8c219c804e00354Christopher Ferris const char* tmp_so_name = "/tmp/libbacktrace_test.so"; 1120684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if (getenv("ANDROID_HOST_OUT") == NULL) { 1121684fb77c82affca723910e26e8c219c804e00354Christopher Ferris fprintf(stderr, "ANDROID_HOST_OUT not set, make sure you run lunch."); 1122684fb77c82affca723910e26e8c219c804e00354Christopher Ferris return nullptr; 1123684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1124684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::string cp_cmd = android::base::StringPrintf("cp %s/%s/libbacktrace_test.so %s", 1125684fb77c82affca723910e26e8c219c804e00354Christopher Ferris getenv("ANDROID_HOST_OUT"), lib_name, 1126684fb77c82affca723910e26e8c219c804e00354Christopher Ferris tmp_so_name); 1127684fb77c82affca723910e26e8c219c804e00354Christopher Ferris#endif 1128684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1129684fb77c82affca723910e26e8c219c804e00354Christopher Ferris // Copy the shared so to a tempory directory. 1130684fb77c82affca723910e26e8c219c804e00354Christopher Ferris system(cp_cmd.c_str()); 1131684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1132684fb77c82affca723910e26e8c219c804e00354Christopher Ferris return tmp_so_name; 1133684fb77c82affca723910e26e8c219c804e00354Christopher Ferris} 1134684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1135684fb77c82affca723910e26e8c219c804e00354Christopher FerrisTEST(libbacktrace, check_unreadable_elf_local) { 1136684fb77c82affca723910e26e8c219c804e00354Christopher Ferris const char* tmp_so_name = CopySharedLibrary(); 1137684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(tmp_so_name != nullptr); 1138684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1139684fb77c82affca723910e26e8c219c804e00354Christopher Ferris struct stat buf; 1140684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(stat(tmp_so_name, &buf) != -1); 1141684fb77c82affca723910e26e8c219c804e00354Christopher Ferris uintptr_t map_size = buf.st_size; 1142684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1143684fb77c82affca723910e26e8c219c804e00354Christopher Ferris int fd = open(tmp_so_name, O_RDONLY); 1144684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(fd != -1); 1145684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1146684fb77c82affca723910e26e8c219c804e00354Christopher Ferris void* map = mmap(NULL, map_size, PROT_READ, MAP_PRIVATE, fd, 0); 1147684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(map != MAP_FAILED); 1148684fb77c82affca723910e26e8c219c804e00354Christopher Ferris close(fd); 1149684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(unlink(tmp_so_name) != -1); 1150684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1151684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::vector<std::string> found_functions; 1152684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, 1153684fb77c82affca723910e26e8c219c804e00354Christopher Ferris BACKTRACE_CURRENT_THREAD)); 1154684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 1155684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1156684fb77c82affca723910e26e8c219c804e00354Christopher Ferris // Needed before GetFunctionName will work. 1157684fb77c82affca723910e26e8c219c804e00354Christopher Ferris backtrace->Unwind(0); 1158684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1159684fb77c82affca723910e26e8c219c804e00354Christopher Ferris // Loop through the entire map, and get every function we can find. 1160684fb77c82affca723910e26e8c219c804e00354Christopher Ferris map_size += reinterpret_cast<uintptr_t>(map); 1161684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::string last_func; 1162684fb77c82affca723910e26e8c219c804e00354Christopher Ferris for (uintptr_t read_addr = reinterpret_cast<uintptr_t>(map); 1163684fb77c82affca723910e26e8c219c804e00354Christopher Ferris read_addr < map_size; read_addr += 4) { 1164684fb77c82affca723910e26e8c219c804e00354Christopher Ferris uintptr_t offset; 1165684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::string func_name = backtrace->GetFunctionName(read_addr, &offset); 1166684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if (!func_name.empty() && last_func != func_name) { 1167684fb77c82affca723910e26e8c219c804e00354Christopher Ferris found_functions.push_back(func_name); 1168684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1169684fb77c82affca723910e26e8c219c804e00354Christopher Ferris last_func = func_name; 1170684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1171684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1172684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(munmap(map, map_size - reinterpret_cast<uintptr_t>(map)) == 0); 1173684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1174684fb77c82affca723910e26e8c219c804e00354Christopher Ferris VerifyFunctionsFound(found_functions); 1175684fb77c82affca723910e26e8c219c804e00354Christopher Ferris} 1176684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1177684fb77c82affca723910e26e8c219c804e00354Christopher FerrisTEST(libbacktrace, check_unreadable_elf_remote) { 1178684fb77c82affca723910e26e8c219c804e00354Christopher Ferris const char* tmp_so_name = CopySharedLibrary(); 1179684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(tmp_so_name != nullptr); 1180684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1181684fb77c82affca723910e26e8c219c804e00354Christopher Ferris g_ready = 0; 1182684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1183684fb77c82affca723910e26e8c219c804e00354Christopher Ferris struct stat buf; 1184684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(stat(tmp_so_name, &buf) != -1); 1185684fb77c82affca723910e26e8c219c804e00354Christopher Ferris uintptr_t map_size = buf.st_size; 1186684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1187684fb77c82affca723910e26e8c219c804e00354Christopher Ferris pid_t pid; 1188684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if ((pid = fork()) == 0) { 1189684fb77c82affca723910e26e8c219c804e00354Christopher Ferris int fd = open(tmp_so_name, O_RDONLY); 1190684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if (fd == -1) { 1191684fb77c82affca723910e26e8c219c804e00354Christopher Ferris fprintf(stderr, "Failed to open file %s: %s\n", tmp_so_name, strerror(errno)); 1192684fb77c82affca723910e26e8c219c804e00354Christopher Ferris unlink(tmp_so_name); 1193684fb77c82affca723910e26e8c219c804e00354Christopher Ferris exit(0); 1194684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1195684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1196684fb77c82affca723910e26e8c219c804e00354Christopher Ferris void* map = mmap(NULL, map_size, PROT_READ, MAP_PRIVATE, fd, 0); 1197684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if (map == MAP_FAILED) { 1198684fb77c82affca723910e26e8c219c804e00354Christopher Ferris fprintf(stderr, "Failed to map in memory: %s\n", strerror(errno)); 1199684fb77c82affca723910e26e8c219c804e00354Christopher Ferris unlink(tmp_so_name); 1200684fb77c82affca723910e26e8c219c804e00354Christopher Ferris exit(0); 1201684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1202684fb77c82affca723910e26e8c219c804e00354Christopher Ferris close(fd); 1203684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if (unlink(tmp_so_name) == -1) { 1204684fb77c82affca723910e26e8c219c804e00354Christopher Ferris fprintf(stderr, "Failed to unlink: %s\n", strerror(errno)); 1205684fb77c82affca723910e26e8c219c804e00354Christopher Ferris exit(0); 1206684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1207684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1208684fb77c82affca723910e26e8c219c804e00354Christopher Ferris g_addr = reinterpret_cast<uintptr_t>(map); 1209684fb77c82affca723910e26e8c219c804e00354Christopher Ferris g_ready = 1; 1210684fb77c82affca723910e26e8c219c804e00354Christopher Ferris while (true) { 1211684fb77c82affca723910e26e8c219c804e00354Christopher Ferris usleep(US_PER_MSEC); 1212684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1213684fb77c82affca723910e26e8c219c804e00354Christopher Ferris exit(0); 1214684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1215684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(pid > 0); 1216684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1217684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::vector<std::string> found_functions; 1218684fb77c82affca723910e26e8c219c804e00354Christopher Ferris uint64_t start = NanoTime(); 1219684fb77c82affca723910e26e8c219c804e00354Christopher Ferris while (true) { 1220684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0); 1221684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1222684fb77c82affca723910e26e8c219c804e00354Christopher Ferris // Wait for the process to get to a stopping point. 1223684fb77c82affca723910e26e8c219c804e00354Christopher Ferris WaitForStop(pid); 1224684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1225684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, BACKTRACE_CURRENT_THREAD)); 1226684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 1227684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1228684fb77c82affca723910e26e8c219c804e00354Christopher Ferris uintptr_t read_addr; 1229684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_EQ(sizeof(uintptr_t), backtrace->Read(reinterpret_cast<uintptr_t>(&g_ready), reinterpret_cast<uint8_t*>(&read_addr), sizeof(uintptr_t))); 1230684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if (read_addr) { 1231684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_EQ(sizeof(uintptr_t), backtrace->Read(reinterpret_cast<uintptr_t>(&g_addr), reinterpret_cast<uint8_t*>(&read_addr), sizeof(uintptr_t))); 1232684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1233684fb77c82affca723910e26e8c219c804e00354Christopher Ferris // Needed before GetFunctionName will work. 1234684fb77c82affca723910e26e8c219c804e00354Christopher Ferris backtrace->Unwind(0); 1235684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1236684fb77c82affca723910e26e8c219c804e00354Christopher Ferris // Loop through the entire map, and get every function we can find. 1237684fb77c82affca723910e26e8c219c804e00354Christopher Ferris map_size += read_addr; 1238684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::string last_func; 1239684fb77c82affca723910e26e8c219c804e00354Christopher Ferris for (; read_addr < map_size; read_addr += 4) { 1240684fb77c82affca723910e26e8c219c804e00354Christopher Ferris uintptr_t offset; 1241684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::string func_name = backtrace->GetFunctionName(read_addr, &offset); 1242684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if (!func_name.empty() && last_func != func_name) { 1243684fb77c82affca723910e26e8c219c804e00354Christopher Ferris found_functions.push_back(func_name); 1244684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1245684fb77c82affca723910e26e8c219c804e00354Christopher Ferris last_func = func_name; 1246684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1247684fb77c82affca723910e26e8c219c804e00354Christopher Ferris break; 1248684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1249684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0); 1250684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1251684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if ((NanoTime() - start) > 5 * NS_PER_SEC) { 1252684fb77c82affca723910e26e8c219c804e00354Christopher Ferris break; 1253684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1254684fb77c82affca723910e26e8c219c804e00354Christopher Ferris usleep(US_PER_MSEC); 1255684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1256684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1257684fb77c82affca723910e26e8c219c804e00354Christopher Ferris kill(pid, SIGKILL); 1258684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_EQ(waitpid(pid, nullptr, 0), pid); 1259684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1260684fb77c82affca723910e26e8c219c804e00354Christopher Ferris VerifyFunctionsFound(found_functions); 1261684fb77c82affca723910e26e8c219c804e00354Christopher Ferris} 1262684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1263684fb77c82affca723910e26e8c219c804e00354Christopher Ferrisbool FindFuncFrameInBacktrace(Backtrace* backtrace, uintptr_t test_func, size_t* frame_num) { 1264684fb77c82affca723910e26e8c219c804e00354Christopher Ferris backtrace_map_t map; 1265684fb77c82affca723910e26e8c219c804e00354Christopher Ferris backtrace->FillInMap(test_func, &map); 1266684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if (!BacktraceMap::IsValid(map)) { 1267684fb77c82affca723910e26e8c219c804e00354Christopher Ferris return false; 1268684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1269684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1270684fb77c82affca723910e26e8c219c804e00354Christopher Ferris // Loop through the frames, and find the one that is in the map. 1271684fb77c82affca723910e26e8c219c804e00354Christopher Ferris *frame_num = 0; 1272684fb77c82affca723910e26e8c219c804e00354Christopher Ferris for (Backtrace::const_iterator it = backtrace->begin(); it != backtrace->end(); ++it) { 1273684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if (BacktraceMap::IsValid(it->map) && map.start == it->map.start && 1274684fb77c82affca723910e26e8c219c804e00354Christopher Ferris it->pc >= test_func) { 1275684fb77c82affca723910e26e8c219c804e00354Christopher Ferris *frame_num = it->num; 1276684fb77c82affca723910e26e8c219c804e00354Christopher Ferris return true; 1277684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1278684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1279684fb77c82affca723910e26e8c219c804e00354Christopher Ferris return false; 1280684fb77c82affca723910e26e8c219c804e00354Christopher Ferris} 1281684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1282684fb77c82affca723910e26e8c219c804e00354Christopher Ferrisvoid VerifyUnreadableElfFrame(Backtrace* backtrace, uintptr_t test_func, size_t frame_num) { 1283684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_LT(backtrace->NumFrames(), static_cast<size_t>(MAX_BACKTRACE_FRAMES)) 1284684fb77c82affca723910e26e8c219c804e00354Christopher Ferris << DumpFrames(backtrace); 1285684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1286684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(frame_num != 0) << DumpFrames(backtrace); 1287684fb77c82affca723910e26e8c219c804e00354Christopher Ferris // Make sure that there is at least one more frame above the test func call. 1288684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_LT(frame_num, backtrace->NumFrames()) << DumpFrames(backtrace); 1289684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1290684fb77c82affca723910e26e8c219c804e00354Christopher Ferris uintptr_t diff = backtrace->GetFrame(frame_num)->pc - test_func; 1291684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_LT(diff, 200U) << DumpFrames(backtrace); 1292684fb77c82affca723910e26e8c219c804e00354Christopher Ferris} 1293684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1294684fb77c82affca723910e26e8c219c804e00354Christopher Ferrisvoid VerifyUnreadableElfBacktrace(uintptr_t test_func) { 1295684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, 1296684fb77c82affca723910e26e8c219c804e00354Christopher Ferris BACKTRACE_CURRENT_THREAD)); 1297684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 1298684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 1299684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1300684fb77c82affca723910e26e8c219c804e00354Christopher Ferris size_t frame_num; 1301684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(FindFuncFrameInBacktrace(backtrace.get(), test_func, &frame_num)); 1302684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1303684fb77c82affca723910e26e8c219c804e00354Christopher Ferris VerifyUnreadableElfFrame(backtrace.get(), test_func, frame_num); 1304684fb77c82affca723910e26e8c219c804e00354Christopher Ferris} 1305684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1306684fb77c82affca723910e26e8c219c804e00354Christopher Ferristypedef int (*test_func_t)(int, int, int, int, void (*)(uintptr_t), uintptr_t); 1307684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1308684fb77c82affca723910e26e8c219c804e00354Christopher FerrisTEST(libbacktrace, unwind_through_unreadable_elf_local) { 1309684fb77c82affca723910e26e8c219c804e00354Christopher Ferris const char* tmp_so_name = CopySharedLibrary(); 1310684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(tmp_so_name != nullptr); 1311684fb77c82affca723910e26e8c219c804e00354Christopher Ferris void* lib_handle = dlopen(tmp_so_name, RTLD_NOW); 1312684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(lib_handle != nullptr); 1313684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(unlink(tmp_so_name) != -1); 1314684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1315684fb77c82affca723910e26e8c219c804e00354Christopher Ferris test_func_t test_func; 1316684fb77c82affca723910e26e8c219c804e00354Christopher Ferris test_func = reinterpret_cast<test_func_t>(dlsym(lib_handle, "test_level_one")); 1317684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(test_func != nullptr); 1318684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1319684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_NE(test_func(1, 2, 3, 4, VerifyUnreadableElfBacktrace, 1320684fb77c82affca723910e26e8c219c804e00354Christopher Ferris reinterpret_cast<uintptr_t>(test_func)), 0); 1321684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1322684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(dlclose(lib_handle) == 0); 1323684fb77c82affca723910e26e8c219c804e00354Christopher Ferris} 1324684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1325684fb77c82affca723910e26e8c219c804e00354Christopher FerrisTEST(libbacktrace, unwind_through_unreadable_elf_remote) { 1326684fb77c82affca723910e26e8c219c804e00354Christopher Ferris const char* tmp_so_name = CopySharedLibrary(); 1327684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(tmp_so_name != nullptr); 1328684fb77c82affca723910e26e8c219c804e00354Christopher Ferris void* lib_handle = dlopen(tmp_so_name, RTLD_NOW); 1329684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(lib_handle != nullptr); 1330684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(unlink(tmp_so_name) != -1); 1331684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1332684fb77c82affca723910e26e8c219c804e00354Christopher Ferris test_func_t test_func; 1333684fb77c82affca723910e26e8c219c804e00354Christopher Ferris test_func = reinterpret_cast<test_func_t>(dlsym(lib_handle, "test_level_one")); 1334684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(test_func != nullptr); 1335684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1336684fb77c82affca723910e26e8c219c804e00354Christopher Ferris pid_t pid; 1337684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if ((pid = fork()) == 0) { 1338684fb77c82affca723910e26e8c219c804e00354Christopher Ferris test_func(1, 2, 3, 4, 0, 0); 1339684fb77c82affca723910e26e8c219c804e00354Christopher Ferris exit(0); 1340684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1341684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(pid > 0); 1342684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(dlclose(lib_handle) == 0); 1343684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1344684fb77c82affca723910e26e8c219c804e00354Christopher Ferris uint64_t start = NanoTime(); 1345684fb77c82affca723910e26e8c219c804e00354Christopher Ferris bool done = false; 1346684fb77c82affca723910e26e8c219c804e00354Christopher Ferris while (!done) { 1347684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0); 1348684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1349684fb77c82affca723910e26e8c219c804e00354Christopher Ferris // Wait for the process to get to a stopping point. 1350684fb77c82affca723910e26e8c219c804e00354Christopher Ferris WaitForStop(pid); 1351684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1352684fb77c82affca723910e26e8c219c804e00354Christopher Ferris std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, BACKTRACE_CURRENT_THREAD)); 1353684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(backtrace.get() != nullptr); 1354684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 1355684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1356684fb77c82affca723910e26e8c219c804e00354Christopher Ferris size_t frame_num; 1357684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if (FindFuncFrameInBacktrace(backtrace.get(), 1358684fb77c82affca723910e26e8c219c804e00354Christopher Ferris reinterpret_cast<uintptr_t>(test_func), &frame_num)) { 1359684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1360684fb77c82affca723910e26e8c219c804e00354Christopher Ferris VerifyUnreadableElfFrame(backtrace.get(), reinterpret_cast<uintptr_t>(test_func), frame_num); 1361684fb77c82affca723910e26e8c219c804e00354Christopher Ferris done = true; 1362684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1363684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1364684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0); 1365684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1366684fb77c82affca723910e26e8c219c804e00354Christopher Ferris if ((NanoTime() - start) > 5 * NS_PER_SEC) { 1367684fb77c82affca723910e26e8c219c804e00354Christopher Ferris break; 1368684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1369684fb77c82affca723910e26e8c219c804e00354Christopher Ferris usleep(US_PER_MSEC); 1370684fb77c82affca723910e26e8c219c804e00354Christopher Ferris } 1371684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1372684fb77c82affca723910e26e8c219c804e00354Christopher Ferris kill(pid, SIGKILL); 1373684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_EQ(waitpid(pid, nullptr, 0), pid); 1374684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1375684fb77c82affca723910e26e8c219c804e00354Christopher Ferris ASSERT_TRUE(done) << "Test function never found in unwind."; 1376684fb77c82affca723910e26e8c219c804e00354Christopher Ferris} 1377684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1378e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris#if defined(ENABLE_PSS_TESTS) 1379e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris#include "GetPss.h" 1380e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1381e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris#define MAX_LEAK_BYTES 32*1024UL 1382e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 13832b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferrisvoid CheckForLeak(pid_t pid, pid_t tid) { 1384e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris // Do a few runs to get the PSS stable. 1385e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris for (size_t i = 0; i < 100; i++) { 1386e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris Backtrace* backtrace = Backtrace::Create(pid, tid); 13872b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace != nullptr); 1388e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 1389e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris delete backtrace; 1390e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris } 1391e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris size_t stable_pss = GetPssBytes(); 13922c43cff01d1271be451671567955158629b23670Christopher Ferris ASSERT_TRUE(stable_pss != 0); 1393e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1394e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris // Loop enough that even a small leak should be detectable. 1395e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris for (size_t i = 0; i < 4096; i++) { 1396e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris Backtrace* backtrace = Backtrace::Create(pid, tid); 13972b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(backtrace != nullptr); 1398e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_TRUE(backtrace->Unwind(0)); 1399e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris delete backtrace; 1400e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris } 1401e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris size_t new_pss = GetPssBytes(); 14022c43cff01d1271be451671567955158629b23670Christopher Ferris ASSERT_TRUE(new_pss != 0); 1403e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris size_t abs_diff = (new_pss > stable_pss) ? new_pss - stable_pss : stable_pss - new_pss; 1404e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris // As long as the new pss is within a certain amount, consider everything okay. 1405e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_LE(abs_diff, MAX_LEAK_BYTES); 1406e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris} 1407e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1408e29609106033a48a6128664668d22bf4fb42a7eeChristopher FerrisTEST(libbacktrace, check_for_leak_local) { 1409e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris CheckForLeak(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD); 1410e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris} 1411e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1412e29609106033a48a6128664668d22bf4fb42a7eeChristopher FerrisTEST(libbacktrace, check_for_leak_local_thread) { 14132b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris thread_t thread_data = { 0, 0, 0, nullptr }; 1414e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris pthread_t thread; 14152b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(pthread_create(&thread, nullptr, ThreadLevelRun, &thread_data) == 0); 1416e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1417e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris // Wait up to 2 seconds for the tid to be set. 1418e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2)); 1419e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1420e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris CheckForLeak(BACKTRACE_CURRENT_PROCESS, thread_data.tid); 1421e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1422e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris // Tell the thread to exit its infinite loop. 1423e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris android_atomic_acquire_store(0, &thread_data.state); 1424e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 14252b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_TRUE(pthread_join(thread, nullptr) == 0); 1426e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris} 1427e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1428e29609106033a48a6128664668d22bf4fb42a7eeChristopher FerrisTEST(libbacktrace, check_for_leak_remote) { 1429e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris pid_t pid; 1430e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1431e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris if ((pid = fork()) == 0) { 1432e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris while (true) { 1433e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris } 1434e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris _exit(0); 1435e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris } 1436e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_LT(0, pid); 1437e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1438e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0); 1439e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1440e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris // Wait for the process to get to a stopping point. 1441e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris WaitForStop(pid); 1442e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1443e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris CheckForLeak(pid, BACKTRACE_CURRENT_THREAD); 1444e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1445e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0); 1446e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris 1447e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris kill(pid, SIGKILL); 14482b4a63fc6a4bfc6db69901258539276b888c7ec4Christopher Ferris ASSERT_EQ(waitpid(pid, nullptr, 0), pid); 1449e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris} 1450e29609106033a48a6128664668d22bf4fb42a7eeChristopher Ferris#endif 1451684fb77c82affca723910e26e8c219c804e00354Christopher Ferris 1452