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 | 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 |
601 | |