1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SRC_PROFILING_PERF_PROC_DESCRIPTORS_H_ 18 #define SRC_PROFILING_PERF_PROC_DESCRIPTORS_H_ 19 20 #include <sys/types.h> 21 22 #include <map> 23 24 #include "perfetto/base/task_runner.h" 25 #include "perfetto/ext/base/scoped_file.h" 26 #include "perfetto/ext/base/unix_socket.h" 27 28 namespace perfetto { 29 30 // Callback interface for receiving /proc/<pid>/ file descriptors (proc-fds) 31 // from |ProcDescriptorGetter|. 32 class ProcDescriptorDelegate { 33 public: 34 virtual void OnProcDescriptors(pid_t pid, 35 uid_t uid, 36 base::ScopedFile maps_fd, 37 base::ScopedFile mem_fd) = 0; 38 39 virtual ~ProcDescriptorDelegate(); 40 }; 41 42 class ProcDescriptorGetter { 43 public: 44 virtual void GetDescriptorsForPid(pid_t pid) = 0; 45 virtual void SetDelegate(ProcDescriptorDelegate* delegate) = 0; 46 // TODO(b/151835887): attempt to remove the race condition in the Android 47 // platform itself, and remove this best-effort workaround. RequiresDelayedRequest()48 virtual bool RequiresDelayedRequest() { return false; } 49 50 virtual ~ProcDescriptorGetter(); 51 }; 52 53 // Directly opens /proc/<pid>/{maps,mem} files. Used when the daemon is running 54 // with sufficient privileges to do so. 55 class DirectDescriptorGetter : public ProcDescriptorGetter { 56 public: 57 void GetDescriptorsForPid(pid_t pid) override; 58 void SetDelegate(ProcDescriptorDelegate* delegate) override; 59 60 ~DirectDescriptorGetter() override; 61 62 private: 63 ProcDescriptorDelegate* delegate_ = nullptr; 64 }; 65 66 // Implementation of |ProcDescriptorGetter| used when running as a system daemon 67 // on Android. Uses a socket inherited from |init| and platform signal handlers 68 // to obtain the proc-fds. 69 class AndroidRemoteDescriptorGetter : public ProcDescriptorGetter, 70 public base::UnixSocket::EventListener { 71 public: AndroidRemoteDescriptorGetter(int listening_raw_socket,base::TaskRunner * task_runner)72 AndroidRemoteDescriptorGetter(int listening_raw_socket, 73 base::TaskRunner* task_runner) { 74 listening_socket_ = base::UnixSocket::Listen( 75 base::ScopedFile(listening_raw_socket), this, task_runner, 76 base::SockFamily::kUnix, base::SockType::kStream); 77 } 78 79 // ProcDescriptorGetter impl: 80 void GetDescriptorsForPid(pid_t pid) override; 81 void SetDelegate(ProcDescriptorDelegate* delegate) override; RequiresDelayedRequest()82 bool RequiresDelayedRequest() override { return true; } 83 84 // UnixSocket::EventListener impl: 85 void OnNewIncomingConnection( 86 base::UnixSocket*, 87 std::unique_ptr<base::UnixSocket> new_connection) override; 88 void OnDataAvailable(base::UnixSocket* self) override; 89 void OnDisconnect(base::UnixSocket* self) override; 90 91 ~AndroidRemoteDescriptorGetter() override; 92 93 private: 94 ProcDescriptorDelegate* delegate_ = nullptr; 95 std::unique_ptr<base::UnixSocket> listening_socket_; 96 // Holds onto connections until we receive the file descriptors (keyed by 97 // their raw addresses, which the map keeps stable). 98 std::map<base::UnixSocket*, std::unique_ptr<base::UnixSocket>> 99 active_connections_; 100 }; 101 102 } // namespace perfetto 103 104 #endif // SRC_PROFILING_PERF_PROC_DESCRIPTORS_H_ 105