• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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