1 //===-- IntelPTSingleBufferTrace.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_IntelPTSingleBufferTrace_H_
10 #define liblldb_IntelPTSingleBufferTrace_H_
11 
12 #include "Perf.h"
13 
14 #include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
15 #include "lldb/lldb-types.h"
16 
17 #include "llvm/Support/Error.h"
18 
19 #include <memory>
20 
21 namespace lldb_private {
22 namespace process_linux {
23 
24 llvm::Expected<uint32_t> GetIntelPTOSEventType();
25 
26 /// This class wraps a single perf event collecting intel pt data in a single
27 /// buffer.
28 class IntelPTSingleBufferTrace {
29 public:
30   /// Start tracing using a single Intel PT trace buffer.
31   ///
32   /// \param[in] request
33   ///     Intel PT configuration parameters.
34   ///
35   /// \param[in] tid
36   ///     The tid of the thread to be traced. If \b None, then this traces all
37   ///     threads of all processes.
38   ///
39   /// \param[in] core_id
40   ///     The CPU core id where to trace. If \b None, then this traces all CPUs.
41   ///
42   /// \param[in] disabled
43   ///     Whether to start the tracing paused.
44   ///
45   /// \return
46   ///   A \a IntelPTSingleBufferTrace instance if tracing was successful, or
47   ///   an \a llvm::Error otherwise.
48   static llvm::Expected<IntelPTSingleBufferTrace>
49   Start(const TraceIntelPTStartRequest &request,
50         llvm::Optional<lldb::tid_t> tid,
51         llvm::Optional<lldb::core_id_t> core_id = llvm::None,
52         bool disabled = false);
53 
54   /// \return
55   ///    The bytes requested by a jLLDBTraceGetBinaryData packet that was routed
56   ///    to this trace instace.
57   llvm::Expected<std::vector<uint8_t>>
58   GetBinaryData(const TraceGetBinaryDataRequest &request) const;
59 
60   /// Read the trace buffer managed by this trace instance. To ensure that the
61   /// data is up-to-date and is not corrupted by read-write race conditions, the
62   /// underlying perf_event is paused during read, and later it's returned to
63   /// its initial state.
64   ///
65   /// \param[in] offset
66   ///     Offset of the data to read.
67   ///
68   /// \param[in] size
69   ///     Number of bytes to read.
70   ///
71   /// \return
72   ///     A vector with the requested binary data. The vector will have the
73   ///     size of the requested \a size. Non-available positions will be
74   ///     filled with zeroes.
75   llvm::Expected<std::vector<uint8_t>> GetTraceBuffer(size_t offset,
76                                                       size_t size);
77 
78   /// \return
79   ///     The total the size in bytes used by the trace buffer managed by this
80   ///     trace instance.
81   size_t GetTraceBufferSize() const;
82 
83   /// Resume the collection of this trace.
84   ///
85   /// \return
86   ///     An error if the trace couldn't be resumed. If the trace is already
87   ///     running, this returns \a Error::success().
88   llvm::Error Resume();
89 
90   /// Pause the collection of this trace.
91   ///
92   /// \return
93   ///     An error if the trace couldn't be paused. If the trace is already
94   ///     paused, this returns \a Error::success().
95   llvm::Error Pause();
96 
97   /// \return
98   ///     The underlying PerfEvent for this trace.
99   const PerfEvent &GetPerfEvent() const;
100 
101 private:
102   /// Construct new \a IntelPTSingleBufferThreadTrace. Users are supposed to
103   /// create instances of this class via the \a Start() method and not invoke
104   /// this one directly.
105   ///
106   /// \param[in] perf_event
107   ///   perf event configured for IntelPT.
108   ///
109   /// \param[in] collection_state
110   ///   The initial collection state for the provided perf_event.
111   IntelPTSingleBufferTrace(PerfEvent &&perf_event)
112       : m_perf_event(std::move(perf_event)) {}
113 
114   /// perf event configured for IntelPT.
115   PerfEvent m_perf_event;
116 };
117 
118 } // namespace process_linux
119 } // namespace lldb_private
120 
121 #endif // liblldb_IntelPTSingleBufferTrace_H_
122