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   ///     If \b true, then no data is collected until \a Resume is invoked.
44   ///     Similarly, if \b false, data is collected right away until \a Pause is
45   ///     invoked.
46   ///
47   /// \return
48   ///   A \a IntelPTSingleBufferTrace instance if tracing was successful, or
49   ///   an \a llvm::Error otherwise.
50   static llvm::Expected<IntelPTSingleBufferTrace>
51   Start(const TraceIntelPTStartRequest &request,
52         llvm::Optional<lldb::tid_t> tid,
53         llvm::Optional<lldb::core_id_t> core_id = llvm::None,
54         bool disabled = false);
55 
56   /// \return
57   ///    The bytes requested by a jLLDBTraceGetBinaryData packet that was routed
58   ///    to this trace instace.
59   llvm::Expected<std::vector<uint8_t>>
60   GetBinaryData(const TraceGetBinaryDataRequest &request) const;
61 
62   /// Read the trace buffer managed by this trace instance. To ensure that the
63   /// data is up-to-date and is not corrupted by read-write race conditions, the
64   /// underlying perf_event is paused during read, and later it's returned to
65   /// its initial state.
66   ///
67   /// \param[in] offset
68   ///     Offset of the data to read.
69   ///
70   /// \param[in] size
71   ///     Number of bytes to read.
72   ///
73   /// \return
74   ///     A vector with the requested binary data. The vector will have the
75   ///     size of the requested \a size. Non-available positions will be
76   ///     filled with zeroes.
77   llvm::Expected<std::vector<uint8_t>> GetTraceBuffer(size_t offset,
78                                                       size_t size);
79 
80   /// \return
81   ///     The total the size in bytes used by the trace buffer managed by this
82   ///     trace instance.
83   size_t GetTraceBufferSize() const;
84 
85   /// Resume the collection of this trace.
86   ///
87   /// \return
88   ///     An error if the trace couldn't be resumed. If the trace is already
89   ///     running, this returns \a Error::success().
90   llvm::Error Resume();
91 
92   /// Pause the collection of this trace.
93   ///
94   /// \return
95   ///     An error if the trace couldn't be paused. If the trace is already
96   ///     paused, this returns \a Error::success().
97   llvm::Error Pause();
98 
99   /// \return
100   ///     The underlying PerfEvent for this trace.
101   const PerfEvent &GetPerfEvent() const;
102 
103 private:
104   /// Construct new \a IntelPTSingleBufferThreadTrace. Users are supposed to
105   /// create instances of this class via the \a Start() method and not invoke
106   /// this one directly.
107   ///
108   /// \param[in] perf_event
109   ///   perf event configured for IntelPT.
110   ///
111   /// \param[in] collection_state
112   ///   The initial collection state for the provided perf_event.
113   IntelPTSingleBufferTrace(PerfEvent &&perf_event)
114       : m_perf_event(std::move(perf_event)) {}
115 
116   /// perf event configured for IntelPT.
117   PerfEvent m_perf_event;
118 };
119 
120 } // namespace process_linux
121 } // namespace lldb_private
122 
123 #endif // liblldb_IntelPTSingleBufferTrace_H_
124