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 base::ScopedFile maps_fd, 36 base::ScopedFile mem_fd) = 0; 37 38 virtual ~ProcDescriptorDelegate(); 39 }; 40 41 class ProcDescriptorGetter { 42 public: 43 virtual void GetDescriptorsForPid(pid_t pid) = 0; 44 virtual void SetDelegate(ProcDescriptorDelegate* delegate) = 0; 45 // TODO(b/151835887): attempt to remove the race condition in the Android 46 // platform itself, and remove this best-effort workaround. RequiresDelayedRequest()47 virtual bool RequiresDelayedRequest() { return false; } 48 49 virtual ~ProcDescriptorGetter(); 50 }; 51 52 // Directly opens /proc/<pid>/{maps,mem} files. Used when the daemon is running 53 // with sufficient privileges to do so. 54 class DirectDescriptorGetter : public ProcDescriptorGetter { 55 public: 56 void GetDescriptorsForPid(pid_t pid) override; 57 void SetDelegate(ProcDescriptorDelegate* delegate) override; 58 59 ~DirectDescriptorGetter() override; 60 61 private: 62 ProcDescriptorDelegate* delegate_ = nullptr; 63 }; 64 65 // Implementation of |ProcDescriptorGetter| used when running as a system daemon 66 // on Android. Uses a socket inherited from |init| and platform signal handlers 67 // to obtain the proc-fds. 68 class AndroidRemoteDescriptorGetter : public ProcDescriptorGetter, 69 public base::UnixSocket::EventListener { 70 public: AndroidRemoteDescriptorGetter(int listening_raw_socket,base::TaskRunner * task_runner)71 AndroidRemoteDescriptorGetter(int listening_raw_socket, 72 base::TaskRunner* task_runner) { 73 listening_socket_ = base::UnixSocket::Listen( 74 base::ScopedFile(listening_raw_socket), this, task_runner, 75 base::SockFamily::kUnix, base::SockType::kStream); 76 } 77 78 // ProcDescriptorGetter impl: 79 void GetDescriptorsForPid(pid_t pid) override; 80 void SetDelegate(ProcDescriptorDelegate* delegate) override; RequiresDelayedRequest()81 bool RequiresDelayedRequest() override { return true; } 82 83 // UnixSocket::EventListener impl: 84 void OnNewIncomingConnection( 85 base::UnixSocket*, 86 std::unique_ptr<base::UnixSocket> new_connection) override; 87 void OnDataAvailable(base::UnixSocket* self) override; 88 void OnDisconnect(base::UnixSocket* self) override; 89 90 ~AndroidRemoteDescriptorGetter() override; 91 92 private: 93 ProcDescriptorDelegate* delegate_ = nullptr; 94 std::unique_ptr<base::UnixSocket> listening_socket_; 95 // Holds onto connections until we receive the file descriptors (keyed by 96 // their raw addresses, which the map keeps stable). 97 std::map<base::UnixSocket*, std::unique_ptr<base::UnixSocket>> 98 active_connections_; 99 }; 100 101 } // namespace perfetto 102 103 #endif // SRC_PROFILING_PERF_PROC_DESCRIPTORS_H_ 104