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] cpu_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::cpu_id_t> cpu_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 intel pt trace buffer managed by this trace instance. To ensure
63   /// that the data is up-to-date and is not corrupted by read-write race
64   /// conditions, the underlying perf_event is paused during read, and later
65   /// it's returned to its initial state.
66   ///
67   /// \return
68   ///     A vector with the requested binary data.
69   llvm::Expected<std::vector<uint8_t>> GetIptTrace();
70 
71   /// \return
72   ///     The total the size in bytes used by the intel pt trace buffer managed
73   ///     by this trace instance.
74   size_t GetIptTraceSize() const;
75 
76   /// Resume the collection of this trace.
77   ///
78   /// \return
79   ///     An error if the trace couldn't be resumed. If the trace is already
80   ///     running, this returns \a Error::success().
81   llvm::Error Resume();
82 
83   /// Pause the collection of this trace.
84   ///
85   /// \return
86   ///     An error if the trace couldn't be paused. If the trace is already
87   ///     paused, this returns \a Error::success().
88   llvm::Error Pause();
89 
90   /// \return
91   ///     The underlying PerfEvent for this trace.
92   const PerfEvent &GetPerfEvent() const;
93 
94 private:
95   /// Construct new \a IntelPTSingleBufferThreadTrace. Users are supposed to
96   /// create instances of this class via the \a Start() method and not invoke
97   /// this one directly.
98   ///
99   /// \param[in] perf_event
100   ///   perf event configured for IntelPT.
101   ///
102   /// \param[in] collection_state
103   ///   The initial collection state for the provided perf_event.
104   IntelPTSingleBufferTrace(PerfEvent &&perf_event)
105       : m_perf_event(std::move(perf_event)) {}
106 
107   /// perf event configured for IntelPT.
108   PerfEvent m_perf_event;
109 };
110 
111 } // namespace process_linux
112 } // namespace lldb_private
113 
114 #endif // liblldb_IntelPTSingleBufferTrace_H_
115