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 #include "lldb/Target/Thread.h"
17 #include "lldb/Utility/Stream.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 using namespace llvm;
22 
23 // Helper structs used to extract the type of a trace session json without
24 // having to parse the entire object.
25 
26 struct JSONSimplePluginSettings {
27   std::string type;
28 };
29 
30 struct JSONSimpleTraceSession {
31   JSONSimplePluginSettings trace;
32 };
33 
34 namespace llvm {
35 namespace json {
36 
37 bool fromJSON(const Value &value, JSONSimplePluginSettings &plugin_settings,
38               Path path) {
39   json::ObjectMapper o(value, path);
40   return o && o.map("type", plugin_settings.type);
41 }
42 
43 bool fromJSON(const Value &value, JSONSimpleTraceSession &session, Path path) {
44   json::ObjectMapper o(value, path);
45   return o && o.map("trace", session.trace);
46 }
47 
48 } // namespace json
49 } // namespace llvm
50 
51 static Error createInvalidPlugInError(StringRef plugin_name) {
52   return createStringError(
53       std::errc::invalid_argument,
54       "no trace plug-in matches the specified type: \"%s\"",
55       plugin_name.data());
56 }
57 
58 Expected<lldb::TraceSP> Trace::FindPlugin(Debugger &debugger,
59                                           const json::Value &trace_session_file,
60                                           StringRef session_file_dir) {
61   JSONSimpleTraceSession json_session;
62   json::Path::Root root("traceSession");
63   if (!json::fromJSON(trace_session_file, json_session, root))
64     return root.getError();
65 
66   ConstString plugin_name(json_session.trace.type);
67   if (auto create_callback = PluginManager::GetTraceCreateCallback(plugin_name))
68     return create_callback(trace_session_file, session_file_dir, debugger);
69 
70   return createInvalidPlugInError(json_session.trace.type);
71 }
72 
73 Expected<StringRef> Trace::FindPluginSchema(StringRef name) {
74   ConstString plugin_name(name);
75   StringRef schema = PluginManager::GetTraceSchema(plugin_name);
76   if (!schema.empty())
77     return schema;
78 
79   return createInvalidPlugInError(name);
80 }
81 
82 void Trace::DumpTraceInstructions(Thread &thread, Stream &s, size_t count,
83                                   size_t start_position) const {
84   s.Printf("thread #%u: tid = %" PRIu64 ", total instructions = 1000\n",
85            thread.GetIndexID(), thread.GetID());
86   s.Printf("  would print %zu instructions from position %zu\n", count,
87            start_position);
88 }
89