1 //===-- IntelPTMultiCoreTrace.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_IntelPTMultiCoreTrace_H_
10 #define liblldb_IntelPTMultiCoreTrace_H_
11 
12 #include "IntelPTSingleBufferTrace.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 class IntelPTMultiCoreTrace;
25 using IntelPTMultiCoreTraceUP = std::unique_ptr<IntelPTMultiCoreTrace>;
26 
27 class IntelPTMultiCoreTrace {
28 public:
29   /// Start tracing all CPU cores.
30   ///
31   /// \param[in] request
32   ///   Intel PT configuration parameters.
33   ///
34   /// \return
35   ///   An \a IntelPTMultiCoreTrace instance if tracing was successful, or
36   ///   an \a llvm::Error otherwise.
37   static llvm::Expected<IntelPTMultiCoreTraceUP>
38   StartOnAllCores(const TraceIntelPTStartRequest &request);
39 
40   /// Execute the provided callback on each core that is being traced.
41   ///
42   /// \param[in] callback.core_id
43   ///   The core id that is being traced.
44   ///
45   /// \param[in] callback.core_trace
46   ///   The single-buffer trace instance for the given core.
47   void ForEachCore(std::function<void(lldb::core_id_t core_id,
48                                       IntelPTSingleBufferTrace &core_trace)>
49                        callback);
50 
51   /// This method should be invoked as early as possible whenever the process
52   /// resumes or stops so that intel-pt collection is not enabled when
53   /// the process is not running. This is done to prevent polluting the core
54   /// traces with executions of unrelated processes, which increases the data
55   /// loss of the target process, given that core traces don't filter by
56   /// process.
57   /// A possible way to avoid this is to use CR3 filtering, which is equivalent
58   /// to process filtering, but the perf_event API doesn't support it.
59   void OnProcessStateChanged(lldb::StateType state);
60 
61 private:
62   IntelPTMultiCoreTrace(
63       llvm::DenseMap<lldb::core_id_t, IntelPTSingleBufferTraceUP>
64           &&traces_per_core)
65       : m_traces_per_core(std::move(traces_per_core)) {}
66 
67   llvm::DenseMap<lldb::core_id_t, IntelPTSingleBufferTraceUP> m_traces_per_core;
68 
69   /// The initial state is stopped because tracing can only start when the
70   /// process is paused.
71   lldb::StateType m_process_state = lldb::StateType::eStateStopped;
72 };
73 
74 } // namespace process_linux
75 } // namespace lldb_private
76 
77 #endif // liblldb_IntelPTMultiCoreTrace_H_
78