1 //===-- Trace.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 LLDB_TARGET_TRACE_H 10 #define LLDB_TARGET_TRACE_H 11 12 #include "llvm/Support/JSON.h" 13 14 #include "lldb/Core/PluginInterface.h" 15 #include "lldb/Utility/ArchSpec.h" 16 #include "lldb/Utility/UnimplementedError.h" 17 #include "lldb/lldb-private.h" 18 19 namespace lldb_private { 20 21 /// \class Trace Trace.h "lldb/Target/Trace.h" 22 /// A plug-in interface definition class for trace information. 23 /// 24 /// Trace plug-ins allow processor trace information to be loaded into LLDB so 25 /// that the data can be dumped, used for reverse and forward stepping to allow 26 /// introspection into the reason your process crashed or found its way to its 27 /// current state. 28 /// 29 /// Trace information can be loaded into a target without a process to allow 30 /// introspection of the trace information during post mortem analysis, such as 31 /// when loading core files. 32 /// 33 /// Processor trace information can also be fetched through the process 34 /// interfaces during a live debug session if your process supports gathering 35 /// this information. 36 /// 37 /// In order to support live tracing, the name of the plug-in should match the 38 /// name of the tracing type returned by the gdb-remote packet 39 /// \a jLLDBTraceSupportedType. 40 class Trace : public PluginInterface, 41 public std::enable_shared_from_this<Trace> { 42 public: 43 enum class TraceDirection { 44 Forwards = 0, 45 Backwards, 46 }; 47 48 /// Dump the trace data that this plug-in has access to. 49 /// 50 /// This function will dump all of the trace data for all threads in a user 51 /// readable format. Options for dumping can be added as this API is iterated 52 /// on. 53 /// 54 /// \param[in] s 55 /// A stream object to dump the information to. 56 virtual void Dump(Stream *s) const = 0; 57 58 /// Find a trace plug-in using JSON data. 59 /// 60 /// When loading trace data from disk, the information for the trace data 61 /// can be contained in multiple files and require plug-in specific 62 /// information about the CPU. Using data like JSON provides an 63 /// easy way to specify all of the settings and information that we will need 64 /// to load trace data into LLDB. This structured data can include: 65 /// - The plug-in name (this allows a specific plug-in to be selected) 66 /// - Architecture or target triple 67 /// - one or more paths to the trace data file on disk 68 /// - core trace data 69 /// - thread events or related information 70 /// - shared library load information to use for this trace data that 71 /// allows a target to be created so the trace information can be 72 /// symbolicated so that the trace information can be displayed to the 73 /// user 74 /// - shared library path 75 /// - load address 76 /// - information on how to fetch the shared library 77 /// - path to locally cached file on disk 78 /// - URL to download the file 79 /// - Any information needed to load the trace file 80 /// - CPU information 81 /// - Custom plug-in information needed to decode the trace information 82 /// correctly. 83 /// 84 /// \param[in] debugger 85 /// The debugger instance where new Targets will be created as part of the 86 /// JSON data parsing. 87 /// 88 /// \param[in] trace_session_file 89 /// The contents of the trace session file describing the trace session. 90 /// See \a TraceSessionFileParser::BuildSchema for more information about 91 /// the schema of this JSON file. 92 /// 93 /// \param[in] session_file_dir 94 /// The path to the directory that contains the session file. It's used to 95 /// resolved relative paths in the session file. 96 static llvm::Expected<lldb::TraceSP> 97 FindPlugin(Debugger &debugger, const llvm::json::Value &trace_session_file, 98 llvm::StringRef session_file_dir); 99 100 /// Get the schema of a Trace plug-in given its name. 101 /// 102 /// \param[in] plugin_name 103 /// Name of the trace plugin. 104 static llvm::Expected<llvm::StringRef> 105 FindPluginSchema(llvm::StringRef plugin_name); 106 107 /// \return 108 /// The JSON schema of this Trace plug-in. 109 virtual llvm::StringRef GetSchema() = 0; 110 111 /// Each decoded thread contains a cursor to the current position the user is 112 /// stopped at. When reverse debugging, each operation like reverse-next or 113 /// reverse-continue will move this cursor, which is then picked by any 114 /// subsequent dump or reverse operation. 115 /// 116 /// The initial position for this cursor is the last element of the thread, 117 /// which is the most recent chronologically. 118 /// 119 /// \return 120 /// The current position of the thread's trace or \b 0 if empty. 121 virtual size_t GetCursorPosition(const Thread &thread) = 0; 122 123 /// Dump \a count instructions of the given thread's trace ending at the 124 /// given \a end_position position. 125 /// 126 /// The instructions are printed along with their indices or positions, which 127 /// are increasing chronologically. This means that the \a index 0 represents 128 /// the oldest instruction of the trace chronologically. 129 /// 130 /// \param[in] thread 131 /// The thread whose trace will be dumped. 132 /// 133 /// \param[in] s 134 /// The stream object where the instructions are printed. 135 /// 136 /// \param[in] count 137 /// The number of instructions to print. 138 /// 139 /// \param[in] end_position 140 /// The position of the last instruction to print. 141 /// 142 /// \param[in] raw 143 /// Dump only instruction addresses without disassembly nor symbol 144 /// information. 145 void DumpTraceInstructions(Thread &thread, Stream &s, size_t count, 146 size_t end_position, bool raw); 147 148 /// Run the provided callback on the instructions of the trace of the given 149 /// thread. 150 /// 151 /// The instructions will be traversed starting at the given \a position 152 /// sequentially until the callback returns \b false, in which case no more 153 /// instructions are inspected. 154 /// 155 /// The purpose of this method is to allow inspecting traced instructions 156 /// without exposing the internal representation of how they are stored on 157 /// memory. 158 /// 159 /// \param[in] thread 160 /// The thread whose trace will be traversed. 161 /// 162 /// \param[in] position 163 /// The instruction position to start iterating on. 164 /// 165 /// \param[in] direction 166 /// If \b TraceDirection::Forwards, then then instructions will be 167 /// traversed forwards chronologically, i.e. with incrementing indices. If 168 /// \b TraceDirection::Backwards, the traversal is done backwards 169 /// chronologically, i.e. with decrementing indices. 170 /// 171 /// \param[in] callback 172 /// The callback to execute on each instruction. If it returns \b false, 173 /// the iteration stops. 174 virtual void TraverseInstructions( 175 const Thread &thread, size_t position, TraceDirection direction, 176 std::function<bool(size_t index, llvm::Expected<lldb::addr_t> load_addr)> 177 callback) = 0; 178 179 /// Stop tracing a live thread 180 /// 181 /// \param[in] thread 182 /// The thread object to stop tracing. 183 /// 184 /// \return 185 /// An \a llvm::Error if stopping tracing failed, or \b 186 /// llvm::Error::success() otherwise. StopTracingThread(const Thread & thread)187 virtual llvm::Error StopTracingThread(const Thread &thread) { 188 return llvm::make_error<UnimplementedError>(); 189 } 190 191 /// Get the number of available instructions in the trace of the given thread. 192 /// 193 /// \param[in] thread 194 /// The thread whose trace will be inspected. 195 /// 196 /// \return 197 /// The total number of instructions in the trace. 198 virtual size_t GetInstructionCount(const Thread &thread) = 0; 199 }; 200 201 } // namespace lldb_private 202 203 #endif // LLDB_TARGET_TRACE_H 204