LLDB  mainline
CommandObjectTrace.cpp
Go to the documentation of this file.
1 //===-- CommandObjectTrace.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 "CommandObjectTrace.h"
10 
11 #include "llvm/Support/JSON.h"
12 #include "llvm/Support/MemoryBuffer.h"
13 
14 #include "lldb/Core/Debugger.h"
16 #include "lldb/Host/OptionParser.h"
26 #include "lldb/Target/Process.h"
27 #include "lldb/Target/Trace.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 using namespace llvm;
32 
33 // CommandObjectTraceLoad
34 #define LLDB_OPTIONS_trace_load
35 #include "CommandOptions.inc"
36 
37 #pragma mark CommandObjectTraceLoad
38 
40 public:
41  class CommandOptions : public Options {
42  public:
43  CommandOptions() { OptionParsingStarting(nullptr); }
44 
45  ~CommandOptions() override = default;
46 
47  Status SetOptionValue(uint32_t option_idx, StringRef option_arg,
48  ExecutionContext *execution_context) override {
49  Status error;
50  const int short_option = m_getopt_table[option_idx].val;
51 
52  switch (short_option) {
53  case 'v': {
54  m_verbose = true;
55  break;
56  }
57  default:
58  llvm_unreachable("Unimplemented option");
59  }
60  return error;
61  }
62 
63  void OptionParsingStarting(ExecutionContext *execution_context) override {
64  m_verbose = false;
65  }
66 
67  ArrayRef<OptionDefinition> GetDefinitions() override {
68  return makeArrayRef(g_trace_load_options);
69  }
70 
71  bool m_verbose; // Enable verbose logging for debugging purposes.
72  };
73 
75  : CommandObjectParsed(interpreter, "trace load",
76  "Load a processor trace session from a JSON file.",
77  "trace load") {}
78 
79  ~CommandObjectTraceLoad() override = default;
80 
81  Options *GetOptions() override { return &m_options; }
82 
83 protected:
84  bool DoExecute(Args &command, CommandReturnObject &result) override {
85  if (command.size() != 1) {
86  result.AppendError(
87  "a single path to a JSON file containing a trace session"
88  "is required");
89  return false;
90  }
91 
92  auto end_with_failure = [&result](llvm::Error err) -> bool {
93  result.AppendErrorWithFormat("%s\n",
94  llvm::toString(std::move(err)).c_str());
95  return false;
96  };
97 
98  FileSpec json_file(command[0].ref());
99 
100  auto buffer_or_error = llvm::MemoryBuffer::getFile(json_file.GetPath());
101  if (!buffer_or_error) {
102  return end_with_failure(llvm::createStringError(
103  std::errc::invalid_argument, "could not open input file: %s - %s.",
104  json_file.GetPath().c_str(),
105  buffer_or_error.getError().message().c_str()));
106  }
107 
108  llvm::Expected<json::Value> session_file =
109  json::parse(buffer_or_error.get()->getBuffer().str());
110  if (!session_file)
111  return end_with_failure(session_file.takeError());
112 
113  if (Expected<lldb::TraceSP> traceOrErr =
114  Trace::FindPluginForPostMortemProcess(
115  GetDebugger(), *session_file,
116  json_file.GetDirectory().AsCString())) {
117  lldb::TraceSP trace_sp = traceOrErr.get();
118  if (m_options.m_verbose && trace_sp)
119  result.AppendMessageWithFormatv("loading trace with plugin {0}\n",
120  trace_sp->GetPluginName());
121  } else
122  return end_with_failure(traceOrErr.takeError());
123 
125  return true;
126  }
127 
129 };
130 
131 // CommandObjectTraceDump
132 #define LLDB_OPTIONS_trace_dump
133 #include "CommandOptions.inc"
134 
135 #pragma mark CommandObjectTraceDump
136 
138 public:
139  class CommandOptions : public Options {
140  public:
141  CommandOptions() { OptionParsingStarting(nullptr); }
142 
143  ~CommandOptions() override = default;
144 
145  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
146  ExecutionContext *execution_context) override {
147  Status error;
148  const int short_option = m_getopt_table[option_idx].val;
149 
150  switch (short_option) {
151  case 'v': {
152  m_verbose = true;
153  break;
154  }
155  default:
156  llvm_unreachable("Unimplemented option");
157  }
158  return error;
159  }
160 
161  void OptionParsingStarting(ExecutionContext *execution_context) override {
162  m_verbose = false;
163  }
164 
165  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
166  return llvm::makeArrayRef(g_trace_dump_options);
167  }
168 
169  bool m_verbose; // Enable verbose logging for debugging purposes.
170  };
171 
173  : CommandObjectParsed(interpreter, "trace dump",
174  "Dump the loaded processor trace data.",
175  "trace dump") {}
176 
177  ~CommandObjectTraceDump() override = default;
178 
179  Options *GetOptions() override { return &m_options; }
180 
181 protected:
182  bool DoExecute(Args &command, CommandReturnObject &result) override {
183  Status error;
184  // TODO: fill in the dumping code here!
185  if (error.Success()) {
187  } else {
188  result.AppendErrorWithFormat("%s\n", error.AsCString());
189  }
190  return result.Succeeded();
191  }
192 
194 };
195 
196 // CommandObjectTraceSchema
197 #define LLDB_OPTIONS_trace_schema
198 #include "CommandOptions.inc"
199 
200 #pragma mark CommandObjectTraceSchema
201 
203 public:
204  class CommandOptions : public Options {
205  public:
206  CommandOptions() { OptionParsingStarting(nullptr); }
207 
208  ~CommandOptions() override = default;
209 
210  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
211  ExecutionContext *execution_context) override {
212  Status error;
213  const int short_option = m_getopt_table[option_idx].val;
214 
215  switch (short_option) {
216  case 'v': {
217  m_verbose = true;
218  break;
219  }
220  default:
221  llvm_unreachable("Unimplemented option");
222  }
223  return error;
224  }
225 
226  void OptionParsingStarting(ExecutionContext *execution_context) override {
227  m_verbose = false;
228  }
229 
230  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
231  return llvm::makeArrayRef(g_trace_schema_options);
232  }
233 
234  bool m_verbose; // Enable verbose logging for debugging purposes.
235  };
236 
238  : CommandObjectParsed(interpreter, "trace schema",
239  "Show the schema of the given trace plugin.",
240  "trace schema <plug-in>. Use the plug-in name "
241  "\"all\" to see all schemas.\n") {}
242 
243  ~CommandObjectTraceSchema() override = default;
244 
245  Options *GetOptions() override { return &m_options; }
246 
247 protected:
248  bool DoExecute(Args &command, CommandReturnObject &result) override {
249  Status error;
250  if (command.empty()) {
251  result.AppendError(
252  "trace schema cannot be invoked without a plug-in as argument");
253  return false;
254  }
255 
256  StringRef plugin_name(command[0].c_str());
257  if (plugin_name == "all") {
258  size_t index = 0;
259  while (true) {
260  StringRef schema = PluginManager::GetTraceSchema(index++);
261  if (schema.empty())
262  break;
263 
264  result.AppendMessage(schema);
265  }
266  } else {
267  if (Expected<StringRef> schemaOrErr =
268  Trace::FindPluginSchema(plugin_name))
269  result.AppendMessage(*schemaOrErr);
270  else
271  error = schemaOrErr.takeError();
272  }
273 
274  if (error.Success()) {
276  } else {
277  result.AppendErrorWithFormat("%s\n", error.AsCString());
278  }
279  return result.Succeeded();
280  }
281 
283 };
284 
285 // CommandObjectTrace
286 
287 CommandObjectTrace::CommandObjectTrace(CommandInterpreter &interpreter)
288  : CommandObjectMultiword(interpreter, "trace",
289  "Commands for loading and using processor "
290  "trace information.",
291  "trace [<sub-command-options>]") {
292  LoadSubCommand("load",
293  CommandObjectSP(new CommandObjectTraceLoad(interpreter)));
294  LoadSubCommand("dump",
295  CommandObjectSP(new CommandObjectTraceDump(interpreter)));
296  LoadSubCommand("schema",
297  CommandObjectSP(new CommandObjectTraceSchema(interpreter)));
298 }
299 
301 
303  ProcessSP process_sp = m_interpreter.GetExecutionContext().GetProcessSP();
304 
305  if (!process_sp)
306  return createStringError(inconvertibleErrorCode(),
307  "Process not available.");
308  if (m_live_debug_session_only && !process_sp->IsLiveDebugSession())
309  return createStringError(inconvertibleErrorCode(),
310  "Process must be alive.");
311 
312  if (Expected<TraceSP> trace_sp = process_sp->GetTarget().GetTraceOrCreate())
313  return GetDelegateCommand(**trace_sp);
314  else
315  return createStringError(inconvertibleErrorCode(),
316  "Tracing is not supported. %s",
317  toString(trace_sp.takeError()).c_str());
318 }
319 
321  if (Expected<CommandObjectSP> delegate = DoGetProxyCommandObject()) {
322  m_delegate_sp = *delegate;
323  m_delegate_error.clear();
324  return m_delegate_sp.get();
325  } else {
326  m_delegate_sp.reset();
327  m_delegate_error = toString(delegate.takeError());
328  return nullptr;
329  }
330 }
lldb_private::toString
const char * toString(AppleArm64ExceptionClass EC)
Definition: AppleArm64ExceptionClass.h:38
lldb_private::CommandObjectParsed
Definition: CommandObject.h:393
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
lldb_private::CommandObjectTraceProxy::DoGetProxyCommandObject
llvm::Expected< lldb::CommandObjectSP > DoGetProxyCommandObject()
Definition: CommandObjectTrace.cpp:302
llvm
Definition: Debugger.h:50
OptionGroupFormat.h
CommandObjectTraceDump::CommandOptions
Definition: CommandObjectTrace.cpp:139
CommandObjectTraceDump::GetOptions
Options * GetOptions() override
Definition: CommandObjectTrace.cpp:179
CommandObjectTraceSchema
Definition: CommandObjectTrace.cpp:202
CommandObjectTraceSchema::CommandOptions::CommandOptions
CommandOptions()
Definition: CommandObjectTrace.cpp:206
CommandObjectTraceDump::m_options
CommandOptions m_options
Definition: CommandObjectTrace.cpp:193
CommandObjectTraceLoad::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: CommandObjectTrace.cpp:84
CommandObjectTraceDump::CommandOptions::CommandOptions
CommandOptions()
Definition: CommandObjectTrace.cpp:141
CommandObjectTraceLoad::CommandOptions::CommandOptions
CommandOptions()
Definition: CommandObjectTrace.cpp:43
CommandObjectTraceLoad::GetOptions
Options * GetOptions() override
Definition: CommandObjectTrace.cpp:81
CommandObjectTraceLoad::CommandOptions
Definition: CommandObjectTrace.cpp:41
OptionArgParser.h
lldb_private::ConstString::AsCString
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:193
Trace.h
lldb_private::Args
Definition: Args.h:33
lldb_private::CommandReturnObject::Succeeded
bool Succeeded() const
Definition: CommandReturnObject.cpp:131
CommandObjectTraceLoad::CommandOptions::OptionParsingStarting
void OptionParsingStarting(ExecutionContext *execution_context) override
Definition: CommandObjectTrace.cpp:63
CommandReturnObject.h
Debugger.h
CommandObjectTrace.h
CommandObjectTraceLoad::CommandOptions::GetDefinitions
ArrayRef< OptionDefinition > GetDefinitions() override
Definition: CommandObjectTrace.cpp:67
CommandObjectTraceLoad::CommandObjectTraceLoad
CommandObjectTraceLoad(CommandInterpreter &interpreter)
Definition: CommandObjectTrace.cpp:74
Process.h
CommandObjectTraceDump::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: CommandObjectTrace.cpp:182
lldb_private::FileSpec
Definition: FileSpec.h:56
lldb_private::CommandObjectMultiword
Definition: CommandObjectMultiword.h:19
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
Options.h
CommandObjectTraceDump::CommandOptions::GetDefinitions
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Definition: CommandObjectTrace.cpp:165
lldb_private::Options
Definition: Options.h:57
lldb_private::CommandObjectMultiword::LoadSubCommand
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
Definition: CommandObjectMultiword.cpp:80
CommandObjectTraceSchema::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: CommandObjectTrace.cpp:248
OptionValueLanguage.h
lldb_private::CommandReturnObject::SetStatus
void SetStatus(lldb::ReturnStatus status)
Definition: CommandReturnObject.cpp:127
CommandObjectTraceLoad::CommandOptions::m_verbose
bool m_verbose
Definition: CommandObjectTrace.cpp:71
CommandObjectTraceDump::CommandOptions::SetOptionValue
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
Definition: CommandObjectTrace.cpp:145
lldb_private::CommandInterpreter
Definition: CommandInterpreter.h:214
lldb_private::CommandObject::m_interpreter
CommandInterpreter & m_interpreter
Definition: CommandObject.h:372
CommandObjectTraceSchema::CommandObjectTraceSchema
CommandObjectTraceSchema(CommandInterpreter &interpreter)
Definition: CommandObjectTrace.cpp:237
CommandObjectTraceDump::CommandOptions::m_verbose
bool m_verbose
Definition: CommandObjectTrace.cpp:169
CommandObjectTraceSchema::CommandOptions::GetDefinitions
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Definition: CommandObjectTrace.cpp:230
OptionValueString.h
lldb_private::CommandObject
Definition: CommandObject.h:67
lldb_private::CommandObjectTraceProxy::m_live_debug_session_only
bool m_live_debug_session_only
Definition: CommandObjectTrace.h:44
lldb_private::CommandObjectTrace::~CommandObjectTrace
~CommandObjectTrace() override
lldb_private::ExecutionContext::GetProcessSP
const lldb::ProcessSP & GetProcessSP() const
Get accessor to get the process shared pointer.
Definition: ExecutionContext.h:459
lldb_private::Status
Definition: Status.h:44
CommandObjectTraceDump::CommandOptions::OptionParsingStarting
void OptionParsingStarting(ExecutionContext *execution_context) override
Definition: CommandObjectTrace.cpp:161
CommandObjectTraceSchema::CommandOptions::SetOptionValue
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
Definition: CommandObjectTrace.cpp:210
lldb_private::CommandReturnObject
Definition: CommandReturnObject.h:26
lldb_private::CommandObjectTraceProxy::GetDelegateCommand
virtual lldb::CommandObjectSP GetDelegateCommand(Trace &trace)=0
uint32_t
CommandObject.h
lldb::eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishResult
Definition: lldb-enumerations.h:261
CommandObjectTraceDump::CommandObjectTraceDump
CommandObjectTraceDump(CommandInterpreter &interpreter)
Definition: CommandObjectTrace.cpp:172
PluginManager.h
CommandObjectTraceDump
Definition: CommandObjectTrace.cpp:137
CommandObjectTraceLoad
Definition: CommandObjectTrace.cpp:39
lldb_private::CommandReturnObject::AppendErrorWithFormat
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
Definition: CommandReturnObject.cpp:46
CommandObjectTraceSchema::GetOptions
Options * GetOptions() override
Definition: CommandObjectTrace.cpp:245
OptionParser.h
CommandObjectTraceLoad::m_options
CommandOptions m_options
Definition: CommandObjectTrace.cpp:128
lldb_private::CommandObjectTraceProxy::m_delegate_sp
lldb::CommandObjectSP m_delegate_sp
Definition: CommandObjectTrace.h:45
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
Error
llvm::Error Error
Definition: UdtRecordCompleter.cpp:30
CommandObjectTraceSchema::m_options
CommandOptions m_options
Definition: CommandObjectTrace.cpp:282
CommandInterpreter.h
lldb_private::FileSpec::GetDirectory
ConstString & GetDirectory()
Directory string get accessor.
Definition: FileSpec.cpp:334
lldb_private::CommandInterpreter::GetExecutionContext
ExecutionContext GetExecutionContext() const
CommandObjectTraceSchema::CommandOptions::m_verbose
bool m_verbose
Definition: CommandObjectTrace.cpp:234
lldb_private::Args::empty
bool empty() const
Definition: Args.h:120
CommandObjectTraceSchema::CommandOptions::OptionParsingStarting
void OptionParsingStarting(ExecutionContext *execution_context) override
Definition: CommandObjectTrace.cpp:226
OptionValueBoolean.h
CommandObjectTraceLoad::CommandOptions::SetOptionValue
Status SetOptionValue(uint32_t option_idx, StringRef option_arg, ExecutionContext *execution_context) override
Definition: CommandObjectTrace.cpp:47
CommandObjectTraceSchema::CommandOptions
Definition: CommandObjectTrace.cpp:204
lldb_private::FileSpec::GetPath
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:347
lldb_private::CommandObjectTraceProxy::GetProxyCommandObject
CommandObject * GetProxyCommandObject() override
Definition: CommandObjectTrace.cpp:320
lldb_private::CommandReturnObject::AppendError
void void AppendError(llvm::StringRef in_string)
Definition: CommandReturnObject.cpp:100
lldb
Definition: SBAddress.h:15
lldb_private::CommandReturnObject::AppendMessage
void AppendMessage(llvm::StringRef in_string)
Definition: CommandReturnObject.cpp:88
lldb_private::CommandReturnObject::AppendMessageWithFormatv
void void AppendMessageWithFormatv(const char *format, Args &&... args)
Definition: CommandReturnObject.h:120
lldb_private::Args::size
size_t size() const
Definition: Args.h:137
lldb_private::CommandObjectTraceProxy::m_delegate_error
std::string m_delegate_error
Definition: CommandObjectTrace.h:46