brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.2 KiB · da9cefe Raw
294 lines · c
1//===-- TraceIntelPT.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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H10#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H11 12#include "TaskTimer.h"13#include "ThreadDecoder.h"14#include "TraceIntelPTBundleLoader.h"15#include "TraceIntelPTMultiCpuDecoder.h"16#include "lldb/Utility/FileSpec.h"17#include "lldb/lldb-types.h"18#include "llvm/Support/raw_ostream.h"19#include <optional>20 21namespace lldb_private {22namespace trace_intel_pt {23 24class TraceIntelPT : public Trace {25public:26  /// Properties to be used with the `settings` command.27  class PluginProperties : public Properties {28  public:29    static llvm::StringRef GetSettingName();30 31    PluginProperties();32 33    ~PluginProperties() override = default;34 35    uint64_t GetInfiniteDecodingLoopVerificationThreshold();36 37    uint64_t GetExtremelyLargeDecodingThreshold();38  };39 40  /// Return the global properties for this trace plug-in.41  static PluginProperties &GetGlobalProperties();42 43  void Dump(Stream *s) const override;44 45  llvm::Expected<FileSpec> SaveToDisk(FileSpec directory,46                                      bool compact) override;47 48  ~TraceIntelPT() override = default;49 50  /// PluginInterface protocol51  /// \{52  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }53 54  static void Initialize();55 56  static void Terminate();57 58  /// Create an instance of this class from a trace bundle.59  ///60  /// \param[in] trace_bundle_description61  ///     The description of the trace bundle. See \a Trace::FindPlugin.62  ///63  /// \param[in] bundle_dir64  ///     The path to the directory that contains the trace bundle.65  ///66  /// \param[in] debugger67  ///     The debugger instance where new Targets will be created as part of the68  ///     JSON data parsing.69  ///70  /// \return71  ///     A trace instance or an error in case of failures.72  static llvm::Expected<lldb::TraceSP> CreateInstanceForTraceBundle(73      const llvm::json::Value &trace_bundle_description,74      llvm::StringRef bundle_dir, Debugger &debugger);75 76  static llvm::Expected<lldb::TraceSP>77  CreateInstanceForLiveProcess(Process &process);78 79  static llvm::StringRef GetPluginNameStatic() { return "intel-pt"; }80 81  static void DebuggerInitialize(Debugger &debugger);82  /// \}83 84  lldb::CommandObjectSP85  GetProcessTraceStartCommand(CommandInterpreter &interpreter) override;86 87  lldb::CommandObjectSP88  GetThreadTraceStartCommand(CommandInterpreter &interpreter) override;89 90  llvm::StringRef GetSchema() override;91 92  llvm::Expected<lldb::TraceCursorSP> CreateNewCursor(Thread &thread) override;93 94  void DumpTraceInfo(Thread &thread, Stream &s, bool verbose,95                     bool json) override;96 97  llvm::Expected<std::optional<uint64_t>> GetRawTraceSize(Thread &thread);98 99  llvm::Error DoRefreshLiveProcessState(TraceGetStateResponse state,100                                        llvm::StringRef json_response) override;101 102  bool IsTraced(lldb::tid_t tid) override;103 104  const char *GetStartConfigurationHelp() override;105 106  /// Start tracing a live process.107  ///108  /// More information on the parameters below can be found in the109  /// jLLDBTraceStart section in lldb/docs/lldb-gdb-remote.txt.110  ///111  /// \param[in] ipt_trace_size112  ///     Trace size per thread in bytes.113  ///114  /// \param[in] total_buffer_size_limit115  ///     Maximum total trace size per process in bytes.116  ///117  /// \param[in] enable_tsc118  ///     Whether to use enable TSC timestamps or not.119  ///120  /// \param[in] psb_period121  ///     This value defines the period in which PSB packets will be generated.122  ///123  /// \param[in] per_cpu_tracing124  ///     This value defines whether to have an intel pt trace buffer per thread125  ///     or per cpu core.126  ///127  /// \param[in] disable_cgroup_filtering128  ///     Disable the cgroup filtering that is automatically applied when doing129  ///     per cpu tracing.130  ///131  /// \return132  ///     \a llvm::Error::success if the operation was successful, or133  ///     \a llvm::Error otherwise.134  llvm::Error Start(uint64_t ipt_trace_size, uint64_t total_buffer_size_limit,135                    bool enable_tsc, std::optional<uint64_t> psb_period,136                    bool m_per_cpu_tracing, bool disable_cgroup_filtering);137 138  /// \copydoc Trace::Start139  llvm::Error Start(StructuredData::ObjectSP configuration =140                        StructuredData::ObjectSP()) override;141 142  /// Start tracing live threads.143  ///144  /// More information on the parameters below can be found in the145  /// jLLDBTraceStart section in lldb/docs/lldb-gdb-remote.txt.146  ///147  /// \param[in] tids148  ///     Threads to trace.149  ///150  /// \param[in] ipt_trace_size151  ///     Trace size per thread or per cpu core in bytes.152  ///153  /// \param[in] enable_tsc154  ///     Whether to use enable TSC timestamps or not.155  ///156  /// \param[in] psb_period157  ///     This value defines the period in which PSB packets will be generated.158  ///159  /// \return160  ///     \a llvm::Error::success if the operation was successful, or161  ///     \a llvm::Error otherwise.162  llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids, uint64_t ipt_trace_size,163                    bool enable_tsc, std::optional<uint64_t> psb_period);164 165  /// \copydoc Trace::Start166  llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids,167                    StructuredData::ObjectSP configuration =168                        StructuredData::ObjectSP()) override;169 170  /// See \a Trace::OnThreadBinaryDataRead().171  llvm::Error OnThreadBufferRead(lldb::tid_t tid,172                                 OnBinaryDataReadCallback callback);173 174  /// Get or fetch the cpu information from, for example, /proc/cpuinfo.175  llvm::Expected<pt_cpu> GetCPUInfo();176 177  /// Get or fetch the values used to convert to and from TSCs and nanos.178  std::optional<LinuxPerfZeroTscConversion> GetPerfZeroTscConversion();179 180  /// \return181  ///     The timer object for this trace.182  TaskTimer &GetTimer();183 184  /// \return185  ///     The ScopedTaskTimer object for the given thread in this trace.186  ScopedTaskTimer &GetThreadTimer(lldb::tid_t tid);187 188  /// \return189  ///     The global copedTaskTimer object for this trace.190  ScopedTaskTimer &GetGlobalTimer();191 192  TraceIntelPTSP GetSharedPtr();193 194  enum class TraceMode { UserMode, KernelMode };195 196  TraceMode GetTraceMode();197 198private:199  friend class TraceIntelPTBundleLoader;200 201  llvm::Expected<pt_cpu> GetCPUInfoForLiveProcess();202 203  /// Postmortem trace constructor204  ///205  /// \param[in] bundle_description206  ///     The definition file for the postmortem bundle.207  ///208  /// \param[in] traced_processes209  ///     The processes traced in the postmortem session.210  ///211  /// \param[in] trace_threads212  ///     The threads traced in the postmortem session. They must belong to the213  ///     processes mentioned above.214  ///215  /// \param[in] trace_mode216  ///     The tracing mode of the postmortem session.217  ///218  /// \return219  ///     A TraceIntelPT shared pointer instance.220  /// \{221  static TraceIntelPTSP CreateInstanceForPostmortemTrace(222      JSONTraceBundleDescription &bundle_description,223      llvm::ArrayRef<lldb::ProcessSP> traced_processes,224      llvm::ArrayRef<lldb::ThreadPostMortemTraceSP> traced_threads,225      TraceMode trace_mode);226 227  /// This constructor is used by CreateInstanceForPostmortemTrace to get the228  /// instance ready before using shared pointers, which is a limitation of C++.229  TraceIntelPT(JSONTraceBundleDescription &bundle_description,230               llvm::ArrayRef<lldb::ProcessSP> traced_processes,231               TraceMode trace_mode);232  /// \}233 234  /// Constructor for live processes235  TraceIntelPT(Process &live_process)236      : Trace(live_process), trace_mode(TraceMode::UserMode){};237 238  /// Decode the trace of the given thread that, i.e. recontruct the traced239  /// instructions.240  ///241  /// \param[in] thread242  ///     If \a thread is a \a ThreadTrace, then its internal trace file will be243  ///     decoded. Live threads are not currently supported.244  ///245  /// \return246  ///     A \a DecodedThread shared pointer with the decoded instructions. Any247  ///     errors are embedded in the instruction list. An \a llvm::Error is248  ///     returned if the decoder couldn't be properly set up.249  llvm::Expected<DecodedThreadSP> Decode(Thread &thread);250 251  /// \return252  ///     The lowest timestamp in nanoseconds in all traces if available, \a253  ///     std::nullopt if all the traces were empty or no trace contained no254  ///     timing information, or an \a llvm::Error if it was not possible to set255  ///     up the decoder for some trace.256  llvm::Expected<std::optional<uint64_t>> FindBeginningOfTimeNanos();257 258  // Dump out trace info in JSON format259  void DumpTraceInfoAsJson(Thread &thread, Stream &s, bool verbose);260 261  /// We package all the data that can change upon process stops to make sure262  /// this contract is very visible.263  /// This variable should only be accessed directly by constructores or live264  /// process data refreshers.265  struct Storage {266    std::optional<TraceIntelPTMultiCpuDecoder> multicpu_decoder;267    /// These decoders are used for the non-per-cpu case268    llvm::DenseMap<lldb::tid_t, std::unique_ptr<ThreadDecoder>> thread_decoders;269    /// Helper variable used to track long running operations for telemetry.270    TaskTimer task_timer;271    /// It is provided by either a trace bundle or a live process to convert TSC272    /// counters to and from nanos. It might not be available on all hosts.273    std::optional<LinuxPerfZeroTscConversion> tsc_conversion;274    std::optional<uint64_t> beginning_of_time_nanos;275    bool beginning_of_time_nanos_calculated = false;276  } m_storage;277 278  /// It is provided by either a trace bundle or a live process' "cpuInfo"279  /// binary data. We don't put it in the Storage because this variable doesn't280  /// change.281  std::optional<pt_cpu> m_cpu_info;282 283  /// Get the storage after refreshing the data in the case of a live process.284  Storage &GetUpdatedStorage();285 286  /// The tracing mode of post mortem trace.287  TraceMode trace_mode;288};289 290} // namespace trace_intel_pt291} // namespace lldb_private292 293#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H294