1 //===-- IntelPTCollector.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 liblldb_IntelPTCollector_H_
10 #define liblldb_IntelPTCollector_H_
11 
12 #include "Perf.h"
13 
14 #include "IntelPTSingleBufferTrace.h"
15 
16 #include "lldb/Utility/Status.h"
17 #include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
18 #include "lldb/lldb-types.h"
19 
20 #include <linux/perf_event.h>
21 #include <sys/mman.h>
22 #include <unistd.h>
23 
24 namespace lldb_private {
25 
26 namespace process_linux {
27 
28 /// Manages a list of thread traces.
29 class IntelPTThreadTraceCollection {
30 public:
31   IntelPTThreadTraceCollection() {}
32 
33   /// Dispose of all traces
34   void Clear();
35 
36   bool TracesThread(lldb::tid_t tid) const;
37 
38   size_t GetTotalBufferSize() const;
39 
40   std::vector<TraceThreadState> GetThreadStates() const;
41 
42   llvm::Expected<const IntelPTSingleBufferTrace &>
43   GetTracedThread(lldb::tid_t tid) const;
44 
45   llvm::Error TraceStart(lldb::tid_t tid,
46                          const TraceIntelPTStartRequest &request);
47 
48   llvm::Error TraceStop(lldb::tid_t tid);
49 
50 private:
51   llvm::DenseMap<lldb::tid_t, IntelPTSingleBufferTraceUP> m_thread_traces;
52   /// Total actual thread buffer size in bytes
53   size_t m_total_buffer_size = 0;
54 };
55 
56 /// Manages a "process trace" instance.
57 class IntelPTProcessTrace {
58 public:
59   IntelPTProcessTrace(const TraceIntelPTStartRequest &request)
60       : m_tracing_params(request) {}
61 
62   bool TracesThread(lldb::tid_t tid) const;
63 
64   const IntelPTThreadTraceCollection &GetThreadTraces() const;
65 
66   llvm::Error TraceStart(lldb::tid_t tid);
67 
68   llvm::Error TraceStop(lldb::tid_t tid);
69 
70 private:
71   IntelPTThreadTraceCollection m_thread_traces;
72   /// Params used to trace threads when the user started "process tracing".
73   TraceIntelPTStartRequest m_tracing_params;
74 };
75 
76 /// Main class that manages intel-pt process and thread tracing.
77 class IntelPTCollector {
78 public:
79   IntelPTCollector();
80 
81   static bool IsSupported();
82 
83   /// If "process tracing" is enabled, then trace the given thread.
84   llvm::Error OnThreadCreated(lldb::tid_t tid);
85 
86   /// Stops tracing a tracing upon a destroy event.
87   llvm::Error OnThreadDestroyed(lldb::tid_t tid);
88 
89   /// Implementation of the jLLDBTraceStop packet
90   llvm::Error TraceStop(const TraceStopRequest &request);
91 
92   /// Implementation of the jLLDBTraceStart packet
93   ///
94   /// \param[in] process_threads
95   ///     A list of all threads owned by the process.
96   llvm::Error TraceStart(const TraceIntelPTStartRequest &request,
97                          const std::vector<lldb::tid_t> &process_threads);
98 
99   /// Implementation of the jLLDBTraceGetState packet
100   llvm::Expected<llvm::json::Value> GetState() const;
101 
102   /// Implementation of the jLLDBTraceGetBinaryData packet
103   llvm::Expected<std::vector<uint8_t>>
104   GetBinaryData(const TraceGetBinaryDataRequest &request) const;
105 
106   /// Dispose of all traces
107   void Clear();
108 
109 private:
110   llvm::Error TraceStop(lldb::tid_t tid);
111 
112   /// Start tracing a specific thread.
113   llvm::Error TraceStart(lldb::tid_t tid,
114                          const TraceIntelPTStartRequest &request);
115 
116   llvm::Expected<const IntelPTSingleBufferTrace &>
117   GetTracedThread(lldb::tid_t tid) const;
118 
119   bool IsProcessTracingEnabled() const;
120 
121   void ClearProcessTracing();
122 
123   /// Threads traced due to "thread tracing"
124   IntelPTThreadTraceCollection m_thread_traces;
125   /// Threads traced due to "process tracing". Only one active "process tracing"
126   /// instance is assumed for a single process.
127   llvm::Optional<IntelPTProcessTrace> m_process_trace;
128   /// TSC to wall time conversion.
129   TraceTscConversionUP m_tsc_conversion;
130 };
131 
132 } // namespace process_linux
133 } // namespace lldb_private
134 
135 #endif // liblldb_IntelPTCollector_H_
136