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