1 //===-- TraceSessionFileParser.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_TRACESESSIONPARSER_H
10 #define LLDB_TARGET_TRACESESSIONPARSER_H
11
12 #include "llvm/Support/JSON.h"
13
14 #include "lldb/Target/ThreadTrace.h"
15
16 namespace lldb_private {
17
18 /// \class TraceSessionFileParser TraceSessionFileParser.h
19 ///
20 /// Base class for parsing the common information of JSON trace session files.
21 /// Contains the basic C++ structs that represent the JSON data, which include
22 /// \a JSONTraceSession as the root object.
23 ///
24 /// See \a Trace::FindPlugin for more information regarding these JSON files.
25 class TraceSessionFileParser {
26 public:
27 /// C++ structs representing the JSON trace session.
28 /// \{
29 struct JSONAddress {
30 lldb::addr_t value;
31 };
32
33 struct JSONModule {
34 std::string system_path;
35 llvm::Optional<std::string> file;
36 JSONAddress load_address;
37 llvm::Optional<std::string> uuid;
38 };
39
40 struct JSONThread {
41 int64_t tid;
42 std::string trace_file;
43 };
44
45 struct JSONProcess {
46 int64_t pid;
47 std::string triple;
48 std::vector<JSONThread> threads;
49 std::vector<JSONModule> modules;
50 };
51
52 struct JSONTracePluginSettings {
53 std::string type;
54 };
55
56 struct JSONTraceSessionBase {
57 std::vector<JSONProcess> processes;
58 };
59
60 /// The trace plug-in implementation should provide its own TPluginSettings,
61 /// which corresponds to the "trace" section of the schema.
62 template <class TPluginSettings>
63 struct JSONTraceSession : JSONTraceSessionBase {
64 TPluginSettings trace;
65 };
66 /// \}
67
68 /// Helper struct holding the objects created when parsing a process
69 struct ParsedProcess {
70 lldb::TargetSP target_sp;
71 std::vector<ThreadTraceSP> threads;
72 };
73
TraceSessionFileParser(Debugger & debugger,llvm::StringRef session_file_dir,llvm::StringRef schema)74 TraceSessionFileParser(Debugger &debugger, llvm::StringRef session_file_dir,
75 llvm::StringRef schema)
76 : m_debugger(debugger), m_session_file_dir(session_file_dir),
77 m_schema(schema) {}
78
79 /// Build the full schema for a Trace plug-in.
80 ///
81 /// \param[in] plugin_schema
82 /// The subschema that corresponds to the "trace" section of the schema.
83 ///
84 /// \return
85 /// The full schema containing the common attributes and the plug-in
86 /// specific attributes.
87 static std::string BuildSchema(llvm::StringRef plugin_schema);
88
89 /// Parse the fields common to all trace session schemas.
90 ///
91 /// \param[in] session
92 /// The session json objects already deserialized.
93 ///
94 /// \return
95 /// A list of \a ParsedProcess containing all threads and targets created
96 /// during the parsing, or an error in case of failures. In case of
97 /// errors, no side effects are produced.
98 llvm::Expected<std::vector<ParsedProcess>>
99 ParseCommonSessionFile(const JSONTraceSessionBase &session);
100
101 protected:
102 /// Resolve non-absolute paths relative to the session file folder. It
103 /// modifies the given file_spec.
104 void NormalizePath(lldb_private::FileSpec &file_spec);
105
106 ThreadTraceSP ParseThread(lldb::ProcessSP &process_sp,
107 const JSONThread &thread);
108
109 llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process);
110
111 llvm::Error ParseModule(lldb::TargetSP &target_sp, const JSONModule &module);
112
113 /// Create a user-friendly error message upon a JSON-parsing failure using the
114 /// \a json::ObjectMapper functionality.
115 ///
116 /// \param[in] root
117 /// The \a llvm::json::Path::Root used to parse the JSON \a value.
118 ///
119 /// \param[in] value
120 /// The json value that failed to parse.
121 ///
122 /// \return
123 /// An \a llvm::Error containing the user-friendly error message.
124 llvm::Error CreateJSONError(llvm::json::Path::Root &root,
125 const llvm::json::Value &value);
126
127 Debugger &m_debugger;
128 std::string m_session_file_dir;
129 llvm::StringRef m_schema;
130 };
131 } // namespace lldb_private
132
133 namespace llvm {
134 namespace json {
135
136 bool fromJSON(const Value &value,
137 lldb_private::TraceSessionFileParser::JSONAddress &address,
138 Path path);
139
140 bool fromJSON(const Value &value,
141 lldb_private::TraceSessionFileParser::JSONModule &module,
142 Path path);
143
144 bool fromJSON(const Value &value,
145 lldb_private::TraceSessionFileParser::JSONThread &thread,
146 Path path);
147
148 bool fromJSON(const Value &value,
149 lldb_private::TraceSessionFileParser::JSONProcess &process,
150 Path path);
151
152 bool fromJSON(const Value &value,
153 lldb_private::TraceSessionFileParser::JSONTracePluginSettings
154 &plugin_settings,
155 Path path);
156
157 bool fromJSON(
158 const Value &value,
159 lldb_private::TraceSessionFileParser::JSONTraceSessionBase &session,
160 Path path);
161
162 template <class TPluginSettings>
fromJSON(const Value & value,lldb_private::TraceSessionFileParser::JSONTraceSession<TPluginSettings> & session,Path path)163 bool fromJSON(
164 const Value &value,
165 lldb_private::TraceSessionFileParser::JSONTraceSession<TPluginSettings>
166 &session,
167 Path path) {
168 ObjectMapper o(value, path);
169 return o && o.map("trace", session.trace) &&
170 fromJSON(value,
171 (lldb_private::TraceSessionFileParser::JSONTraceSessionBase &)
172 session,
173 path);
174 }
175
176 } // namespace json
177 } // namespace llvm
178
179 #endif // LLDB_TARGET_TRACESESSIONPARSER_H
180