/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Target/Trace.h
Line | Count | Source (jump to first uncovered line) |
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 <optional> |
13 | | #include <unordered_map> |
14 | | |
15 | | #include "llvm/Support/JSON.h" |
16 | | |
17 | | #include "lldb/Core/PluginInterface.h" |
18 | | #include "lldb/Target/Thread.h" |
19 | | #include "lldb/Target/TraceCursor.h" |
20 | | #include "lldb/Utility/ArchSpec.h" |
21 | | #include "lldb/Utility/TraceGDBRemotePackets.h" |
22 | | #include "lldb/Utility/UnimplementedError.h" |
23 | | #include "lldb/lldb-private.h" |
24 | | #include "lldb/lldb-types.h" |
25 | | |
26 | | namespace lldb_private { |
27 | | |
28 | | /// \class Trace Trace.h "lldb/Target/Trace.h" |
29 | | /// A plug-in interface definition class for trace information. |
30 | | /// |
31 | | /// Trace plug-ins allow processor trace information to be loaded into LLDB so |
32 | | /// that the data can be dumped, used for reverse and forward stepping to allow |
33 | | /// introspection into the reason your process crashed or found its way to its |
34 | | /// current state. |
35 | | /// |
36 | | /// Trace information can be loaded into a target without a process to allow |
37 | | /// introspection of the trace information during post mortem analysis, such as |
38 | | /// when loading core files. |
39 | | /// |
40 | | /// Processor trace information can also be fetched through the process |
41 | | /// interfaces during a live debug session if your process supports gathering |
42 | | /// this information. |
43 | | /// |
44 | | /// In order to support live tracing, the name of the plug-in should match the |
45 | | /// name of the tracing type returned by the gdb-remote packet |
46 | | /// \a jLLDBTraceSupported. |
47 | | class Trace : public PluginInterface, |
48 | | public std::enable_shared_from_this<Trace> { |
49 | | public: |
50 | | /// Dump the trace data that this plug-in has access to. |
51 | | /// |
52 | | /// This function will dump all of the trace data for all threads in a user |
53 | | /// readable format. Options for dumping can be added as this API is iterated |
54 | | /// on. |
55 | | /// |
56 | | /// \param[in] s |
57 | | /// A stream object to dump the information to. |
58 | | virtual void Dump(Stream *s) const = 0; |
59 | | |
60 | | /// Save the trace to the specified directory, which will be created if |
61 | | /// needed. This will also create a file \a <directory>/trace.json with the |
62 | | /// main properties of the trace session, along with others files which |
63 | | /// contain the actual trace data. The trace.json file can be used later as |
64 | | /// input for the "trace load" command to load the trace in LLDB. |
65 | | /// |
66 | | /// \param[in] directory |
67 | | /// The directory where the trace files will be saved. |
68 | | /// |
69 | | /// \param[in] compact |
70 | | /// Try not to save to disk information irrelevant to the traced processes. |
71 | | /// Each trace plug-in implements this in a different fashion. |
72 | | /// |
73 | | /// \return |
74 | | /// A \a FileSpec pointing to the bundle description file, or an \a |
75 | | /// llvm::Error otherwise. |
76 | | virtual llvm::Expected<FileSpec> SaveToDisk(FileSpec directory, |
77 | | bool compact) = 0; |
78 | | |
79 | | /// Find a trace plug-in using JSON data. |
80 | | /// |
81 | | /// When loading trace data from disk, the information for the trace data |
82 | | /// can be contained in multiple files and require plug-in specific |
83 | | /// information about the CPU. Using data like JSON provides an |
84 | | /// easy way to specify all of the settings and information that we will need |
85 | | /// to load trace data into LLDB. This structured data can include: |
86 | | /// - The plug-in name (this allows a specific plug-in to be selected) |
87 | | /// - Architecture or target triple |
88 | | /// - one or more paths to the trace data file on disk |
89 | | /// - cpu trace data |
90 | | /// - thread events or related information |
91 | | /// - shared library load information to use for this trace data that |
92 | | /// allows a target to be created so the trace information can be |
93 | | /// symbolicated so that the trace information can be displayed to the |
94 | | /// user |
95 | | /// - shared library path |
96 | | /// - load address |
97 | | /// - information on how to fetch the shared library |
98 | | /// - path to locally cached file on disk |
99 | | /// - URL to download the file |
100 | | /// - Any information needed to load the trace file |
101 | | /// - CPU information |
102 | | /// - Custom plug-in information needed to decode the trace information |
103 | | /// correctly. |
104 | | /// |
105 | | /// \param[in] debugger |
106 | | /// The debugger instance where new Targets will be created as part of the |
107 | | /// JSON data parsing. |
108 | | /// |
109 | | /// \param[in] bundle_description |
110 | | /// The trace bundle description object describing the trace session. |
111 | | /// |
112 | | /// \param[in] bundle_dir |
113 | | /// The path to the directory that contains the trace bundle. |
114 | | static llvm::Expected<lldb::TraceSP> |
115 | | FindPluginForPostMortemProcess(Debugger &debugger, |
116 | | const llvm::json::Value &bundle_description, |
117 | | llvm::StringRef session_file_dir); |
118 | | |
119 | | /// Find a trace plug-in to trace a live process. |
120 | | /// |
121 | | /// \param[in] plugin_name |
122 | | /// Plug-in name to search. |
123 | | /// |
124 | | /// \param[in] process |
125 | | /// Live process to trace. |
126 | | /// |
127 | | /// \return |
128 | | /// A \a TraceSP instance, or an \a llvm::Error if the plug-in name |
129 | | /// doesn't match any registered plug-ins or tracing couldn't be |
130 | | /// started. |
131 | | static llvm::Expected<lldb::TraceSP> |
132 | | FindPluginForLiveProcess(llvm::StringRef plugin_name, Process &process); |
133 | | |
134 | | /// Get the schema of a Trace plug-in given its name. |
135 | | /// |
136 | | /// \param[in] plugin_name |
137 | | /// Name of the trace plugin. |
138 | | static llvm::Expected<llvm::StringRef> |
139 | | FindPluginSchema(llvm::StringRef plugin_name); |
140 | | |
141 | | /// Load a trace from a trace description file and create Targets, |
142 | | /// Processes and Threads based on the contents of such file. |
143 | | /// |
144 | | /// \param[in] debugger |
145 | | /// The debugger instance where new Targets will be created as part of the |
146 | | /// JSON data parsing. |
147 | | /// |
148 | | /// \param[in] trace_description_file |
149 | | /// The file containing the necessary information to load the trace. |
150 | | /// |
151 | | /// \return |
152 | | /// A \a TraceSP instance, or an \a llvm::Error if loading the trace |
153 | | /// fails. |
154 | | static llvm::Expected<lldb::TraceSP> |
155 | | LoadPostMortemTraceFromFile(Debugger &debugger, |
156 | | const FileSpec &trace_description_file); |
157 | | |
158 | | /// Get the command handle for the "process trace start" command. |
159 | | virtual lldb::CommandObjectSP |
160 | | GetProcessTraceStartCommand(CommandInterpreter &interpreter) = 0; |
161 | | |
162 | | /// Get the command handle for the "thread trace start" command. |
163 | | virtual lldb::CommandObjectSP |
164 | | GetThreadTraceStartCommand(CommandInterpreter &interpreter) = 0; |
165 | | |
166 | | /// \return |
167 | | /// The JSON schema of this Trace plug-in. |
168 | | virtual llvm::StringRef GetSchema() = 0; |
169 | | |
170 | | /// Get a \a TraceCursor for the given thread's trace. |
171 | | /// |
172 | | /// \return |
173 | | /// A \a TraceCursorSP. If the thread is not traced or its trace |
174 | | /// information failed to load, an \a llvm::Error is returned. |
175 | | virtual llvm::Expected<lldb::TraceCursorSP> |
176 | | CreateNewCursor(Thread &thread) = 0; |
177 | | |
178 | | /// Dump general info about a given thread's trace. Each Trace plug-in |
179 | | /// decides which data to show. |
180 | | /// |
181 | | /// \param[in] thread |
182 | | /// The thread that owns the trace in question. |
183 | | /// |
184 | | /// \param[in] s |
185 | | /// The stream object where the info will be printed printed. |
186 | | /// |
187 | | /// \param[in] verbose |
188 | | /// If \b true, print detailed info |
189 | | /// If \b false, print compact info |
190 | | virtual void DumpTraceInfo(Thread &thread, Stream &s, bool verbose, |
191 | | bool json) = 0; |
192 | | |
193 | | /// Check if a thread is currently traced by this object. |
194 | | /// |
195 | | /// \param[in] tid |
196 | | /// The id of the thread in question. |
197 | | /// |
198 | | /// \return |
199 | | /// \b true if the thread is traced by this instance, \b false otherwise. |
200 | | virtual bool IsTraced(lldb::tid_t tid) = 0; |
201 | | |
202 | | /// \return |
203 | | /// A description of the parameters to use for the \a Trace::Start method. |
204 | | virtual const char *GetStartConfigurationHelp() = 0; |
205 | | |
206 | | /// Start tracing a live process. |
207 | | /// |
208 | | /// \param[in] configuration |
209 | | /// See \a SBTrace::Start(const lldb::SBStructuredData &) for more |
210 | | /// information. |
211 | | /// |
212 | | /// \return |
213 | | /// \a llvm::Error::success if the operation was successful, or |
214 | | /// \a llvm::Error otherwise. |
215 | | virtual llvm::Error Start( |
216 | | StructuredData::ObjectSP configuration = StructuredData::ObjectSP()) = 0; |
217 | | |
218 | | /// Start tracing live threads. |
219 | | /// |
220 | | /// \param[in] tids |
221 | | /// Threads to trace. This method tries to trace as many threads as |
222 | | /// possible. |
223 | | /// |
224 | | /// \param[in] configuration |
225 | | /// See \a SBTrace::Start(const lldb::SBThread &, const |
226 | | /// lldb::SBStructuredData &) for more information. |
227 | | /// |
228 | | /// \return |
229 | | /// \a llvm::Error::success if the operation was successful, or |
230 | | /// \a llvm::Error otherwise. |
231 | | virtual llvm::Error Start( |
232 | | llvm::ArrayRef<lldb::tid_t> tids, |
233 | | StructuredData::ObjectSP configuration = StructuredData::ObjectSP()) = 0; |
234 | | |
235 | | /// Stop tracing live threads. |
236 | | /// |
237 | | /// \param[in] tids |
238 | | /// The threads to stop tracing on. |
239 | | /// |
240 | | /// \return |
241 | | /// \a llvm::Error::success if the operation was successful, or |
242 | | /// \a llvm::Error otherwise. |
243 | | llvm::Error Stop(llvm::ArrayRef<lldb::tid_t> tids); |
244 | | |
245 | | /// Stop tracing all current and future threads of a live process. |
246 | | /// |
247 | | /// \param[in] request |
248 | | /// The information determining which threads or process to stop tracing. |
249 | | /// |
250 | | /// \return |
251 | | /// \a llvm::Error::success if the operation was successful, or |
252 | | /// \a llvm::Error otherwise. |
253 | | llvm::Error Stop(); |
254 | | |
255 | | /// \return |
256 | | /// The stop ID of the live process being traced, or an invalid stop ID |
257 | | /// if the trace is in an error or invalid state. |
258 | | uint32_t GetStopID(); |
259 | | |
260 | | using OnBinaryDataReadCallback = |
261 | | std::function<llvm::Error(llvm::ArrayRef<uint8_t> data)>; |
262 | | using OnCpusBinaryDataReadCallback = std::function<llvm::Error( |
263 | | const llvm::DenseMap<lldb::cpu_id_t, llvm::ArrayRef<uint8_t>> |
264 | | &cpu_to_data)>; |
265 | | |
266 | | /// Fetch binary data associated with a thread, either live or postmortem, and |
267 | | /// pass it to the given callback. The reason of having a callback is to free |
268 | | /// the caller from having to manage the life cycle of the data and to hide |
269 | | /// the different data fetching procedures that exist for live and post mortem |
270 | | /// threads. |
271 | | /// |
272 | | /// The fetched data is not persisted after the callback is invoked. |
273 | | /// |
274 | | /// \param[in] tid |
275 | | /// The tid who owns the data. |
276 | | /// |
277 | | /// \param[in] kind |
278 | | /// The kind of data to read. |
279 | | /// |
280 | | /// \param[in] callback |
281 | | /// The callback to be invoked once the data was successfully read. Its |
282 | | /// return value, which is an \a llvm::Error, is returned by this |
283 | | /// function. |
284 | | /// |
285 | | /// \return |
286 | | /// An \a llvm::Error if the data couldn't be fetched, or the return value |
287 | | /// of the callback, otherwise. |
288 | | llvm::Error OnThreadBinaryDataRead(lldb::tid_t tid, llvm::StringRef kind, |
289 | | OnBinaryDataReadCallback callback); |
290 | | |
291 | | /// Fetch binary data associated with a cpu, either live or postmortem, and |
292 | | /// pass it to the given callback. The reason of having a callback is to free |
293 | | /// the caller from having to manage the life cycle of the data and to hide |
294 | | /// the different data fetching procedures that exist for live and post mortem |
295 | | /// cpus. |
296 | | /// |
297 | | /// The fetched data is not persisted after the callback is invoked. |
298 | | /// |
299 | | /// \param[in] cpu_id |
300 | | /// The cpu who owns the data. |
301 | | /// |
302 | | /// \param[in] kind |
303 | | /// The kind of data to read. |
304 | | /// |
305 | | /// \param[in] callback |
306 | | /// The callback to be invoked once the data was successfully read. Its |
307 | | /// return value, which is an \a llvm::Error, is returned by this |
308 | | /// function. |
309 | | /// |
310 | | /// \return |
311 | | /// An \a llvm::Error if the data couldn't be fetched, or the return value |
312 | | /// of the callback, otherwise. |
313 | | llvm::Error OnCpuBinaryDataRead(lldb::cpu_id_t cpu_id, llvm::StringRef kind, |
314 | | OnBinaryDataReadCallback callback); |
315 | | |
316 | | /// Similar to \a OnCpuBinaryDataRead but this is able to fetch the same data |
317 | | /// from all cpus at once. |
318 | | llvm::Error OnAllCpusBinaryDataRead(llvm::StringRef kind, |
319 | | OnCpusBinaryDataReadCallback callback); |
320 | | |
321 | | /// \return |
322 | | /// All the currently traced processes. |
323 | | std::vector<Process *> GetAllProcesses(); |
324 | | |
325 | | /// \return |
326 | | /// The list of cpus being traced. Might be empty depending on the |
327 | | /// plugin. |
328 | | llvm::ArrayRef<lldb::cpu_id_t> GetTracedCpus(); |
329 | | |
330 | | /// Helper method for reading a data file and passing its data to the given |
331 | | /// callback. |
332 | | static llvm::Error OnDataFileRead(FileSpec file, |
333 | | OnBinaryDataReadCallback callback); |
334 | | |
335 | | protected: |
336 | | /// Get the currently traced live process. |
337 | | /// |
338 | | /// \return |
339 | | /// If it's not a live process, return \a nullptr. |
340 | | Process *GetLiveProcess(); |
341 | | |
342 | | /// Get the currently traced postmortem processes. |
343 | | /// |
344 | | /// \return |
345 | | /// If it's not a live process session, return an empty list. |
346 | | llvm::ArrayRef<Process *> GetPostMortemProcesses(); |
347 | | |
348 | | /// Dispatcher for live trace data requests with some additional error |
349 | | /// checking. |
350 | | llvm::Expected<std::vector<uint8_t>> |
351 | | GetLiveTraceBinaryData(const TraceGetBinaryDataRequest &request, |
352 | | uint64_t expected_size); |
353 | | |
354 | | /// Implementation of \a OnThreadBinaryDataRead() for live threads. |
355 | | llvm::Error OnLiveThreadBinaryDataRead(lldb::tid_t tid, llvm::StringRef kind, |
356 | | OnBinaryDataReadCallback callback); |
357 | | |
358 | | /// Implementation of \a OnLiveBinaryDataRead() for live cpus. |
359 | | llvm::Error OnLiveCpuBinaryDataRead(lldb::cpu_id_t cpu, llvm::StringRef kind, |
360 | | OnBinaryDataReadCallback callback); |
361 | | |
362 | | /// Implementation of \a OnThreadBinaryDataRead() for post mortem threads. |
363 | | llvm::Error |
364 | | OnPostMortemThreadBinaryDataRead(lldb::tid_t tid, llvm::StringRef kind, |
365 | | OnBinaryDataReadCallback callback); |
366 | | |
367 | | /// Implementation of \a OnCpuBinaryDataRead() for post mortem cpus. |
368 | | llvm::Error OnPostMortemCpuBinaryDataRead(lldb::cpu_id_t cpu_id, |
369 | | llvm::StringRef kind, |
370 | | OnBinaryDataReadCallback callback); |
371 | | |
372 | | /// Get the file path containing data of a postmortem thread given a data |
373 | | /// identifier. |
374 | | /// |
375 | | /// \param[in] tid |
376 | | /// The thread whose data is requested. |
377 | | /// |
378 | | /// \param[in] kind |
379 | | /// The kind of data requested. |
380 | | /// |
381 | | /// \return |
382 | | /// The file spec containing the requested data, or an \a llvm::Error in |
383 | | /// case of failures. |
384 | | llvm::Expected<FileSpec> GetPostMortemThreadDataFile(lldb::tid_t tid, |
385 | | llvm::StringRef kind); |
386 | | |
387 | | /// Get the file path containing data of a postmortem cpu given a data |
388 | | /// identifier. |
389 | | /// |
390 | | /// \param[in] cpu_id |
391 | | /// The cpu whose data is requested. |
392 | | /// |
393 | | /// \param[in] kind |
394 | | /// The kind of data requested. |
395 | | /// |
396 | | /// \return |
397 | | /// The file spec containing the requested data, or an \a llvm::Error in |
398 | | /// case of failures. |
399 | | llvm::Expected<FileSpec> GetPostMortemCpuDataFile(lldb::cpu_id_t cpu_id, |
400 | | llvm::StringRef kind); |
401 | | |
402 | | /// Associate a given thread with a data file using a data identifier. |
403 | | /// |
404 | | /// \param[in] tid |
405 | | /// The thread associated with the data file. |
406 | | /// |
407 | | /// \param[in] kind |
408 | | /// The kind of data being registered. |
409 | | /// |
410 | | /// \param[in] file_spec |
411 | | /// The path of the data file. |
412 | | void SetPostMortemThreadDataFile(lldb::tid_t tid, llvm::StringRef kind, |
413 | | FileSpec file_spec); |
414 | | |
415 | | /// Associate a given cpu with a data file using a data identifier. |
416 | | /// |
417 | | /// \param[in] cpu_id |
418 | | /// The cpu associated with the data file. |
419 | | /// |
420 | | /// \param[in] kind |
421 | | /// The kind of data being registered. |
422 | | /// |
423 | | /// \param[in] file_spec |
424 | | /// The path of the data file. |
425 | | void SetPostMortemCpuDataFile(lldb::cpu_id_t cpu_id, llvm::StringRef kind, |
426 | | FileSpec file_spec); |
427 | | |
428 | | /// Get binary data of a live thread given a data identifier. |
429 | | /// |
430 | | /// \param[in] tid |
431 | | /// The thread whose data is requested. |
432 | | /// |
433 | | /// \param[in] kind |
434 | | /// The kind of data requested. |
435 | | /// |
436 | | /// \return |
437 | | /// A vector of bytes with the requested data, or an \a llvm::Error in |
438 | | /// case of failures. |
439 | | llvm::Expected<std::vector<uint8_t>> |
440 | | GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind); |
441 | | |
442 | | /// Get binary data of a live cpu given a data identifier. |
443 | | /// |
444 | | /// \param[in] cpu_id |
445 | | /// The cpu whose data is requested. |
446 | | /// |
447 | | /// \param[in] kind |
448 | | /// The kind of data requested. |
449 | | /// |
450 | | /// \return |
451 | | /// A vector of bytes with the requested data, or an \a llvm::Error in |
452 | | /// case of failures. |
453 | | llvm::Expected<std::vector<uint8_t>> |
454 | | GetLiveCpuBinaryData(lldb::cpu_id_t cpu_id, llvm::StringRef kind); |
455 | | |
456 | | /// Get binary data of the current process given a data identifier. |
457 | | /// |
458 | | /// \param[in] kind |
459 | | /// The kind of data requested. |
460 | | /// |
461 | | /// \return |
462 | | /// A vector of bytes with the requested data, or an \a llvm::Error in |
463 | | /// case of failures. |
464 | | llvm::Expected<std::vector<uint8_t>> |
465 | | GetLiveProcessBinaryData(llvm::StringRef kind); |
466 | | |
467 | | /// Get the size of the data returned by \a GetLiveThreadBinaryData |
468 | | std::optional<uint64_t> GetLiveThreadBinaryDataSize(lldb::tid_t tid, |
469 | | llvm::StringRef kind); |
470 | | |
471 | | /// Get the size of the data returned by \a GetLiveCpuBinaryData |
472 | | std::optional<uint64_t> GetLiveCpuBinaryDataSize(lldb::cpu_id_t cpu_id, |
473 | | llvm::StringRef kind); |
474 | | |
475 | | /// Get the size of the data returned by \a GetLiveProcessBinaryData |
476 | | std::optional<uint64_t> GetLiveProcessBinaryDataSize(llvm::StringRef kind); |
477 | | |
478 | | /// Constructor for post mortem processes |
479 | | Trace(llvm::ArrayRef<lldb::ProcessSP> postmortem_processes, |
480 | | std::optional<std::vector<lldb::cpu_id_t>> postmortem_cpus); |
481 | | |
482 | | /// Constructor for a live process |
483 | 0 | Trace(Process &live_process) : m_live_process(&live_process) {} |
484 | | |
485 | | /// Start tracing a live process or its threads. |
486 | | /// |
487 | | /// \param[in] request |
488 | | /// JSON object with the information necessary to start tracing. In the |
489 | | /// case of gdb-remote processes, this JSON object should conform to the |
490 | | /// jLLDBTraceStart packet. |
491 | | /// |
492 | | /// \return |
493 | | /// \a llvm::Error::success if the operation was successful, or |
494 | | /// \a llvm::Error otherwise. |
495 | | llvm::Error Start(const llvm::json::Value &request); |
496 | | |
497 | | /// Get the current tracing state of a live process and its threads. |
498 | | /// |
499 | | /// \return |
500 | | /// A JSON object string with custom data depending on the trace |
501 | | /// technology, or an \a llvm::Error in case of errors. |
502 | | llvm::Expected<std::string> GetLiveProcessState(); |
503 | | |
504 | | /// Method to be overriden by the plug-in to refresh its own state. |
505 | | /// |
506 | | /// This is invoked by RefreshLiveProcessState when a new state is found. |
507 | | /// |
508 | | /// \param[in] state |
509 | | /// The jLLDBTraceGetState response. |
510 | | /// |
511 | | /// \param[in] json_response |
512 | | /// The original JSON response as a string. It might be useful to redecode |
513 | | /// it if it contains custom data for a specific trace plug-in. |
514 | | /// |
515 | | /// \return |
516 | | /// \b Error::success() if this operation succeedes, or an actual error |
517 | | /// otherwise. |
518 | | virtual llvm::Error |
519 | | DoRefreshLiveProcessState(TraceGetStateResponse state, |
520 | | llvm::StringRef json_response) = 0; |
521 | | |
522 | | /// Return the list of processes traced by this instance. None of the returned |
523 | | /// pointers are invalid. |
524 | | std::vector<Process *> GetTracedProcesses(); |
525 | | |
526 | | /// Method to be invoked by the plug-in to refresh the live process state. It |
527 | | /// will invoked DoRefreshLiveProcessState at some point, which should be |
528 | | /// implemented by the plug-in for custom state handling. |
529 | | /// |
530 | | /// The result is cached through the same process stop. Even in the case of |
531 | | /// errors, it caches the error. |
532 | | /// |
533 | | /// \return |
534 | | /// An error message if this operation failed, or \b nullptr otherwise. |
535 | | const char *RefreshLiveProcessState(); |
536 | | |
537 | | private: |
538 | | uint32_t m_stop_id = LLDB_INVALID_STOP_ID; |
539 | | |
540 | | /// Process traced by this object if doing live tracing. Otherwise it's null. |
541 | | Process *m_live_process = nullptr; |
542 | | |
543 | | /// We package all the data that can change upon process stops to make sure |
544 | | /// this contract is very visible. |
545 | | /// This variable should only be accessed directly by constructores or live |
546 | | /// process data refreshers. |
547 | | struct Storage { |
548 | | /// Portmortem processes traced by this object if doing non-live tracing. |
549 | | /// Otherwise it's empty. |
550 | | std::vector<Process *> postmortem_processes; |
551 | | |
552 | | /// These data kinds are returned by lldb-server when fetching the state of |
553 | | /// the tracing session. The size in bytes can be used later for fetching |
554 | | /// the data in batches. |
555 | | /// \{ |
556 | | |
557 | | /// tid -> data kind -> size |
558 | | llvm::DenseMap<lldb::tid_t, llvm::DenseMap<ConstString, uint64_t>> |
559 | | live_thread_data; |
560 | | |
561 | | /// cpu id -> data kind -> size |
562 | | llvm::DenseMap<lldb::cpu_id_t, llvm::DenseMap<ConstString, uint64_t>> |
563 | | live_cpu_data_sizes; |
564 | | /// cpu id -> data kind -> bytes |
565 | | llvm::DenseMap<lldb::cpu_id_t, |
566 | | llvm::DenseMap<ConstString, std::vector<uint8_t>>> |
567 | | live_cpu_data; |
568 | | |
569 | | /// data kind -> size |
570 | | llvm::DenseMap<ConstString, uint64_t> live_process_data; |
571 | | /// \} |
572 | | |
573 | | /// The list of cpus being traced. Might be \b std::nullopt depending on the |
574 | | /// plug-in. |
575 | | std::optional<std::vector<lldb::cpu_id_t>> cpus; |
576 | | |
577 | | /// Postmortem traces can specific additional data files, which are |
578 | | /// represented in this variable using a data kind identifier for each file. |
579 | | /// \{ |
580 | | |
581 | | /// tid -> data kind -> file |
582 | | llvm::DenseMap<lldb::tid_t, llvm::DenseMap<ConstString, FileSpec>> |
583 | | postmortem_thread_data; |
584 | | |
585 | | /// cpu id -> data kind -> file |
586 | | llvm::DenseMap<lldb::cpu_id_t, llvm::DenseMap<ConstString, FileSpec>> |
587 | | postmortem_cpu_data; |
588 | | |
589 | | /// \} |
590 | | |
591 | | std::optional<std::string> live_refresh_error; |
592 | | } m_storage; |
593 | | |
594 | | /// Get the storage after refreshing the data in the case of a live process. |
595 | | Storage &GetUpdatedStorage(); |
596 | | }; |
597 | | |
598 | | } // namespace lldb_private |
599 | | |
600 | | #endif // LLDB_TARGET_TRACE_H |