• 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                                  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