1911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao/* 2911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * Copyright (C) 2016 The Android Open Source Project 3911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * 4911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * Licensed under the Apache License, Version 2.0 (the "License"); 5911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * you may not use this file except in compliance with the License. 6911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * You may obtain a copy of the License at 7911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * 8911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * http://www.apache.org/licenses/LICENSE-2.0 9911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * 10911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * Unless required by applicable law or agreed to in writing, software 11911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * distributed under the License is distributed on an "AS IS" BASIS, 12911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * See the License for the specific language governing permissions and 14911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao * limitations under the License. 15911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao */ 16911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 17911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#include <procinfo/process.h> 18911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 19911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#include <fcntl.h> 20911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#include <stdlib.h> 21911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#include <sys/types.h> 22911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#include <unistd.h> 23911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 249cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao#include <chrono> 25911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#include <set> 26911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#include <thread> 27911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#include <vector> 28911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 29911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#include <gtest/gtest.h> 30911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 31911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#include <android-base/stringprintf.h> 32911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 339cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gaousing namespace std::chrono_literals; 349cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao 35911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#if !defined(__BIONIC__) 36911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#include <syscall.h> 37911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gaostatic pid_t gettid() { 38911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao return syscall(__NR_gettid); 39911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao} 40911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao#endif 41911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 42911d729c8a01fbc052a8e15322bad5413a1138a9Josh GaoTEST(process_info, process_info_smoke) { 43911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao android::procinfo::ProcessInfo self; 44911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_TRUE(android::procinfo::GetProcessInfo(gettid(), &self)); 45911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(gettid(), self.tid); 46911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(getpid(), self.pid); 47911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(getppid(), self.ppid); 48911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(getuid(), self.uid); 49911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(getgid(), self.gid); 50911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao} 51911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 52911d729c8a01fbc052a8e15322bad5413a1138a9Josh GaoTEST(process_info, process_info_proc_pid_fd_smoke) { 53911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao android::procinfo::ProcessInfo self; 54911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao int fd = open(android::base::StringPrintf("/proc/%d", gettid()).c_str(), O_DIRECTORY | O_RDONLY); 55911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_NE(-1, fd); 56911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_TRUE(android::procinfo::GetProcessInfoFromProcPidFd(fd, &self)); 57911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 58911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao // Process name is capped at 15 bytes. 59911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ("libprocinfo_tes", self.name); 60911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(gettid(), self.tid); 61911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(getpid(), self.pid); 62911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(getppid(), self.ppid); 63911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(getuid(), self.uid); 64911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(getgid(), self.gid); 65911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao close(fd); 66911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao} 67911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 68911d729c8a01fbc052a8e15322bad5413a1138a9Josh GaoTEST(process_info, process_tids_smoke) { 69911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao pid_t main_tid = gettid(); 70911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao std::thread([main_tid]() { 71911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao pid_t thread_tid = gettid(); 72911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 73911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao { 74911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao std::vector<pid_t> vec; 75911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_TRUE(android::procinfo::GetProcessTids(getpid(), &vec)); 76911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(1, std::count(vec.begin(), vec.end(), main_tid)); 77911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(1, std::count(vec.begin(), vec.end(), thread_tid)); 78911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao } 79911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao 80911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao { 81911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao std::set<pid_t> set; 82911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_TRUE(android::procinfo::GetProcessTids(getpid(), &set)); 83911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(1, std::count(set.begin(), set.end(), main_tid)); 84911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao ASSERT_EQ(1, std::count(set.begin(), set.end(), thread_tid)); 85911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao } 86911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao }).join(); 87911d729c8a01fbc052a8e15322bad5413a1138a9Josh Gao} 889cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao 899cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh GaoTEST(process_info, process_state) { 909cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao int pipefd[2]; 919cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao ASSERT_EQ(0, pipe2(pipefd, O_CLOEXEC)); 929cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao pid_t forkpid = fork(); 939cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao 949cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao ASSERT_NE(-1, forkpid); 959cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao if (forkpid == 0) { 969cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao close(pipefd[1]); 979cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao char buf; 989cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao TEMP_FAILURE_RETRY(read(pipefd[0], &buf, 1)); 999cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao _exit(0); 1009cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao } 1019cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao 1029cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao // Give the child some time to get to the read. 1039cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao std::this_thread::sleep_for(100ms); 1049cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao 1059cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao android::procinfo::ProcessInfo procinfo; 1069cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao ASSERT_TRUE(android::procinfo::GetProcessInfo(forkpid, &procinfo)); 1079cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao ASSERT_EQ(android::procinfo::kProcessStateSleeping, procinfo.state); 1089cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao 1099cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao ASSERT_EQ(0, kill(forkpid, SIGKILL)); 1109cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao 1119cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao // Give the kernel some time to kill the child. 1129cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao std::this_thread::sleep_for(100ms); 1139cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao 1149cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao ASSERT_TRUE(android::procinfo::GetProcessInfo(forkpid, &procinfo)); 1159cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao ASSERT_EQ(android::procinfo::kProcessStateZombie, procinfo.state); 1169cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao 1179cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao ASSERT_EQ(forkpid, waitpid(forkpid, nullptr, 0)); 1189cb2e2eb8cefcfca5133d01f29ab29005e1f2a46Josh Gao} 119