1 //===-- DarwinLogCollector.h ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGCOLLECTOR_H
10 #define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGCOLLECTOR_H
11 
12 #include <sys/types.h>
13 
14 #include <memory>
15 #include <mutex>
16 #include <unordered_map>
17 
18 #include "ActivityStore.h"
19 #include "ActivityStreamSPI.h"
20 #include "DNBDefs.h"
21 #include "DarwinLogEvent.h"
22 #include "DarwinLogInterfaces.h"
23 #include "JSON.h"
24 
25 class DarwinLogCollector;
26 typedef std::shared_ptr<DarwinLogCollector> DarwinLogCollectorSP;
27 
28 class DarwinLogCollector
29     : public std::enable_shared_from_this<DarwinLogCollector>,
30       public ActivityStore {
31 public:
32   /// Return whether the os_log and activity tracing SPI is available.
33   ///
34   /// \return \b true if the activity stream support is available,
35   /// \b false otherwise.
36   static bool IsSupported();
37 
38   /// Return a log function suitable for DNBLog to use as the internal
39   /// logging function.
40   ///
41   /// \return a DNBLog-style logging function if IsSupported() returns
42   ///      true; otherwise, returns nullptr.
43   static DNBCallbackLog GetLogFunction();
44 
45   static bool StartCollectingForProcess(nub_process_t pid,
46                                         const JSONObject &config);
47 
48   static bool CancelStreamForProcess(nub_process_t pid);
49 
50   static DarwinLogEventVector GetEventsForProcess(nub_process_t pid);
51 
52   ~DarwinLogCollector();
53 
GetProcessID()54   pid_t GetProcessID() const { return m_pid; }
55 
56   // ActivityStore API
57   const char *GetActivityForID(os_activity_id_t activity_id) const override;
58 
59   std::string
60   GetActivityChainForID(os_activity_id_t activity_id) const override;
61 
62 private:
63   DarwinLogCollector() = delete;
64   DarwinLogCollector(const DarwinLogCollector &) = delete;
65   DarwinLogCollector &operator=(const DarwinLogCollector &) = delete;
66 
67   explicit DarwinLogCollector(nub_process_t pid,
68                               const LogFilterChainSP &filter_chain_sp);
69 
70   void SignalDataAvailable();
71 
72   void SetActivityStream(os_activity_stream_t activity_stream);
73 
74   bool HandleStreamEntry(os_activity_stream_entry_t entry, int error);
75 
76   DarwinLogEventVector RemoveEvents();
77 
78   void CancelActivityStream();
79 
80   void GetActivityChainForID_internal(os_activity_id_t activity_id,
81                                       std::string &result, size_t depth) const;
82 
83   struct ActivityInfo {
ActivityInfoActivityInfo84     ActivityInfo(const char *name, os_activity_id_t activity_id,
85                  os_activity_id_t parent_activity_id)
86         : m_name(name), m_id(activity_id), m_parent_id(parent_activity_id) {}
87 
88     const std::string m_name;
89     const os_activity_id_t m_id;
90     const os_activity_id_t m_parent_id;
91   };
92 
93   using ActivityMap = std::unordered_map<os_activity_id_t, ActivityInfo>;
94 
95   const nub_process_t m_pid;
96   os_activity_stream_t m_activity_stream;
97   DarwinLogEventVector m_events;
98   std::mutex m_events_mutex;
99   LogFilterChainSP m_filter_chain_sp;
100 
101   /// Mutex to protect activity info (activity name and parent structures)
102   mutable std::mutex m_activity_info_mutex;
103   /// Map of activity id to ActivityInfo
104   ActivityMap m_activity_map;
105 };
106 
107 #endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_DARWINLOG_DARWINLOGCOLLECTOR_H
108