LLDB  mainline
Trace.h
Go to the documentation of this file.
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 <unordered_map>
13 
14 #include "llvm/Support/JSON.h"
15 
17 #include "lldb/Target/Thread.h"
19 #include "lldb/Utility/ArchSpec.h"
22 #include "lldb/lldb-private.h"
23 #include "lldb/lldb-types.h"
24 
25 namespace lldb_private {
26 
27 /// \class Trace Trace.h "lldb/Target/Trace.h"
28 /// A plug-in interface definition class for trace information.
29 ///
30 /// Trace plug-ins allow processor trace information to be loaded into LLDB so
31 /// that the data can be dumped, used for reverse and forward stepping to allow
32 /// introspection into the reason your process crashed or found its way to its
33 /// current state.
34 ///
35 /// Trace information can be loaded into a target without a process to allow
36 /// introspection of the trace information during post mortem analysis, such as
37 /// when loading core files.
38 ///
39 /// Processor trace information can also be fetched through the process
40 /// interfaces during a live debug session if your process supports gathering
41 /// this information.
42 ///
43 /// In order to support live tracing, the name of the plug-in should match the
44 /// name of the tracing type returned by the gdb-remote packet
45 /// \a jLLDBTraceSupported.
46 class Trace : public PluginInterface,
47  public std::enable_shared_from_this<Trace> {
48 public:
49  /// Dump the trace data that this plug-in has access to.
50  ///
51  /// This function will dump all of the trace data for all threads in a user
52  /// readable format. Options for dumping can be added as this API is iterated
53  /// on.
54  ///
55  /// \param[in] s
56  /// A stream object to dump the information to.
57  virtual void Dump(Stream *s) const = 0;
58 
59  /// Save the trace of a live process to the specified directory, which
60  /// will be created if needed.
61  /// This will also create a a file \a <directory>/trace.json with the main
62  /// properties of the trace session, along with others files which contain
63  /// the actual trace data. The trace.json file can be used later as input
64  /// for the "trace load" command to load the trace in LLDB.
65  /// The process being trace is not a live process, return an error.
66  ///
67  /// \param[in] directory
68  /// The directory where the trace files will be saved.
69  ///
70  /// \return
71  /// \a llvm::success if the operation was successful, or an \a llvm::Error
72  /// otherwise.
73  virtual llvm::Error SaveLiveTraceToDisk(FileSpec directory) = 0;
74 
75  /// Find a trace plug-in using JSON data.
76  ///
77  /// When loading trace data from disk, the information for the trace data
78  /// can be contained in multiple files and require plug-in specific
79  /// information about the CPU. Using data like JSON provides an
80  /// easy way to specify all of the settings and information that we will need
81  /// to load trace data into LLDB. This structured data can include:
82  /// - The plug-in name (this allows a specific plug-in to be selected)
83  /// - Architecture or target triple
84  /// - one or more paths to the trace data file on disk
85  /// - core trace data
86  /// - thread events or related information
87  /// - shared library load information to use for this trace data that
88  /// allows a target to be created so the trace information can be
89  /// symbolicated so that the trace information can be displayed to the
90  /// user
91  /// - shared library path
92  /// - load address
93  /// - information on how to fetch the shared library
94  /// - path to locally cached file on disk
95  /// - URL to download the file
96  /// - Any information needed to load the trace file
97  /// - CPU information
98  /// - Custom plug-in information needed to decode the trace information
99  /// correctly.
100  ///
101  /// \param[in] debugger
102  /// The debugger instance where new Targets will be created as part of the
103  /// JSON data parsing.
104  ///
105  /// \param[in] trace_session_file
106  /// The contents of the trace session file describing the trace session.
107  /// See \a TraceSessionFileParser::BuildSchema for more information about
108  /// the schema of this JSON file.
109  ///
110  /// \param[in] session_file_dir
111  /// The path to the directory that contains the session file. It's used to
112  /// resolved relative paths in the session file.
113  static llvm::Expected<lldb::TraceSP>
115  const llvm::json::Value &trace_session_file,
116  llvm::StringRef session_file_dir);
117 
118  /// Find a trace plug-in to trace a live process.
119  ///
120  /// \param[in] plugin_name
121  /// Plug-in name to search.
122  ///
123  /// \param[in] process
124  /// Live process to trace.
125  ///
126  /// \return
127  /// A \a TraceSP instance, or an \a llvm::Error if the plug-in name
128  /// doesn't match any registered plug-ins or tracing couldn't be
129  /// started.
130  static llvm::Expected<lldb::TraceSP>
131  FindPluginForLiveProcess(llvm::StringRef plugin_name, Process &process);
132 
133  /// Get the schema of a Trace plug-in given its name.
134  ///
135  /// \param[in] plugin_name
136  /// Name of the trace plugin.
137  static llvm::Expected<llvm::StringRef>
138  FindPluginSchema(llvm::StringRef plugin_name);
139 
140  /// Get the command handle for the "process trace start" command.
141  virtual lldb::CommandObjectSP
143 
144  /// Get the command handle for the "thread trace start" command.
145  virtual lldb::CommandObjectSP
147 
148  /// \return
149  /// The JSON schema of this Trace plug-in.
150  virtual llvm::StringRef GetSchema() = 0;
151 
152  /// Get a \a TraceCursor for the given thread's trace.
153  ///
154  /// \return
155  /// A \a TraceCursorUP. If the thread is not traced or its trace
156  /// information failed to load, the corresponding error is embedded in the
157  /// trace.
158  virtual lldb::TraceCursorUP GetCursor(Thread &thread) = 0;
159 
160  /// Dump general info about a given thread's trace. Each Trace plug-in
161  /// decides which data to show.
162  ///
163  /// \param[in] thread
164  /// The thread that owns the trace in question.
165  ///
166  /// \param[in] s
167  /// The stream object where the info will be printed printed.
168  ///
169  /// \param[in] verbose
170  /// If \b true, print detailed info
171  /// If \b false, print compact info
172  virtual void DumpTraceInfo(Thread &thread, Stream &s, bool verbose) = 0;
173 
174  /// Check if a thread is currently traced by this object.
175  ///
176  /// \param[in] tid
177  /// The id of the thread in question.
178  ///
179  /// \return
180  /// \b true if the thread is traced by this instance, \b false otherwise.
181  virtual bool IsTraced(lldb::tid_t tid) = 0;
182 
183  /// \return
184  /// A description of the parameters to use for the \a Trace::Start method.
185  virtual const char *GetStartConfigurationHelp() = 0;
186 
187  /// Start tracing a live process.
188  ///
189  /// \param[in] configuration
190  /// See \a SBTrace::Start(const lldb::SBStructuredData &) for more
191  /// information.
192  ///
193  /// \return
194  /// \a llvm::Error::success if the operation was successful, or
195  /// \a llvm::Error otherwise.
196  virtual llvm::Error Start(
197  StructuredData::ObjectSP configuration = StructuredData::ObjectSP()) = 0;
198 
199  /// Start tracing live threads.
200  ///
201  /// \param[in] tids
202  /// Threads to trace. This method tries to trace as many threads as
203  /// possible.
204  ///
205  /// \param[in] configuration
206  /// See \a SBTrace::Start(const lldb::SBThread &, const
207  /// lldb::SBStructuredData &) for more information.
208  ///
209  /// \return
210  /// \a llvm::Error::success if the operation was successful, or
211  /// \a llvm::Error otherwise.
212  virtual llvm::Error Start(
213  llvm::ArrayRef<lldb::tid_t> tids,
214  StructuredData::ObjectSP configuration = StructuredData::ObjectSP()) = 0;
215 
216  /// Stop tracing live threads.
217  ///
218  /// \param[in] tids
219  /// The threads to stop tracing on.
220  ///
221  /// \return
222  /// \a llvm::Error::success if the operation was successful, or
223  /// \a llvm::Error otherwise.
224  llvm::Error Stop(llvm::ArrayRef<lldb::tid_t> tids);
225 
226  /// Stop tracing all current and future threads of a live process.
227  ///
228  /// \param[in] request
229  /// The information determining which threads or process to stop tracing.
230  ///
231  /// \return
232  /// \a llvm::Error::success if the operation was successful, or
233  /// \a llvm::Error otherwise.
234  llvm::Error Stop();
235 
236  /// Get the trace file of the given post mortem thread.
237  llvm::Expected<const FileSpec &> GetPostMortemTraceFile(lldb::tid_t tid);
238 
239  /// \return
240  /// The stop ID of the live process being traced, or an invalid stop ID
241  /// if the trace is in an error or invalid state.
243 
244 protected:
245  /// Get binary data of a live thread given a data identifier.
246  ///
247  /// \param[in] tid
248  /// The thread whose data is requested.
249  ///
250  /// \param[in] kind
251  /// The kind of data requested.
252  ///
253  /// \return
254  /// A vector of bytes with the requested data, or an \a llvm::Error in
255  /// case of failures.
256  llvm::Expected<llvm::ArrayRef<uint8_t>>
257  GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind);
258 
259  /// Get binary data of the current process given a data identifier.
260  ///
261  /// \param[in] kind
262  /// The kind of data requested.
263  ///
264  /// \return
265  /// A vector of bytes with the requested data, or an \a llvm::Error in
266  /// case of failures.
267  llvm::Expected<llvm::ArrayRef<uint8_t>>
268  GetLiveProcessBinaryData(llvm::StringRef kind);
269 
270  /// Get the size of the data returned by \a GetLiveThreadBinaryData
271  llvm::Optional<size_t> GetLiveThreadBinaryDataSize(lldb::tid_t tid,
272  llvm::StringRef kind);
273 
274  /// Get the size of the data returned by \a GetLiveProcessBinaryData
275  llvm::Optional<size_t> GetLiveProcessBinaryDataSize(llvm::StringRef kind);
276  /// Constructor for post mortem processes
277  Trace() = default;
278 
279  /// Constructor for a live process
280  Trace(Process &live_process) : m_live_process(&live_process) {}
281 
282  /// Start tracing a live process or its threads.
283  ///
284  /// \param[in] request
285  /// JSON object with the information necessary to start tracing. In the
286  /// case of gdb-remote processes, this JSON object should conform to the
287  /// jLLDBTraceStart packet.
288  ///
289  /// \return
290  /// \a llvm::Error::success if the operation was successful, or
291  /// \a llvm::Error otherwise.
292  llvm::Error Start(const llvm::json::Value &request);
293 
294  /// Get the current tracing state of a live process and its threads.
295  ///
296  /// \return
297  /// A JSON object string with custom data depending on the trace
298  /// technology, or an \a llvm::Error in case of errors.
299  llvm::Expected<std::string> GetLiveProcessState();
300 
301  /// Method to be overriden by the plug-in to refresh its own state.
302  ///
303  /// This is invoked by RefreshLiveProcessState when a new state is found.
304  ///
305  /// \param[in] state
306  /// The jLLDBTraceGetState response.
307  virtual void
308  DoRefreshLiveProcessState(llvm::Expected<TraceGetStateResponse> state) = 0;
309 
310  /// Method to be invoked by the plug-in to refresh the live process state.
311  ///
312  /// The result is cached through the same process stop.
314 
316  /// Process traced by this object if doing live tracing. Otherwise it's null.
318  /// tid -> data kind -> size
319  std::map<lldb::tid_t, std::unordered_map<std::string, size_t>>
321  /// data kind -> size
322  std::unordered_map<std::string, size_t> m_live_process_data;
323 };
324 
325 } // namespace lldb_private
326 
327 #endif // LLDB_TARGET_TRACE_H
lldb_private::Trace::Trace
Trace()=default
Constructor for post mortem processes.
lldb_private::Trace::GetLiveThreadBinaryDataSize
llvm::Optional< size_t > GetLiveThreadBinaryDataSize(lldb::tid_t tid, llvm::StringRef kind)
Get the size of the data returned by GetLiveThreadBinaryData.
Definition: Trace.cpp:128
lldb_private::Trace::GetLiveProcessBinaryData
llvm::Expected< llvm::ArrayRef< uint8_t > > GetLiveProcessBinaryData(llvm::StringRef kind)
Get binary data of the current process given a data identifier.
Definition: Trace.cpp:166
lldb_private::Trace::GetStopID
uint32_t GetStopID()
Definition: Trace.cpp:216
lldb_private::PluginInterface
Definition: PluginInterface.h:16
lldb_private::Trace::DoRefreshLiveProcessState
virtual void DoRefreshLiveProcessState(llvm::Expected< TraceGetStateResponse > state)=0
Method to be overriden by the plug-in to refresh its own state.
lldb_private::Process
Definition: Process.h:341
lldb_private::Trace::GetProcessTraceStartCommand
virtual lldb::CommandObjectSP GetProcessTraceStartCommand(CommandInterpreter &interpreter)=0
Get the command handle for the "process trace start" command.
lldb_private::Trace::FindPluginForLiveProcess
static llvm::Expected< lldb::TraceSP > FindPluginForLiveProcess(llvm::StringRef plugin_name, Process &process)
Find a trace plug-in to trace a live process.
Definition: Trace.cpp:78
lldb_private::Stream
Definition: Stream.h:28
lldb_private::Trace::RefreshLiveProcessState
void RefreshLiveProcessState()
Method to be invoked by the plug-in to refresh the live process state.
Definition: Trace.cpp:181
lldb_private::Trace::GetStartConfigurationHelp
virtual const char * GetStartConfigurationHelp()=0
lldb_private::Trace::m_stop_id
uint32_t m_stop_id
Definition: Trace.h:315
lldb_private::Trace
Definition: Trace.h:46
lldb_private::FileSpec
Definition: FileSpec.h:56
lldb_private::Trace::m_live_process_data
std::unordered_map< std::string, size_t > m_live_process_data
data kind -> size
Definition: Trace.h:322
UnimplementedError.h
lldb_private::Thread
Definition: Thread.h:60
lldb_private::StructuredData::ObjectSP
std::shared_ptr< Object > ObjectSP
Definition: StructuredData.h:59
lldb_private::Trace::GetPostMortemTraceFile
llvm::Expected< const FileSpec & > GetPostMortemTraceFile(lldb::tid_t tid)
Get the trace file of the given post mortem thread.
lldb_private::Trace::GetThreadTraceStartCommand
virtual lldb::CommandObjectSP GetThreadTraceStartCommand(CommandInterpreter &interpreter)=0
Get the command handle for the "thread trace start" command.
PluginInterface.h
lldb_private::Trace::m_live_thread_data
std::map< lldb::tid_t, std::unordered_map< std::string, size_t > > m_live_thread_data
tid -> data kind -> size
Definition: Trace.h:320
lldb_private::CommandInterpreter
Definition: CommandInterpreter.h:214
lldb_private::Trace::IsTraced
virtual bool IsTraced(lldb::tid_t tid)=0
Check if a thread is currently traced by this object.
lldb_private::Trace::GetLiveThreadBinaryData
llvm::Expected< llvm::ArrayRef< uint8_t > > GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind)
Get binary data of a live thread given a data identifier.
Definition: Trace.cpp:148
lldb_private::Debugger
Definition: Debugger.h:70
lldb_private::Trace::Start
virtual llvm::Error Start(StructuredData::ObjectSP configuration=StructuredData::ObjectSP())=0
Start tracing a live process.
Thread.h
lldb-private.h
LLDB_INVALID_STOP_ID
#define LLDB_INVALID_STOP_ID
Invalid value definitions.
Definition: lldb-defines.h:85
lldb-types.h
lldb_private::Trace::m_live_process
Process * m_live_process
Process traced by this object if doing live tracing. Otherwise it's null.
Definition: Trace.h:317
uint32_t
lldb_private::Trace::Dump
virtual void Dump(Stream *s) const =0
Dump the trace data that this plug-in has access to.
ArchSpec.h
TraceCursor.h
lldb_private::Trace::Stop
llvm::Error Stop()
Stop tracing all current and future threads of a live process.
Definition: Trace.cpp:107
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::Trace::FindPluginForPostMortemProcess
static llvm::Expected< lldb::TraceSP > FindPluginForPostMortemProcess(Debugger &debugger, const llvm::json::Value &trace_session_file, llvm::StringRef session_file_dir)
Find a trace plug-in using JSON data.
Definition: Trace.cpp:62
lldb_private::Trace::GetCursor
virtual lldb::TraceCursorUP GetCursor(Thread &thread)=0
Get a TraceCursor for the given thread's trace.
Error
llvm::Error Error
Definition: UdtRecordCompleter.cpp:29
lldb_private::Trace::GetSchema
virtual llvm::StringRef GetSchema()=0
lldb_private::Trace::DumpTraceInfo
virtual void DumpTraceInfo(Thread &thread, Stream &s, bool verbose)=0
Dump general info about a given thread's trace.
lldb_private::Trace::Trace
Trace(Process &live_process)
Constructor for a live process.
Definition: Trace.h:280
lldb_private::Trace::FindPluginSchema
static llvm::Expected< llvm::StringRef > FindPluginSchema(llvm::StringRef plugin_name)
Get the schema of a Trace plug-in given its name.
Definition: Trace.cpp:91
lldb_private::Trace::GetLiveProcessBinaryDataSize
llvm::Optional< size_t > GetLiveProcessBinaryDataSize(llvm::StringRef kind)
Get the size of the data returned by GetLiveProcessBinaryData.
Definition: Trace.cpp:140
lldb_private::Trace::SaveLiveTraceToDisk
virtual llvm::Error SaveLiveTraceToDisk(FileSpec directory)=0
Save the trace of a live process to the specified directory, which will be created if needed.
lldb_private::Trace::GetLiveProcessState
llvm::Expected< std::string > GetLiveProcessState()
Get the current tracing state of a live process and its threads.
Definition: Trace.cpp:121
TraceGDBRemotePackets.h
lldb::tid_t
uint64_t tid_t
Definition: lldb-types.h:86