xref: /aosp_15_r20/system/unwinding/libunwindstack/tests/ForkTest.h (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker  * Copyright (C) 2023 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 #pragma once
18*eb293b8fSAndroid Build Coastguard Worker 
19*eb293b8fSAndroid Build Coastguard Worker #include <signal.h>
20*eb293b8fSAndroid Build Coastguard Worker #include <sys/types.h>
21*eb293b8fSAndroid Build Coastguard Worker #include <sys/wait.h>
22*eb293b8fSAndroid Build Coastguard Worker #include <unistd.h>
23*eb293b8fSAndroid Build Coastguard Worker 
24*eb293b8fSAndroid Build Coastguard Worker #include <functional>
25*eb293b8fSAndroid Build Coastguard Worker 
26*eb293b8fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
27*eb293b8fSAndroid Build Coastguard Worker 
28*eb293b8fSAndroid Build Coastguard Worker #include "PidUtils.h"
29*eb293b8fSAndroid Build Coastguard Worker #include "TestUtils.h"
30*eb293b8fSAndroid Build Coastguard Worker 
31*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
32*eb293b8fSAndroid Build Coastguard Worker 
33*eb293b8fSAndroid Build Coastguard Worker class ForkTest : public ::testing::Test {
34*eb293b8fSAndroid Build Coastguard Worker  protected:
SetForkFunc(std::function<void ()> fork_func)35*eb293b8fSAndroid Build Coastguard Worker   void SetForkFunc(std::function<void()> fork_func) { fork_func_ = fork_func; }
36*eb293b8fSAndroid Build Coastguard Worker 
Fork(std::function<void ()> fork_func)37*eb293b8fSAndroid Build Coastguard Worker   void Fork(std::function<void()> fork_func) {
38*eb293b8fSAndroid Build Coastguard Worker     SetForkFunc(fork_func);
39*eb293b8fSAndroid Build Coastguard Worker     Fork();
40*eb293b8fSAndroid Build Coastguard Worker   }
41*eb293b8fSAndroid Build Coastguard Worker 
Fork()42*eb293b8fSAndroid Build Coastguard Worker   void Fork() {
43*eb293b8fSAndroid Build Coastguard Worker     for (size_t i = 0; i < kMaxRetries; i++) {
44*eb293b8fSAndroid Build Coastguard Worker       if ((pid_ = fork()) == 0) {
45*eb293b8fSAndroid Build Coastguard Worker         fork_func_();
46*eb293b8fSAndroid Build Coastguard Worker         _exit(1);
47*eb293b8fSAndroid Build Coastguard Worker       }
48*eb293b8fSAndroid Build Coastguard Worker       ASSERT_NE(-1, pid_);
49*eb293b8fSAndroid Build Coastguard Worker       if (Attach(pid_)) {
50*eb293b8fSAndroid Build Coastguard Worker         return;
51*eb293b8fSAndroid Build Coastguard Worker       }
52*eb293b8fSAndroid Build Coastguard Worker       kill(pid_, SIGKILL);
53*eb293b8fSAndroid Build Coastguard Worker       waitpid(pid_, nullptr, 0);
54*eb293b8fSAndroid Build Coastguard Worker       pid_ = -1;
55*eb293b8fSAndroid Build Coastguard Worker     }
56*eb293b8fSAndroid Build Coastguard Worker     FAIL() << "Unable to fork and attach to process.";
57*eb293b8fSAndroid Build Coastguard Worker   }
58*eb293b8fSAndroid Build Coastguard Worker 
ForkAndWaitForPidState(const std::function<PidRunEnum ()> & state_check_func)59*eb293b8fSAndroid Build Coastguard Worker   void ForkAndWaitForPidState(const std::function<PidRunEnum()>& state_check_func) {
60*eb293b8fSAndroid Build Coastguard Worker     for (size_t i = 0; i < kMaxRetries; i++) {
61*eb293b8fSAndroid Build Coastguard Worker       ASSERT_NO_FATAL_FAILURE(Fork());
62*eb293b8fSAndroid Build Coastguard Worker 
63*eb293b8fSAndroid Build Coastguard Worker       if (WaitForPidStateAfterAttach(pid_, state_check_func)) {
64*eb293b8fSAndroid Build Coastguard Worker         return;
65*eb293b8fSAndroid Build Coastguard Worker       }
66*eb293b8fSAndroid Build Coastguard Worker       kill(pid_, SIGKILL);
67*eb293b8fSAndroid Build Coastguard Worker       waitpid(pid_, nullptr, 0);
68*eb293b8fSAndroid Build Coastguard Worker       pid_ = -1;
69*eb293b8fSAndroid Build Coastguard Worker     }
70*eb293b8fSAndroid Build Coastguard Worker     FAIL() << "Process never got to expected state.";
71*eb293b8fSAndroid Build Coastguard Worker   }
72*eb293b8fSAndroid Build Coastguard Worker 
TearDown()73*eb293b8fSAndroid Build Coastguard Worker   void TearDown() override {
74*eb293b8fSAndroid Build Coastguard Worker     if (pid_ == -1) {
75*eb293b8fSAndroid Build Coastguard Worker       return;
76*eb293b8fSAndroid Build Coastguard Worker     }
77*eb293b8fSAndroid Build Coastguard Worker     Detach(pid_);
78*eb293b8fSAndroid Build Coastguard Worker     kill(pid_, SIGKILL);
79*eb293b8fSAndroid Build Coastguard Worker     waitpid(pid_, nullptr, 0);
80*eb293b8fSAndroid Build Coastguard Worker   }
81*eb293b8fSAndroid Build Coastguard Worker 
82*eb293b8fSAndroid Build Coastguard Worker   pid_t pid_ = -1;
83*eb293b8fSAndroid Build Coastguard Worker   bool should_detach_ = true;
84*eb293b8fSAndroid Build Coastguard Worker   // Default to a run forever function.
85*eb293b8fSAndroid Build Coastguard Worker   std::function<void()> fork_func_ = []() {
86*eb293b8fSAndroid Build Coastguard Worker     while (true)
87*eb293b8fSAndroid Build Coastguard Worker       ;
88*eb293b8fSAndroid Build Coastguard Worker   };
89*eb293b8fSAndroid Build Coastguard Worker 
90*eb293b8fSAndroid Build Coastguard Worker   static constexpr size_t kMaxRetries = 3;
91*eb293b8fSAndroid Build Coastguard Worker };
92*eb293b8fSAndroid Build Coastguard Worker 
93*eb293b8fSAndroid Build Coastguard Worker }  // namespace unwindstack
94