1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project
3*eb293b8fSAndroid Build Coastguard Worker *
4*eb293b8fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*eb293b8fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*eb293b8fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*eb293b8fSAndroid Build Coastguard Worker *
8*eb293b8fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*eb293b8fSAndroid Build Coastguard Worker *
10*eb293b8fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*eb293b8fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*eb293b8fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*eb293b8fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*eb293b8fSAndroid Build Coastguard Worker * limitations under the License.
15*eb293b8fSAndroid Build Coastguard Worker */
16*eb293b8fSAndroid Build Coastguard Worker
17*eb293b8fSAndroid Build Coastguard Worker #include <dlfcn.h>
18*eb293b8fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
19*eb293b8fSAndroid Build Coastguard Worker #include <sys/ptrace.h>
20*eb293b8fSAndroid Build Coastguard Worker #include <sys/types.h>
21*eb293b8fSAndroid Build Coastguard Worker #include <unistd.h>
22*eb293b8fSAndroid Build Coastguard Worker
23*eb293b8fSAndroid Build Coastguard Worker #include <algorithm>
24*eb293b8fSAndroid Build Coastguard Worker #include <array>
25*eb293b8fSAndroid Build Coastguard Worker #include <atomic>
26*eb293b8fSAndroid Build Coastguard Worker #include <cerrno>
27*eb293b8fSAndroid Build Coastguard Worker #include <csignal>
28*eb293b8fSAndroid Build Coastguard Worker #include <cstddef>
29*eb293b8fSAndroid Build Coastguard Worker #include <cstdio>
30*eb293b8fSAndroid Build Coastguard Worker #include <cstdlib>
31*eb293b8fSAndroid Build Coastguard Worker #include <cstring>
32*eb293b8fSAndroid Build Coastguard Worker #include <filesystem>
33*eb293b8fSAndroid Build Coastguard Worker #include <memory>
34*eb293b8fSAndroid Build Coastguard Worker #include <string>
35*eb293b8fSAndroid Build Coastguard Worker #include <system_error>
36*eb293b8fSAndroid Build Coastguard Worker #include <thread>
37*eb293b8fSAndroid Build Coastguard Worker
38*eb293b8fSAndroid Build Coastguard Worker #include <android-base/file.h>
39*eb293b8fSAndroid Build Coastguard Worker #include <procinfo/process.h>
40*eb293b8fSAndroid Build Coastguard Worker
41*eb293b8fSAndroid Build Coastguard Worker #include "OfflineUnwindUtils.h"
42*eb293b8fSAndroid Build Coastguard Worker #include "ProcessTracer.h"
43*eb293b8fSAndroid Build Coastguard Worker #include "tests/TestUtils.h"
44*eb293b8fSAndroid Build Coastguard Worker
45*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
46*eb293b8fSAndroid Build Coastguard Worker namespace {
47*eb293b8fSAndroid Build Coastguard Worker
48*eb293b8fSAndroid Build Coastguard Worker class ProcessTracerTest : public ::testing::TestWithParam<bool> {
49*eb293b8fSAndroid Build Coastguard Worker protected:
50*eb293b8fSAndroid Build Coastguard Worker enum class BoolOrTimeout {
51*eb293b8fSAndroid Build Coastguard Worker kSuccess = 0,
52*eb293b8fSAndroid Build Coastguard Worker kFail,
53*eb293b8fSAndroid Build Coastguard Worker kTimeout,
54*eb293b8fSAndroid Build Coastguard Worker };
55*eb293b8fSAndroid Build Coastguard Worker
56*eb293b8fSAndroid Build Coastguard Worker // Setup a child process that has a few threads that simply busy wait.
SetUp()57*eb293b8fSAndroid Build Coastguard Worker void SetUp() override {
58*eb293b8fSAndroid Build Coastguard Worker // Setup signal handlers for child to let parent know that it is ready and for parent
59*eb293b8fSAndroid Build Coastguard Worker // to kill the child.
60*eb293b8fSAndroid Build Coastguard Worker child_is_ready_ = false;
61*eb293b8fSAndroid Build Coastguard Worker ASSERT_NE(SIG_ERR, signal(kChildIsReadySignal, [](int) { child_is_ready_ = true; }))
62*eb293b8fSAndroid Build Coastguard Worker << "Failed to set up signal handler for kChildIsReadySignal: " << strerror(errno);
63*eb293b8fSAndroid Build Coastguard Worker child_keep_running_ = true;
64*eb293b8fSAndroid Build Coastguard Worker ASSERT_NE(SIG_ERR, signal(kStopChildSignal, [](int) { child_keep_running_ = false; }))
65*eb293b8fSAndroid Build Coastguard Worker << "Failed to set up signal handler for kStopChildSignal: " << strerror(errno);
66*eb293b8fSAndroid Build Coastguard Worker
67*eb293b8fSAndroid Build Coastguard Worker pid_t parent_pid = getpid();
68*eb293b8fSAndroid Build Coastguard Worker child_pid_ = fork();
69*eb293b8fSAndroid Build Coastguard Worker if (child_pid_ == static_cast<pid_t>(-1)) FAIL() << "SetUp: fork() failed: " << strerror(errno);
70*eb293b8fSAndroid Build Coastguard Worker if (child_pid_ == 0) {
71*eb293b8fSAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(ChildProcSpin(parent_pid));
72*eb293b8fSAndroid Build Coastguard Worker }
73*eb293b8fSAndroid Build Coastguard Worker
74*eb293b8fSAndroid Build Coastguard Worker // Make sure the child process has set up its threads before running the test.
75*eb293b8fSAndroid Build Coastguard Worker sigset_t signal_mask, old_mask;
76*eb293b8fSAndroid Build Coastguard Worker sigemptyset(&signal_mask);
77*eb293b8fSAndroid Build Coastguard Worker sigaddset(&signal_mask, kChildIsReadySignal);
78*eb293b8fSAndroid Build Coastguard Worker sigprocmask(SIG_BLOCK, &signal_mask, &old_mask);
79*eb293b8fSAndroid Build Coastguard Worker while (!child_is_ready_) sigsuspend(&old_mask);
80*eb293b8fSAndroid Build Coastguard Worker sigprocmask(SIG_UNBLOCK, &signal_mask, NULL);
81*eb293b8fSAndroid Build Coastguard Worker }
82*eb293b8fSAndroid Build Coastguard Worker
TearDown()83*eb293b8fSAndroid Build Coastguard Worker void TearDown() override {
84*eb293b8fSAndroid Build Coastguard Worker // Send signal to join threads and exit.
85*eb293b8fSAndroid Build Coastguard Worker if (-1 == kill(child_pid_, kStopChildSignal)) {
86*eb293b8fSAndroid Build Coastguard Worker std::cerr << "TearDown: kill sending kStopChildSignal failed: " << strerror(errno) << ".\n";
87*eb293b8fSAndroid Build Coastguard Worker kill(child_pid_, SIGKILL);
88*eb293b8fSAndroid Build Coastguard Worker }
89*eb293b8fSAndroid Build Coastguard Worker }
90*eb293b8fSAndroid Build Coastguard Worker
ChildProcSpin(pid_t parent_pid)91*eb293b8fSAndroid Build Coastguard Worker void ChildProcSpin(pid_t parent_pid) {
92*eb293b8fSAndroid Build Coastguard Worker // Busy wait in a dlopened local library so we can reliably test (across different
93*eb293b8fSAndroid Build Coastguard Worker // architecture) if a process is within a desired ELF.
94*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<void, decltype(&dlclose)> test_lib_handle(GetTestLibHandle(), &dlclose);
95*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(test_lib_handle);
96*eb293b8fSAndroid Build Coastguard Worker int (*busy_wait_func)() = reinterpret_cast<int (*)()>(dlsym(test_lib_handle.get(), "BusyWait"));
97*eb293b8fSAndroid Build Coastguard Worker ASSERT_NE(nullptr, busy_wait_func);
98*eb293b8fSAndroid Build Coastguard Worker
99*eb293b8fSAndroid Build Coastguard Worker std::array<std::thread, kNumThreads> threads;
100*eb293b8fSAndroid Build Coastguard Worker std::array<std::atomic_bool, kNumThreads> threads_are_ready{false, false, false, false, false};
101*eb293b8fSAndroid Build Coastguard Worker for (size_t i = 0; i < kNumThreads; ++i) {
102*eb293b8fSAndroid Build Coastguard Worker threads.at(i) = std::thread([&threads_are_ready, i, &busy_wait_func]() {
103*eb293b8fSAndroid Build Coastguard Worker while (child_keep_running_) {
104*eb293b8fSAndroid Build Coastguard Worker DoNotOptimize(busy_wait_func());
105*eb293b8fSAndroid Build Coastguard Worker threads_are_ready.at(i) = true;
106*eb293b8fSAndroid Build Coastguard Worker }
107*eb293b8fSAndroid Build Coastguard Worker });
108*eb293b8fSAndroid Build Coastguard Worker }
109*eb293b8fSAndroid Build Coastguard Worker // Wait until all threads have entered the loop before informing parent child is
110*eb293b8fSAndroid Build Coastguard Worker // ready to avoid a race.
111*eb293b8fSAndroid Build Coastguard Worker while (!std::all_of(threads_are_ready.begin(), threads_are_ready.end(),
112*eb293b8fSAndroid Build Coastguard Worker [&](const std::atomic_bool& el) { return el == true; })) {
113*eb293b8fSAndroid Build Coastguard Worker usleep(100);
114*eb293b8fSAndroid Build Coastguard Worker }
115*eb293b8fSAndroid Build Coastguard Worker ASSERT_NE(-1, kill(parent_pid, kChildIsReadySignal) == -1)
116*eb293b8fSAndroid Build Coastguard Worker << "TearDown: kill sending kChildIsReady failed: " << strerror(errno) << ".\n";
117*eb293b8fSAndroid Build Coastguard Worker for (size_t i = 0; i < kNumThreads; ++i) {
118*eb293b8fSAndroid Build Coastguard Worker threads.at(i).join();
119*eb293b8fSAndroid Build Coastguard Worker }
120*eb293b8fSAndroid Build Coastguard Worker exit(EXIT_SUCCESS);
121*eb293b8fSAndroid Build Coastguard Worker }
122*eb293b8fSAndroid Build Coastguard Worker
StopInDesiredElfTimeout(ProcessTracer & proc,const std::string & elf_name,size_t timeout_sec=2)123*eb293b8fSAndroid Build Coastguard Worker BoolOrTimeout StopInDesiredElfTimeout(ProcessTracer& proc, const std::string& elf_name,
124*eb293b8fSAndroid Build Coastguard Worker size_t timeout_sec = 2) {
125*eb293b8fSAndroid Build Coastguard Worker static BoolOrTimeout result = BoolOrTimeout::kSuccess;
126*eb293b8fSAndroid Build Coastguard Worker if (SIG_ERR == signal(SIGALRM, [](int) {
127*eb293b8fSAndroid Build Coastguard Worker result = BoolOrTimeout::kTimeout;
128*eb293b8fSAndroid Build Coastguard Worker // StopInDesiredElf contains signal handler for SIGINT mainly so that we could stop the
129*eb293b8fSAndroid Build Coastguard Worker // search easily when running unwind_for_offline and we can use it here too.
130*eb293b8fSAndroid Build Coastguard Worker kill(getpid(), SIGINT);
131*eb293b8fSAndroid Build Coastguard Worker })) {
132*eb293b8fSAndroid Build Coastguard Worker std::cerr << "Failed to set up signal handler for SIGALRM: " << strerror(errno) << ".\n";
133*eb293b8fSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
134*eb293b8fSAndroid Build Coastguard Worker }
135*eb293b8fSAndroid Build Coastguard Worker alarm(timeout_sec);
136*eb293b8fSAndroid Build Coastguard Worker if (proc.StopInDesiredElf(elf_name)) {
137*eb293b8fSAndroid Build Coastguard Worker result = BoolOrTimeout::kSuccess;
138*eb293b8fSAndroid Build Coastguard Worker } else if (result != BoolOrTimeout::kTimeout) {
139*eb293b8fSAndroid Build Coastguard Worker result = BoolOrTimeout::kFail;
140*eb293b8fSAndroid Build Coastguard Worker }
141*eb293b8fSAndroid Build Coastguard Worker alarm(0);
142*eb293b8fSAndroid Build Coastguard Worker return result;
143*eb293b8fSAndroid Build Coastguard Worker }
144*eb293b8fSAndroid Build Coastguard Worker
145*eb293b8fSAndroid Build Coastguard Worker static constexpr size_t kNumThreads = 5;
146*eb293b8fSAndroid Build Coastguard Worker static constexpr int kChildIsReadySignal = SIGUSR1;
147*eb293b8fSAndroid Build Coastguard Worker static constexpr int kStopChildSignal = SIGUSR2;
148*eb293b8fSAndroid Build Coastguard Worker static inline std::atomic_bool child_is_ready_ = false;
149*eb293b8fSAndroid Build Coastguard Worker static inline std::atomic_bool child_keep_running_ = true;
150*eb293b8fSAndroid Build Coastguard Worker pid_t child_pid_;
151*eb293b8fSAndroid Build Coastguard Worker };
152*eb293b8fSAndroid Build Coastguard Worker
VerifyState(pid_t tid,bool running)153*eb293b8fSAndroid Build Coastguard Worker static void VerifyState(pid_t tid, bool running) {
154*eb293b8fSAndroid Build Coastguard Worker while (true) {
155*eb293b8fSAndroid Build Coastguard Worker android::procinfo::ProcessInfo proc_info;
156*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(GetProcessInfo(tid, &proc_info));
157*eb293b8fSAndroid Build Coastguard Worker if (running) {
158*eb293b8fSAndroid Build Coastguard Worker if (proc_info.state == android::procinfo::kProcessStateRunning ||
159*eb293b8fSAndroid Build Coastguard Worker proc_info.state == android::procinfo::kProcessStateSleeping) {
160*eb293b8fSAndroid Build Coastguard Worker break;
161*eb293b8fSAndroid Build Coastguard Worker }
162*eb293b8fSAndroid Build Coastguard Worker } else if (proc_info.state == android::procinfo::kProcessStateStopped) {
163*eb293b8fSAndroid Build Coastguard Worker break;
164*eb293b8fSAndroid Build Coastguard Worker }
165*eb293b8fSAndroid Build Coastguard Worker usleep(1000);
166*eb293b8fSAndroid Build Coastguard Worker }
167*eb293b8fSAndroid Build Coastguard Worker }
168*eb293b8fSAndroid Build Coastguard Worker
VerifyState(ProcessTracer & proc,bool running)169*eb293b8fSAndroid Build Coastguard Worker static void VerifyState(ProcessTracer& proc, bool running) {
170*eb293b8fSAndroid Build Coastguard Worker // Verify that the main thread and all threads are in the expected state.
171*eb293b8fSAndroid Build Coastguard Worker VerifyState(proc.pid(), running);
172*eb293b8fSAndroid Build Coastguard Worker if (::testing::Test::HasFatalFailure()) return;
173*eb293b8fSAndroid Build Coastguard Worker for (const pid_t& tid : proc.tids()) {
174*eb293b8fSAndroid Build Coastguard Worker VerifyState(tid, running);
175*eb293b8fSAndroid Build Coastguard Worker if (::testing::Test::HasFatalFailure()) return;
176*eb293b8fSAndroid Build Coastguard Worker }
177*eb293b8fSAndroid Build Coastguard Worker }
178*eb293b8fSAndroid Build Coastguard Worker
TEST_P(ProcessTracerTest,stop_and_resume)179*eb293b8fSAndroid Build Coastguard Worker TEST_P(ProcessTracerTest, stop_and_resume) {
180*eb293b8fSAndroid Build Coastguard Worker ProcessTracer proc(child_pid_, /*is_tracing_threads*/ GetParam());
181*eb293b8fSAndroid Build Coastguard Worker
182*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(proc.Stop());
183*eb293b8fSAndroid Build Coastguard Worker VerifyState(proc, /*running*/ false);
184*eb293b8fSAndroid Build Coastguard Worker if (::testing::Test::HasFatalFailure()) return;
185*eb293b8fSAndroid Build Coastguard Worker
186*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(proc.Resume());
187*eb293b8fSAndroid Build Coastguard Worker VerifyState(proc, /*running*/ true);
188*eb293b8fSAndroid Build Coastguard Worker if (::testing::Test::HasFatalFailure()) return;
189*eb293b8fSAndroid Build Coastguard Worker }
190*eb293b8fSAndroid Build Coastguard Worker
TEST_P(ProcessTracerTest,attach_and_detach)191*eb293b8fSAndroid Build Coastguard Worker TEST_P(ProcessTracerTest, attach_and_detach) {
192*eb293b8fSAndroid Build Coastguard Worker ProcessTracer proc(child_pid_, /*is_tracing_threads*/ GetParam());
193*eb293b8fSAndroid Build Coastguard Worker
194*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(proc.Attach(child_pid_));
195*eb293b8fSAndroid Build Coastguard Worker // Attaching to the same pid should result in failure and errno indicating that we cannot trace
196*eb293b8fSAndroid Build Coastguard Worker // the priocess because it is already being traced after the call to Attach().
197*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(-1, ptrace(PTRACE_ATTACH, child_pid_, nullptr, nullptr));
198*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(EPERM, errno);
199*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(proc.Detach(child_pid_));
200*eb293b8fSAndroid Build Coastguard Worker for (const pid_t& tid : proc.tids()) {
201*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(proc.Attach(tid));
202*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(-1, ptrace(PTRACE_ATTACH, tid, nullptr, nullptr));
203*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(EPERM, errno);
204*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(proc.Detach(tid));
205*eb293b8fSAndroid Build Coastguard Worker }
206*eb293b8fSAndroid Build Coastguard Worker }
207*eb293b8fSAndroid Build Coastguard Worker
TEST_P(ProcessTracerTest,consecutive_attach_fail)208*eb293b8fSAndroid Build Coastguard Worker TEST_P(ProcessTracerTest, consecutive_attach_fail) {
209*eb293b8fSAndroid Build Coastguard Worker if (!GetParam()) GTEST_SKIP();
210*eb293b8fSAndroid Build Coastguard Worker ProcessTracer proc(child_pid_, /*is_tracing_threads*/ GetParam());
211*eb293b8fSAndroid Build Coastguard Worker
212*eb293b8fSAndroid Build Coastguard Worker bool is_first_thread = true;
213*eb293b8fSAndroid Build Coastguard Worker for (const pid_t& tid : proc.tids()) {
214*eb293b8fSAndroid Build Coastguard Worker if (is_first_thread) {
215*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(proc.Attach(tid));
216*eb293b8fSAndroid Build Coastguard Worker is_first_thread = false;
217*eb293b8fSAndroid Build Coastguard Worker } else {
218*eb293b8fSAndroid Build Coastguard Worker ASSERT_FALSE(proc.Attach(tid));
219*eb293b8fSAndroid Build Coastguard Worker }
220*eb293b8fSAndroid Build Coastguard Worker }
221*eb293b8fSAndroid Build Coastguard Worker }
222*eb293b8fSAndroid Build Coastguard Worker
TEST_P(ProcessTracerTest,trace_invalid_tid)223*eb293b8fSAndroid Build Coastguard Worker TEST_P(ProcessTracerTest, trace_invalid_tid) {
224*eb293b8fSAndroid Build Coastguard Worker if (GetParam()) GTEST_SKIP();
225*eb293b8fSAndroid Build Coastguard Worker ProcessTracer proc(child_pid_, /*is_tracing_threads*/ GetParam());
226*eb293b8fSAndroid Build Coastguard Worker ASSERT_FALSE(proc.Attach(getpid()));
227*eb293b8fSAndroid Build Coastguard Worker ASSERT_FALSE(proc.Detach(getpid()));
228*eb293b8fSAndroid Build Coastguard Worker }
229*eb293b8fSAndroid Build Coastguard Worker
TEST_P(ProcessTracerTest,detach_with_no_attached)230*eb293b8fSAndroid Build Coastguard Worker TEST_P(ProcessTracerTest, detach_with_no_attached) {
231*eb293b8fSAndroid Build Coastguard Worker if (GetParam()) GTEST_SKIP();
232*eb293b8fSAndroid Build Coastguard Worker ProcessTracer proc(child_pid_, /*is_tracing_threads*/ GetParam());
233*eb293b8fSAndroid Build Coastguard Worker ASSERT_FALSE(proc.Detach(child_pid_));
234*eb293b8fSAndroid Build Coastguard Worker }
235*eb293b8fSAndroid Build Coastguard Worker
TEST_P(ProcessTracerTest,uses_shared_library)236*eb293b8fSAndroid Build Coastguard Worker TEST_P(ProcessTracerTest, uses_shared_library) {
237*eb293b8fSAndroid Build Coastguard Worker ProcessTracer proc(child_pid_, /*is_tracing_threads*/ GetParam());
238*eb293b8fSAndroid Build Coastguard Worker
239*eb293b8fSAndroid Build Coastguard Worker std::string elf_name = "libunwindstack_local.so";
240*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(proc.UsesSharedLibrary(child_pid_, elf_name));
241*eb293b8fSAndroid Build Coastguard Worker for (const pid_t& tid : proc.tids()) {
242*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(proc.UsesSharedLibrary(tid, elf_name));
243*eb293b8fSAndroid Build Coastguard Worker }
244*eb293b8fSAndroid Build Coastguard Worker }
245*eb293b8fSAndroid Build Coastguard Worker
TEST_P(ProcessTracerTest,does_not_use_shared_library)246*eb293b8fSAndroid Build Coastguard Worker TEST_P(ProcessTracerTest, does_not_use_shared_library) {
247*eb293b8fSAndroid Build Coastguard Worker ProcessTracer proc(child_pid_, /*is_tracing_threads*/ GetParam());
248*eb293b8fSAndroid Build Coastguard Worker
249*eb293b8fSAndroid Build Coastguard Worker std::string elf_name = "libfake.so";
250*eb293b8fSAndroid Build Coastguard Worker ASSERT_FALSE(proc.UsesSharedLibrary(child_pid_, elf_name));
251*eb293b8fSAndroid Build Coastguard Worker for (const pid_t& tid : proc.tids()) {
252*eb293b8fSAndroid Build Coastguard Worker ASSERT_FALSE(proc.UsesSharedLibrary(tid, elf_name));
253*eb293b8fSAndroid Build Coastguard Worker }
254*eb293b8fSAndroid Build Coastguard Worker }
255*eb293b8fSAndroid Build Coastguard Worker
TEST_P(ProcessTracerTest,stop_in_elf_we_use)256*eb293b8fSAndroid Build Coastguard Worker TEST_P(ProcessTracerTest, stop_in_elf_we_use) {
257*eb293b8fSAndroid Build Coastguard Worker // Skip the run with is_tracing_threads=false because main thread only uses
258*eb293b8fSAndroid Build Coastguard Worker // the threading library.
259*eb293b8fSAndroid Build Coastguard Worker if (!GetParam()) GTEST_SKIP();
260*eb293b8fSAndroid Build Coastguard Worker ProcessTracer proc(child_pid_, /*is_tracing_threads*/ GetParam());
261*eb293b8fSAndroid Build Coastguard Worker std::string elf_name = "libunwindstack_local.so";
262*eb293b8fSAndroid Build Coastguard Worker
263*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(BoolOrTimeout::kSuccess, StopInDesiredElfTimeout(proc, elf_name));
264*eb293b8fSAndroid Build Coastguard Worker }
265*eb293b8fSAndroid Build Coastguard Worker
TEST_P(ProcessTracerTest,timeout_when_try_to_stop_in_elf_we_do_not_use)266*eb293b8fSAndroid Build Coastguard Worker TEST_P(ProcessTracerTest, timeout_when_try_to_stop_in_elf_we_do_not_use) {
267*eb293b8fSAndroid Build Coastguard Worker ProcessTracer proc(child_pid_, /*is_tracing_threads*/ GetParam());
268*eb293b8fSAndroid Build Coastguard Worker std::string elf_name = "libfake.so";
269*eb293b8fSAndroid Build Coastguard Worker
270*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(BoolOrTimeout::kTimeout, StopInDesiredElfTimeout(proc, elf_name));
271*eb293b8fSAndroid Build Coastguard Worker }
272*eb293b8fSAndroid Build Coastguard Worker
273*eb293b8fSAndroid Build Coastguard Worker INSTANTIATE_TEST_CASE_P(IsTracingThreads, ProcessTracerTest, testing::Values(false, true));
274*eb293b8fSAndroid Build Coastguard Worker
275*eb293b8fSAndroid Build Coastguard Worker } // namespace
276*eb293b8fSAndroid Build Coastguard Worker } // namespace unwindstack
277