1 //===-- Trace.cpp ---------------------------------------------------------===//
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 #include "lldb/Target/Trace.h"
10 
11 #include <sstream>
12 
13 #include "llvm/Support/Format.h"
14 
15 #include "lldb/Core/PluginManager.h"
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 using namespace llvm;
20 
21 // Helper structs used to extract the type of a trace settings json without
22 // having to parse the entire object.
23 
24 struct JSONSimplePluginSettings {
25   std::string type;
26 };
27 
28 struct JSONSimpleTraceSettings {
29   JSONSimplePluginSettings trace;
30 };
31 
32 namespace llvm {
33 namespace json {
34 
35 bool fromJSON(const json::Value &value,
36               JSONSimplePluginSettings &plugin_settings, json::Path path) {
37   json::ObjectMapper o(value, path);
38   return o && o.map("type", plugin_settings.type);
39 }
40 
41 bool fromJSON(const json::Value &value, JSONSimpleTraceSettings &settings,
42               json::Path path) {
43   json::ObjectMapper o(value, path);
44   return o && o.map("trace", settings.trace);
45 }
46 
47 } // namespace json
48 } // namespace llvm
49 
50 llvm::Expected<lldb::TraceSP> Trace::FindPlugin(Debugger &debugger,
51                                                 const json::Value &settings,
52                                                 StringRef info_dir) {
53   JSONSimpleTraceSettings json_settings;
54   json::Path::Root root("settings");
55   if (!json::fromJSON(settings, json_settings, root))
56     return root.getError();
57 
58   ConstString plugin_name(json_settings.trace.type);
59   auto create_callback = PluginManager::GetTraceCreateCallback(plugin_name);
60   if (create_callback) {
61     TraceSP instance = create_callback();
62     if (llvm::Error err = instance->ParseSettings(debugger, settings, info_dir))
63       return std::move(err);
64     return instance;
65   }
66 
67   return createStringError(
68       std::errc::invalid_argument,
69       "no trace plug-in matches the specified type: \"%s\"",
70       plugin_name.AsCString());
71 }
72 
73 llvm::Expected<lldb::TraceSP> Trace::FindPlugin(StringRef name) {
74   ConstString plugin_name(name);
75   auto create_callback = PluginManager::GetTraceCreateCallback(plugin_name);
76   if (create_callback)
77     return create_callback();
78 
79   return createStringError(
80       std::errc::invalid_argument,
81       "no trace plug-in matches the specified type: \"%s\"",
82       plugin_name.AsCString());
83 }
84 
85 llvm::Error Trace::ParseSettings(Debugger &debugger,
86                                  const llvm::json::Value &settings,
87                                  llvm::StringRef settings_dir) {
88   if (llvm::Error err =
89           CreateParser()->ParseSettings(debugger, settings, settings_dir))
90     return err;
91 
92   return llvm::Error::success();
93 }
94 
95 llvm::StringRef Trace::GetSchema() { return CreateParser()->GetSchema(); }
96