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() : Options() { 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  m_options() {}
79 
80  ~CommandObjectTraceLoad() override = default;
81 
82  Options *GetOptions() override { return &m_options; }
83 
84 protected:
85  bool DoExecute(Args &command, CommandReturnObject &result) override {
86  if (command.size() != 1) {
87  result.AppendError(
88  "a single path to a JSON file containing a trace session"
89  "is required");
90  return false;
91  }
92 
93  auto end_with_failure = [&result](llvm::Error err) -> bool {
94  result.AppendErrorWithFormat("%s\n",
95  llvm::toString(std::move(err)).c_str());
96  return false;
97  };
98 
99  FileSpec json_file(command[0].ref());
100 
101  auto buffer_or_error = llvm::MemoryBuffer::getFile(json_file.GetPath());
102  if (!buffer_or_error) {
103  return end_with_failure(llvm::createStringError(
104  std::errc::invalid_argument, "could not open input file: %s - %s.",
105  json_file.GetPath().c_str(),
106  buffer_or_error.getError().message().c_str()));
107  }
108 
109  llvm::Expected<json::Value> session_file =
110  json::parse(buffer_or_error.get()->getBuffer().str());
111  if (!session_file)
112  return end_with_failure(session_file.takeError());
113 
114  if (Expected<lldb::TraceSP> traceOrErr =
115  Trace::FindPluginForPostMortemProcess(
116  GetDebugger(), *session_file,
117  json_file.GetDirectory().AsCString())) {
118  lldb::TraceSP trace_sp = traceOrErr.get();
119  if (m_options.m_verbose && trace_sp)
120  result.AppendMessageWithFormat("loading trace with plugin %s\n",
121  trace_sp->GetPluginName().AsCString());
122  } else
123  return end_with_failure(traceOrErr.takeError());
124 
126  return true;
127  }
128 
130 };
131 
132 // CommandObjectTraceDump
133 #define LLDB_OPTIONS_trace_dump
134 #include "CommandOptions.inc"
135 
136 #pragma mark CommandObjectTraceDump
137 
139 public:
140  class CommandOptions : public Options {
141  public:
142  CommandOptions() : Options() { OptionParsingStarting(nullptr); }
143 
144  ~CommandOptions() override = default;
145 
146  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
147  ExecutionContext *execution_context) override {
148  Status error;
149  const int short_option = m_getopt_table[option_idx].val;
150 
151  switch (short_option) {
152  case 'v': {
153  m_verbose = true;
154  break;
155  }
156  default:
157  llvm_unreachable("Unimplemented option");
158  }
159  return error;
160  }
161 
162  void OptionParsingStarting(ExecutionContext *execution_context) override {
163  m_verbose = false;
164  }
165 
166  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
167  return llvm::makeArrayRef(g_trace_dump_options);
168  }
169 
170  bool m_verbose; // Enable verbose logging for debugging purposes.
171  };
172 
174  : CommandObjectParsed(interpreter, "trace dump",
175  "Dump the loaded processor trace data.",
176  "trace dump"),
177  m_options() {}
178 
179  ~CommandObjectTraceDump() override = default;
180 
181  Options *GetOptions() override { return &m_options; }
182 
183 protected:
184  bool DoExecute(Args &command, CommandReturnObject &result) override {
185  Status error;
186  // TODO: fill in the dumping code here!
187  if (error.Success()) {
189  } else {
190  result.AppendErrorWithFormat("%s\n", error.AsCString());
191  }
192  return result.Succeeded();
193  }
194 
196 };
197 
198 // CommandObjectTraceSchema
199 #define LLDB_OPTIONS_trace_schema
200 #include "CommandOptions.inc"
201 
202 #pragma mark CommandObjectTraceSchema
203 
205 public:
206  class CommandOptions : public Options {
207  public:
208  CommandOptions() : Options() { OptionParsingStarting(nullptr); }
209 
210  ~CommandOptions() override = default;
211 
212  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
213  ExecutionContext *execution_context) override {
214  Status error;
215  const int short_option = m_getopt_table[option_idx].val;
216 
217  switch (short_option) {
218  case 'v': {
219  m_verbose = true;
220  break;
221  }
222  default:
223  llvm_unreachable("Unimplemented option");
224  }
225  return error;
226  }
227 
228  void OptionParsingStarting(ExecutionContext *execution_context) override {
229  m_verbose = false;
230  }
231 
232  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
233  return llvm::makeArrayRef(g_trace_schema_options);
234  }
235 
236  bool m_verbose; // Enable verbose logging for debugging purposes.
237  };
238 
240  : CommandObjectParsed(interpreter, "trace schema",
241  "Show the schema of the given trace plugin.",
242  "trace schema <plug-in>. Use the plug-in name "
243  "\"all\" to see all schemas.\n"),
244  m_options() {}
245 
246  ~CommandObjectTraceSchema() override = default;
247 
248  Options *GetOptions() override { return &m_options; }
249 
250 protected:
251  bool DoExecute(Args &command, CommandReturnObject &result) override {
252  Status error;
253  if (command.empty()) {
254  result.AppendError(
255  "trace schema cannot be invoked without a plug-in as argument");
256  return false;
257  }
258 
259  StringRef plugin_name(command[0].c_str());
260  if (plugin_name == "all") {
261  size_t index = 0;
262  while (true) {
263  StringRef schema = PluginManager::GetTraceSchema(index++);
264  if (schema.empty())
265  break;
266 
267  result.AppendMessage(schema);
268  }
269  } else {
270  if (Expected<StringRef> schemaOrErr =
271  Trace::FindPluginSchema(plugin_name))
272  result.AppendMessage(*schemaOrErr);
273  else
274  error = schemaOrErr.takeError();
275  }
276 
277  if (error.Success()) {
279  } else {
280  result.AppendErrorWithFormat("%s\n", error.AsCString());
281  }
282  return result.Succeeded();
283  }
284 
286 };
287 
288 // CommandObjectTrace
289 
290 CommandObjectTrace::CommandObjectTrace(CommandInterpreter &interpreter)
291  : CommandObjectMultiword(interpreter, "trace",
292  "Commands for loading and using processor "
293  "trace information.",
294  "trace [<sub-command-options>]") {
295  LoadSubCommand("load",
296  CommandObjectSP(new CommandObjectTraceLoad(interpreter)));
297  LoadSubCommand("dump",
298  CommandObjectSP(new CommandObjectTraceDump(interpreter)));
299  LoadSubCommand("schema",
300  CommandObjectSP(new CommandObjectTraceSchema(interpreter)));
301 }
302 
304 
306  ProcessSP process_sp = m_interpreter.GetExecutionContext().GetProcessSP();
307 
308  if (!process_sp)
309  return createStringError(inconvertibleErrorCode(),
310  "Process not available.");
311  if (m_live_debug_session_only && !process_sp->IsLiveDebugSession())
312  return createStringError(inconvertibleErrorCode(),
313  "Process must be alive.");
314 
315  if (Expected<TraceSP> trace_sp = process_sp->GetTarget().GetTraceOrCreate())
316  return GetDelegateCommand(**trace_sp);
317  else
318  return createStringError(inconvertibleErrorCode(),
319  "Tracing is not supported. %s",
320  toString(trace_sp.takeError()).c_str());
321 }
322 
324  if (Expected<CommandObjectSP> delegate = DoGetProxyCommandObject()) {
325  m_delegate_sp = *delegate;
326  m_delegate_error.clear();
327  return m_delegate_sp.get();
328  } else {
329  m_delegate_sp.reset();
330  m_delegate_error = toString(delegate.takeError());
331  return nullptr;
332  }
333 }
lldb_private::CommandObjectParsed
Definition: CommandObject.h:378
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
lldb_private::CommandObjectTraceProxy::DoGetProxyCommandObject
llvm::Expected< lldb::CommandObjectSP > DoGetProxyCommandObject()
Definition: CommandObjectTrace.cpp:305
llvm
Definition: Debugger.h:49
OptionGroupFormat.h
CommandObjectTraceDump::CommandOptions
Definition: CommandObjectTrace.cpp:140
CommandObjectTraceDump::GetOptions
Options * GetOptions() override
Definition: CommandObjectTrace.cpp:181
CommandObjectTraceSchema
Definition: CommandObjectTrace.cpp:204
CommandObjectTraceSchema::CommandOptions::CommandOptions
CommandOptions()
Definition: CommandObjectTrace.cpp:208
CommandObjectTraceDump::m_options
CommandOptions m_options
Definition: CommandObjectTrace.cpp:195
CommandObjectTraceLoad::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: CommandObjectTrace.cpp:85
CommandObjectTraceDump::CommandOptions::CommandOptions
CommandOptions()
Definition: CommandObjectTrace.cpp:142
CommandObjectTraceLoad::CommandOptions::CommandOptions
CommandOptions()
Definition: CommandObjectTrace.cpp:43
CommandObjectTraceLoad::GetOptions
Options * GetOptions() override
Definition: CommandObjectTrace.cpp:82
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
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:184
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:166
lldb_private::Options
Definition: Options.h:57
lldb_private::breakpad::toString
llvm::StringRef toString(Record::Kind K)
Definition: BreakpadRecords.cpp:483
lldb_private::CommandObjectMultiword::LoadSubCommand
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
Definition: CommandObjectMultiword.cpp:68
CommandObjectTraceSchema::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: CommandObjectTrace.cpp:251
OptionValueLanguage.h
lldb_private::CommandReturnObject::SetStatus
void SetStatus(lldb::ReturnStatus status)
Definition: CommandReturnObject.cpp:121
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:146
lldb_private::CommandInterpreter
Definition: CommandInterpreter.h:214
lldb_private::CommandObject::m_interpreter
CommandInterpreter & m_interpreter
Definition: CommandObject.h:358
CommandObjectTraceSchema::CommandObjectTraceSchema
CommandObjectTraceSchema(CommandInterpreter &interpreter)
Definition: CommandObjectTrace.cpp:239
CommandObjectTraceDump::CommandOptions::m_verbose
bool m_verbose
Definition: CommandObjectTrace.cpp:170
CommandObjectTraceSchema::CommandOptions::GetDefinitions
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Definition: CommandObjectTrace.cpp:232
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:162
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:212
lldb_private::CommandReturnObject
Definition: CommandReturnObject.h:25
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:173
lldb_private::CommandReturnObject::AppendMessageWithFormat
void AppendMessageWithFormat(const char *format,...) __attribute__((format(printf
Definition: CommandReturnObject.cpp:64
lldb_private::CommandReturnObject::Succeeded
bool Succeeded()
Definition: CommandReturnObject.cpp:125
PluginManager.h
CommandObjectTraceDump
Definition: CommandObjectTrace.cpp:138
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:248
OptionParser.h
CommandObjectTraceLoad::m_options
CommandOptions m_options
Definition: CommandObjectTrace.cpp:129
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:29
CommandObjectTraceSchema::m_options
CommandOptions m_options
Definition: CommandObjectTrace.cpp:285
CommandInterpreter.h
lldb_private::FileSpec::GetDirectory
ConstString & GetDirectory()
Directory string get accessor.
Definition: FileSpec.cpp:335
lldb_private::CommandInterpreter::GetExecutionContext
ExecutionContext GetExecutionContext() const
CommandObjectTraceSchema::CommandOptions::m_verbose
bool m_verbose
Definition: CommandObjectTrace.cpp:236
lldb_private::Args::empty
bool empty() const
Definition: Args.h:120
CommandObjectTraceSchema::CommandOptions::OptionParsingStarting
void OptionParsingStarting(ExecutionContext *execution_context) override
Definition: CommandObjectTrace.cpp:228
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:206
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:348
lldb_private::CommandObjectTraceProxy::GetProxyCommandObject
CommandObject * GetProxyCommandObject() override
Definition: CommandObjectTrace.cpp:323
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::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