1 //===-- TraceIntelPTBundleLoader.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_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLELOADER_H
10 #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLELOADER_H
11 
12 #include "../common/ThreadPostMortemTrace.h"
13 #include "TraceIntelPTJSONStructs.h"
14 
15 namespace lldb_private {
16 namespace trace_intel_pt {
17 
18 class TraceIntelPT;
19 
20 class TraceIntelPTBundleLoader {
21 public:
22   /// Helper struct holding the objects created when parsing a process
23   struct ParsedProcess {
24     lldb::TargetSP target_sp;
25     std::vector<lldb::ThreadPostMortemTraceSP> threads;
26   };
27 
28   /// \param[in] debugger
29   ///   The debugger that will own the targets to create.
30   ///
31   /// \param[in] bundle_description
32   ///   The JSON description of a trace bundle that follows the schema of the intel pt trace plug-in.
33   ///
34   /// \param[in] bundle_dir
35   ///   The folder where the trace bundle is located.
36   TraceIntelPTBundleLoader(Debugger &debugger,
37                                 const llvm::json::Value &bundle_description,
38                                 llvm::StringRef bundle_dir)
39       : m_debugger(debugger), m_bundle_description(bundle_description),
40         m_bundle_dir(bundle_dir) {}
41 
42   /// \return
43   ///   The JSON schema for the bundle description.
44   static llvm::StringRef GetSchema();
45 
46   /// Parse the trace bundle description and create the corresponding \a
47   /// Target objects. In case of an error, no targets are created.
48   ///
49   /// \return
50   ///   A \a lldb::TraceSP instance created according to the trace bundle information. In case of
51   ///   errors, return a null pointer.
52   llvm::Expected<lldb::TraceSP> Load();
53 
54 private:
55   /// Resolve non-absolute paths relative to the bundle folder.
56   FileSpec NormalizePath(const std::string &path);
57 
58   /// Create a post-mortem thread associated with the given \p process
59   /// using the definition from \p thread.
60   lldb::ThreadPostMortemTraceSP ParseThread(Process &process,
61                                             const JSONThread &thread);
62 
63   /// Given a bundle description and a list of fully parsed processes,
64   /// create an actual Trace instance that "traces" these processes.
65   llvm::Expected<lldb::TraceSP>
66   CreateTraceIntelPTInstance(JSONTraceBundleDescription &bundle_description,
67                              std::vector<ParsedProcess> &parsed_processes);
68 
69   /// Create the corresponding Threads and Process objects given the JSON
70   /// process definition.
71   ///
72   /// \param[in] process
73   ///   The JSON process definition
74   llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process);
75 
76   /// Create a module associated with the given \p target using the definition from \p module.
77   llvm::Error ParseModule(Target &target, const JSONModule &module);
78 
79   /// Create a user-friendly error message upon a JSON-parsing failure using the
80   /// \a json::ObjectMapper functionality.
81   ///
82   /// \param[in] root
83   ///   The \a llvm::json::Path::Root used to parse the JSON \a value.
84   ///
85   /// \param[in] value
86   ///   The json value that failed to parse.
87   ///
88   /// \return
89   ///   An \a llvm::Error containing the user-friendly error message.
90   llvm::Error CreateJSONError(llvm::json::Path::Root &root,
91                               const llvm::json::Value &value);
92 
93   /// Create the corresponding Process, Thread and Module objects given this
94   /// bundle description.
95   llvm::Expected<std::vector<ParsedProcess>>
96   LoadBundle(const JSONTraceBundleDescription &bundle_description);
97 
98   /// When applicable, augment the list of threads in the trace bundle by
99   /// inspecting the context switch trace. This only applies for threads of
100   /// processes already specified in this bundle description.
101   ///
102   /// \return
103   ///   An \a llvm::Error in case if failures, or \a llvm::Error::success
104   ///   otherwise.
105   llvm::Error AugmentThreadsFromContextSwitches(JSONTraceBundleDescription &bundle_description);
106 
107   /// Modifiy the bundle description by normalizing all the paths relative to the
108   /// session file directory.
109   void NormalizeAllPaths(JSONTraceBundleDescription &bundle_description);
110 
111   Debugger &m_debugger;
112   const llvm::json::Value &m_bundle_description;
113   const std::string m_bundle_dir;
114 };
115 
116 } // namespace trace_intel_pt
117 } // namespace lldb_private
118 
119 
120 #endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTBUNDLELOADER_H
121