/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SRC_PROFILING_PERF_PROC_DESCRIPTORS_H_ #define SRC_PROFILING_PERF_PROC_DESCRIPTORS_H_ #include #include #include "perfetto/base/task_runner.h" #include "perfetto/ext/base/scoped_file.h" #include "perfetto/ext/base/unix_socket.h" namespace perfetto { // Callback interface for receiving /proc// file descriptors (proc-fds) // from |ProcDescriptorGetter|. class ProcDescriptorDelegate { public: virtual void OnProcDescriptors(pid_t pid, uid_t uid, base::ScopedFile maps_fd, base::ScopedFile mem_fd) = 0; virtual ~ProcDescriptorDelegate(); }; class ProcDescriptorGetter { public: virtual void GetDescriptorsForPid(pid_t pid) = 0; virtual void SetDelegate(ProcDescriptorDelegate* delegate) = 0; // TODO(b/151835887): attempt to remove the race condition in the Android // platform itself, and remove this best-effort workaround. virtual bool RequiresDelayedRequest() { return false; } virtual ~ProcDescriptorGetter(); }; // Directly opens /proc//{maps,mem} files. Used when the daemon is running // with sufficient privileges to do so. class DirectDescriptorGetter : public ProcDescriptorGetter { public: void GetDescriptorsForPid(pid_t pid) override; void SetDelegate(ProcDescriptorDelegate* delegate) override; ~DirectDescriptorGetter() override; private: ProcDescriptorDelegate* delegate_ = nullptr; }; // Implementation of |ProcDescriptorGetter| used when running as a system daemon // on Android. Uses a socket inherited from |init| and platform signal handlers // to obtain the proc-fds. class AndroidRemoteDescriptorGetter : public ProcDescriptorGetter, public base::UnixSocket::EventListener { public: AndroidRemoteDescriptorGetter(int listening_raw_socket, base::TaskRunner* task_runner) { listening_socket_ = base::UnixSocket::Listen( base::ScopedFile(listening_raw_socket), this, task_runner, base::SockFamily::kUnix, base::SockType::kStream); } // ProcDescriptorGetter impl: void GetDescriptorsForPid(pid_t pid) override; void SetDelegate(ProcDescriptorDelegate* delegate) override; bool RequiresDelayedRequest() override { return true; } // UnixSocket::EventListener impl: void OnNewIncomingConnection( base::UnixSocket*, std::unique_ptr new_connection) override; void OnDataAvailable(base::UnixSocket* self) override; void OnDisconnect(base::UnixSocket* self) override; ~AndroidRemoteDescriptorGetter() override; private: ProcDescriptorDelegate* delegate_ = nullptr; std::unique_ptr listening_socket_; // Holds onto connections until we receive the file descriptors (keyed by // their raw addresses, which the map keeps stable). std::map> active_connections_; }; } // namespace perfetto #endif // SRC_PROFILING_PERF_PROC_DESCRIPTORS_H_