LLDB  mainline
CommandObjectSource.cpp
Go to the documentation of this file.
1 //===-- CommandObjectSource.cpp ---------------------------------*- 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 #include "CommandObjectSource.h"
10 
11 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
16 #include "lldb/Host/OptionParser.h"
23 #include "lldb/Symbol/Function.h"
24 #include "lldb/Symbol/Symbol.h"
25 #include "lldb/Target/Process.h"
27 #include "lldb/Target/StackFrame.h"
28 #include "lldb/Target/TargetList.h"
29 #include "lldb/Utility/FileSpec.h"
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 #pragma mark CommandObjectSourceInfo
35 // CommandObjectSourceInfo - debug line entries dumping command
36 
37 static constexpr OptionDefinition g_source_info_options[] = {
38  // clang-format off
39  { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "The number of line entries to display." },
40  { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source in the given module or shared library (can be specified more than once)." },
41  { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." },
42  { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to start the displaying lines." },
43  { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to stop displaying lines." },
44  { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." },
45  { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." },
46  // clang-format on
47 };
48 
50  class CommandOptions : public Options {
51  public:
52  CommandOptions() : Options() {}
53 
54  ~CommandOptions() override = default;
55 
56  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
57  ExecutionContext *execution_context) override {
58  Status error;
59  const int short_option = GetDefinitions()[option_idx].short_option;
60  switch (short_option) {
61  case 'l':
62  if (option_arg.getAsInteger(0, start_line))
63  error.SetErrorStringWithFormat("invalid line number: '%s'",
64  option_arg.str().c_str());
65  break;
66 
67  case 'e':
68  if (option_arg.getAsInteger(0, end_line))
69  error.SetErrorStringWithFormat("invalid line number: '%s'",
70  option_arg.str().c_str());
71  break;
72 
73  case 'c':
74  if (option_arg.getAsInteger(0, num_lines))
75  error.SetErrorStringWithFormat("invalid line count: '%s'",
76  option_arg.str().c_str());
77  break;
78 
79  case 'f':
80  file_name = option_arg;
81  break;
82 
83  case 'n':
84  symbol_name = option_arg;
85  break;
86 
87  case 'a': {
88  address = OptionArgParser::ToAddress(execution_context, option_arg,
89  LLDB_INVALID_ADDRESS, &error);
90  } break;
91  case 's':
92  modules.push_back(std::string(option_arg));
93  break;
94  default:
95  error.SetErrorStringWithFormat("unrecognized short option '%c'",
96  short_option);
97  break;
98  }
99 
100  return error;
101  }
102 
103  void OptionParsingStarting(ExecutionContext *execution_context) override {
104  file_spec.Clear();
105  file_name.clear();
106  symbol_name.clear();
107  address = LLDB_INVALID_ADDRESS;
108  start_line = 0;
109  end_line = 0;
110  num_lines = 0;
111  modules.clear();
112  }
113 
114  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
115  return llvm::makeArrayRef(g_source_info_options);
116  }
117 
118  // Instance variables to hold the values for command options.
119  FileSpec file_spec;
120  std::string file_name;
121  std::string symbol_name;
122  lldb::addr_t address;
123  uint32_t start_line;
124  uint32_t end_line;
125  uint32_t num_lines;
126  STLStringArray modules;
127  };
128 
129 public:
132  interpreter, "source info",
133  "Display source line information for the current target "
134  "process. Defaults to instruction pointer in current stack "
135  "frame.",
136  nullptr, eCommandRequiresTarget),
137  m_options() {}
138 
139  ~CommandObjectSourceInfo() override = default;
140 
141  Options *GetOptions() override { return &m_options; }
142 
143 protected:
144  // Dump the line entries in each symbol context. Return the number of entries
145  // found. If module_list is set, only dump lines contained in one of the
146  // modules. If file_spec is set, only dump lines in the file. If the
147  // start_line option was specified, don't print lines less than start_line.
148  // If the end_line option was specified, don't print lines greater than
149  // end_line. If the num_lines option was specified, dont print more than
150  // num_lines entries.
152  const SymbolContextList &sc_list,
153  const ModuleList &module_list,
154  const FileSpec &file_spec) {
155  uint32_t start_line = m_options.start_line;
156  uint32_t end_line = m_options.end_line;
157  uint32_t num_lines = m_options.num_lines;
158  Target *target = m_exe_ctx.GetTargetPtr();
159 
160  uint32_t num_matches = 0;
161  bool has_path = false;
162  if (file_spec) {
163  assert(file_spec.GetFilename().AsCString());
164  has_path = (file_spec.GetDirectory().AsCString() != nullptr);
165  }
166 
167  // Dump all the line entries for the file in the list.
168  ConstString last_module_file_name;
169  uint32_t num_scs = sc_list.GetSize();
170  for (uint32_t i = 0; i < num_scs; ++i) {
171  SymbolContext sc;
172  sc_list.GetContextAtIndex(i, sc);
173  if (sc.comp_unit) {
174  Module *module = sc.module_sp.get();
175  CompileUnit *cu = sc.comp_unit;
176  const LineEntry &line_entry = sc.line_entry;
177  assert(module && cu);
178 
179  // Are we looking for specific modules, files or lines?
180  if (module_list.GetSize() &&
181  module_list.GetIndexForModule(module) == LLDB_INVALID_INDEX32)
182  continue;
183  if (file_spec &&
184  !lldb_private::FileSpec::Equal(file_spec, line_entry.file,
185  has_path))
186  continue;
187  if (start_line > 0 && line_entry.line < start_line)
188  continue;
189  if (end_line > 0 && line_entry.line > end_line)
190  continue;
191  if (num_lines > 0 && num_matches > num_lines)
192  continue;
193 
194  // Print a new header if the module changed.
195  ConstString module_file_name =
196  module->GetFileSpec().GetFilename();
197  assert(module_file_name);
198  if (module_file_name != last_module_file_name) {
199  if (num_matches > 0)
200  strm << "\n\n";
201  strm << "Lines found in module `" << module_file_name << "\n";
202  }
203  // Dump the line entry.
204  line_entry.GetDescription(&strm, lldb::eDescriptionLevelBrief, cu,
205  target, /*show_address_only=*/false);
206  strm << "\n";
207  last_module_file_name = module_file_name;
208  num_matches++;
209  }
210  }
211  return num_matches;
212  }
213 
214  // Dump the requested line entries for the file in the compilation unit.
215  // Return the number of entries found. If module_list is set, only dump lines
216  // contained in one of the modules. If the start_line option was specified,
217  // don't print lines less than start_line. If the end_line option was
218  // specified, don't print lines greater than end_line. If the num_lines
219  // option was specified, dont print more than num_lines entries.
221  CompileUnit *cu, const FileSpec &file_spec) {
222  uint32_t start_line = m_options.start_line;
223  uint32_t end_line = m_options.end_line;
224  uint32_t num_lines = m_options.num_lines;
225  Target *target = m_exe_ctx.GetTargetPtr();
226 
227  uint32_t num_matches = 0;
228  assert(module);
229  if (cu) {
230  assert(file_spec.GetFilename().AsCString());
231  bool has_path = (file_spec.GetDirectory().AsCString() != nullptr);
232  const FileSpecList &cu_file_list = cu->GetSupportFiles();
233  size_t file_idx = cu_file_list.FindFileIndex(0, file_spec, has_path);
234  if (file_idx != UINT32_MAX) {
235  // Update the file to how it appears in the CU.
236  const FileSpec &cu_file_spec =
237  cu_file_list.GetFileSpecAtIndex(file_idx);
238 
239  // Dump all matching lines at or above start_line for the file in the
240  // CU.
241  ConstString file_spec_name = file_spec.GetFilename();
242  ConstString module_file_name =
243  module->GetFileSpec().GetFilename();
244  bool cu_header_printed = false;
245  uint32_t line = start_line;
246  while (true) {
247  LineEntry line_entry;
248 
249  // Find the lowest index of a line entry with a line equal to or
250  // higher than 'line'.
251  uint32_t start_idx = 0;
252  start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec,
253  /*exact=*/false, &line_entry);
254  if (start_idx == UINT32_MAX)
255  // No more line entries for our file in this CU.
256  break;
257 
258  if (end_line > 0 && line_entry.line > end_line)
259  break;
260 
261  // Loop through to find any other entries for this line, dumping
262  // each.
263  line = line_entry.line;
264  do {
265  num_matches++;
266  if (num_lines > 0 && num_matches > num_lines)
267  break;
268  assert(lldb_private::FileSpec::Equal(cu_file_spec, line_entry.file,
269  has_path));
270  if (!cu_header_printed) {
271  if (num_matches > 0)
272  strm << "\n\n";
273  strm << "Lines found for file " << file_spec_name
274  << " in compilation unit " << cu->GetFilename() << " in `"
275  << module_file_name << "\n";
276  cu_header_printed = true;
277  }
278  line_entry.GetDescription(&strm, lldb::eDescriptionLevelBrief, cu,
279  target, /*show_address_only=*/false);
280  strm << "\n";
281 
282  // Anymore after this one?
283  start_idx++;
284  start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec,
285  /*exact=*/true, &line_entry);
286  } while (start_idx != UINT32_MAX);
287 
288  // Try the next higher line, starting over at start_idx 0.
289  line++;
290  }
291  }
292  }
293  return num_matches;
294  }
295 
296  // Dump the requested line entries for the file in the module. Return the
297  // number of entries found. If module_list is set, only dump lines contained
298  // in one of the modules. If the start_line option was specified, don't print
299  // lines less than start_line. If the end_line option was specified, don't
300  // print lines greater than end_line. If the num_lines option was specified,
301  // dont print more than num_lines entries.
303  const FileSpec &file_spec) {
304  uint32_t num_matches = 0;
305  if (module) {
306  // Look through all the compilation units (CUs) in this module for ones
307  // that contain lines of code from this source file.
308  for (size_t i = 0; i < module->GetNumCompileUnits(); i++) {
309  // Look for a matching source file in this CU.
310  CompUnitSP cu_sp(module->GetCompileUnitAtIndex(i));
311  if (cu_sp) {
312  num_matches +=
313  DumpFileLinesInCompUnit(strm, module, cu_sp.get(), file_spec);
314  }
315  }
316  }
317  return num_matches;
318  }
319 
320  // Given an address and a list of modules, append the symbol contexts of all
321  // line entries containing the address found in the modules and return the
322  // count of matches. If none is found, return an error in 'error_strm'.
323  size_t GetSymbolContextsForAddress(const ModuleList &module_list,
324  lldb::addr_t addr,
325  SymbolContextList &sc_list,
326  StreamString &error_strm) {
327  Address so_addr;
328  size_t num_matches = 0;
329  assert(module_list.GetSize() > 0);
330  Target *target = m_exe_ctx.GetTargetPtr();
331  if (target->GetSectionLoadList().IsEmpty()) {
332  // The target isn't loaded yet, we need to lookup the file address in all
333  // modules. Note: the module list option does not apply to addresses.
334  const size_t num_modules = module_list.GetSize();
335  for (size_t i = 0; i < num_modules; ++i) {
336  ModuleSP module_sp(module_list.GetModuleAtIndex(i));
337  if (!module_sp)
338  continue;
339  if (module_sp->ResolveFileAddress(addr, so_addr)) {
340  SymbolContext sc;
341  sc.Clear(true);
342  if (module_sp->ResolveSymbolContextForAddress(
343  so_addr, eSymbolContextEverything, sc) &
344  eSymbolContextLineEntry) {
345  sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/false);
346  ++num_matches;
347  }
348  }
349  }
350  if (num_matches == 0)
351  error_strm.Printf("Source information for file address 0x%" PRIx64
352  " not found in any modules.\n",
353  addr);
354  } else {
355  // The target has some things loaded, resolve this address to a compile
356  // unit + file + line and display
357  if (target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
358  ModuleSP module_sp(so_addr.GetModule());
359  // Check to make sure this module is in our list.
360  if (module_sp &&
361  module_list.GetIndexForModule(module_sp.get()) !=
363  SymbolContext sc;
364  sc.Clear(true);
365  if (module_sp->ResolveSymbolContextForAddress(
366  so_addr, eSymbolContextEverything, sc) &
367  eSymbolContextLineEntry) {
368  sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/false);
369  ++num_matches;
370  } else {
371  StreamString addr_strm;
372  so_addr.Dump(&addr_strm, nullptr,
373  Address::DumpStyleModuleWithFileAddress);
374  error_strm.Printf(
375  "Address 0x%" PRIx64 " resolves to %s, but there is"
376  " no source information available for this address.\n",
377  addr, addr_strm.GetData());
378  }
379  } else {
380  StreamString addr_strm;
381  so_addr.Dump(&addr_strm, nullptr,
382  Address::DumpStyleModuleWithFileAddress);
383  error_strm.Printf("Address 0x%" PRIx64
384  " resolves to %s, but it cannot"
385  " be found in any modules.\n",
386  addr, addr_strm.GetData());
387  }
388  } else
389  error_strm.Printf("Unable to resolve address 0x%" PRIx64 ".\n", addr);
390  }
391  return num_matches;
392  }
393 
394  // Dump the line entries found in functions matching the name specified in
395  // the option.
397  SymbolContextList sc_list_funcs;
398  ConstString name(m_options.symbol_name.c_str());
399  SymbolContextList sc_list_lines;
400  Target *target = m_exe_ctx.GetTargetPtr();
401  uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
402 
403  // Note: module_list can't be const& because FindFunctionSymbols isn't
404  // const.
405  ModuleList module_list =
406  (m_module_list.GetSize() > 0) ? m_module_list : target->GetImages();
407  size_t num_matches =
408  module_list.FindFunctions(name, eFunctionNameTypeAuto,
409  /*include_symbols=*/false,
410  /*include_inlines=*/true,
411  /*append=*/true, sc_list_funcs);
412  if (!num_matches) {
413  // If we didn't find any functions with that name, try searching for
414  // symbols that line up exactly with function addresses.
415  SymbolContextList sc_list_symbols;
416  size_t num_symbol_matches = module_list.FindFunctionSymbols(
417  name, eFunctionNameTypeAuto, sc_list_symbols);
418  for (size_t i = 0; i < num_symbol_matches; i++) {
419  SymbolContext sc;
420  sc_list_symbols.GetContextAtIndex(i, sc);
421  if (sc.symbol && sc.symbol->ValueIsAddress()) {
422  const Address &base_address = sc.symbol->GetAddressRef();
423  Function *function = base_address.CalculateSymbolContextFunction();
424  if (function) {
425  sc_list_funcs.Append(SymbolContext(function));
426  num_matches++;
427  }
428  }
429  }
430  }
431  if (num_matches == 0) {
432  result.AppendErrorWithFormat("Could not find function named \'%s\'.\n",
433  m_options.symbol_name.c_str());
434  return false;
435  }
436  for (size_t i = 0; i < num_matches; i++) {
437  SymbolContext sc;
438  sc_list_funcs.GetContextAtIndex(i, sc);
439  bool context_found_for_symbol = false;
440  // Loop through all the ranges in the function.
441  AddressRange range;
442  for (uint32_t r = 0;
443  sc.GetAddressRange(eSymbolContextEverything, r,
444  /*use_inline_block_range=*/true, range);
445  ++r) {
446  // Append the symbol contexts for each address in the range to
447  // sc_list_lines.
448  const Address &base_address = range.GetBaseAddress();
449  const addr_t size = range.GetByteSize();
450  lldb::addr_t start_addr = base_address.GetLoadAddress(target);
451  if (start_addr == LLDB_INVALID_ADDRESS)
452  start_addr = base_address.GetFileAddress();
453  lldb::addr_t end_addr = start_addr + size;
454  for (lldb::addr_t addr = start_addr; addr < end_addr;
455  addr += addr_byte_size) {
456  StreamString error_strm;
457  if (!GetSymbolContextsForAddress(module_list, addr, sc_list_lines,
458  error_strm))
459  result.AppendWarningWithFormat("in symbol '%s': %s",
460  sc.GetFunctionName().AsCString(),
461  error_strm.GetData());
462  else
463  context_found_for_symbol = true;
464  }
465  }
466  if (!context_found_for_symbol)
467  result.AppendWarningWithFormat("Unable to find line information"
468  " for matching symbol '%s'.\n",
469  sc.GetFunctionName().AsCString());
470  }
471  if (sc_list_lines.GetSize() == 0) {
472  result.AppendErrorWithFormat("No line information could be found"
473  " for any symbols matching '%s'.\n",
474  name.AsCString());
475  return false;
476  }
477  FileSpec file_spec;
478  if (!DumpLinesInSymbolContexts(result.GetOutputStream(), sc_list_lines,
479  module_list, file_spec)) {
480  result.AppendErrorWithFormat(
481  "Unable to dump line information for symbol '%s'.\n",
482  name.AsCString());
483  return false;
484  }
485  return true;
486  }
487 
488  // Dump the line entries found for the address specified in the option.
490  Target *target = m_exe_ctx.GetTargetPtr();
491  SymbolContextList sc_list;
492 
493  StreamString error_strm;
494  if (!GetSymbolContextsForAddress(target->GetImages(), m_options.address,
495  sc_list, error_strm)) {
496  result.AppendErrorWithFormat("%s.\n", error_strm.GetData());
497  return false;
498  }
499  ModuleList module_list;
500  FileSpec file_spec;
501  if (!DumpLinesInSymbolContexts(result.GetOutputStream(), sc_list,
502  module_list, file_spec)) {
503  result.AppendErrorWithFormat("No modules contain load address 0x%" PRIx64
504  ".\n",
505  m_options.address);
506  return false;
507  }
508  return true;
509  }
510 
511  // Dump the line entries found in the file specified in the option.
513  FileSpec file_spec(m_options.file_name);
514  const char *filename = m_options.file_name.c_str();
515  Target *target = m_exe_ctx.GetTargetPtr();
516  const ModuleList &module_list =
517  (m_module_list.GetSize() > 0) ? m_module_list : target->GetImages();
518 
519  bool displayed_something = false;
520  const size_t num_modules = module_list.GetSize();
521  for (uint32_t i = 0; i < num_modules; ++i) {
522  // Dump lines for this module.
523  Module *module = module_list.GetModulePointerAtIndex(i);
524  assert(module);
525  if (DumpFileLinesInModule(result.GetOutputStream(), module, file_spec))
526  displayed_something = true;
527  }
528  if (!displayed_something) {
529  result.AppendErrorWithFormat("No source filenames matched '%s'.\n",
530  filename);
531  return false;
532  }
533  return true;
534  }
535 
536  // Dump the line entries for the current frame.
538  StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
539  if (cur_frame == nullptr) {
540  result.AppendError(
541  "No selected frame to use to find the default source.");
542  return false;
543  } else if (!cur_frame->HasDebugInformation()) {
544  result.AppendError("No debug info for the selected frame.");
545  return false;
546  } else {
547  const SymbolContext &sc =
548  cur_frame->GetSymbolContext(eSymbolContextLineEntry);
549  SymbolContextList sc_list;
550  sc_list.Append(sc);
551  ModuleList module_list;
552  FileSpec file_spec;
553  if (!DumpLinesInSymbolContexts(result.GetOutputStream(), sc_list,
554  module_list, file_spec)) {
555  result.AppendError(
556  "No source line info available for the selected frame.");
557  return false;
558  }
559  }
560  return true;
561  }
562 
563  bool DoExecute(Args &command, CommandReturnObject &result) override {
564  const size_t argc = command.GetArgumentCount();
565 
566  if (argc != 0) {
567  result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n",
568  GetCommandName().str().c_str());
570  return false;
571  }
572 
573  Target *target = m_exe_ctx.GetTargetPtr();
574  if (target == nullptr) {
575  target = GetDebugger().GetSelectedTarget().get();
576  if (target == nullptr) {
577  result.AppendError("invalid target, create a debug target using the "
578  "'target create' command.");
580  return false;
581  }
582  }
583 
584  uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
585  result.GetOutputStream().SetAddressByteSize(addr_byte_size);
586  result.GetErrorStream().SetAddressByteSize(addr_byte_size);
587 
588  // Collect the list of modules to search.
589  m_module_list.Clear();
590  if (!m_options.modules.empty()) {
591  for (size_t i = 0, e = m_options.modules.size(); i < e; ++i) {
592  FileSpec module_file_spec(m_options.modules[i]);
593  if (module_file_spec) {
594  ModuleSpec module_spec(module_file_spec);
595  if (target->GetImages().FindModules(module_spec, m_module_list) == 0)
596  result.AppendWarningWithFormat("No module found for '%s'.\n",
597  m_options.modules[i].c_str());
598  }
599  }
600  if (!m_module_list.GetSize()) {
601  result.AppendError("No modules match the input.");
603  return false;
604  }
605  } else if (target->GetImages().GetSize() == 0) {
606  result.AppendError("The target has no associated executable images.");
608  return false;
609  }
610 
611  // Check the arguments to see what lines we should dump.
612  if (!m_options.symbol_name.empty()) {
613  // Print lines for symbol.
614  if (DumpLinesInFunctions(result))
616  else
618  } else if (m_options.address != LLDB_INVALID_ADDRESS) {
619  // Print lines for an address.
620  if (DumpLinesForAddress(result))
622  else
624  } else if (!m_options.file_name.empty()) {
625  // Dump lines for a file.
626  if (DumpLinesForFile(result))
628  else
630  } else {
631  // Dump the line for the current frame.
632  if (DumpLinesForFrame(result))
634  else
636  }
637  return result.Succeeded();
638  }
639 
640  CommandOptions m_options;
642 };
643 
644 #pragma mark CommandObjectSourceList
645 // CommandObjectSourceList
646 
647 static constexpr OptionDefinition g_source_list_options[] = {
648  // clang-format off
649  { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "The number of source lines to display." },
650  { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library." },
651  { LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints." },
652  { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." },
653  { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to start the display source." },
654  { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." },
655  { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." },
656  { LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source." },
657  // clang-format on
658 };
659 
661  class CommandOptions : public Options {
662  public:
663  CommandOptions() : Options() {}
664 
665  ~CommandOptions() override = default;
666 
667  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
668  ExecutionContext *execution_context) override {
669  Status error;
670  const int short_option = GetDefinitions()[option_idx].short_option;
671  switch (short_option) {
672  case 'l':
673  if (option_arg.getAsInteger(0, start_line))
674  error.SetErrorStringWithFormat("invalid line number: '%s'",
675  option_arg.str().c_str());
676  break;
677 
678  case 'c':
679  if (option_arg.getAsInteger(0, num_lines))
680  error.SetErrorStringWithFormat("invalid line count: '%s'",
681  option_arg.str().c_str());
682  break;
683 
684  case 'f':
685  file_name = option_arg;
686  break;
687 
688  case 'n':
689  symbol_name = option_arg;
690  break;
691 
692  case 'a': {
693  address = OptionArgParser::ToAddress(execution_context, option_arg,
694  LLDB_INVALID_ADDRESS, &error);
695  } break;
696  case 's':
697  modules.push_back(std::string(option_arg));
698  break;
699 
700  case 'b':
701  show_bp_locs = true;
702  break;
703  case 'r':
704  reverse = true;
705  break;
706  default:
707  error.SetErrorStringWithFormat("unrecognized short option '%c'",
708  short_option);
709  break;
710  }
711 
712  return error;
713  }
714 
715  void OptionParsingStarting(ExecutionContext *execution_context) override {
716  file_spec.Clear();
717  file_name.clear();
718  symbol_name.clear();
719  address = LLDB_INVALID_ADDRESS;
720  start_line = 0;
721  num_lines = 0;
722  show_bp_locs = false;
723  reverse = false;
724  modules.clear();
725  }
726 
727  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
728  return llvm::makeArrayRef(g_source_list_options);
729  }
730 
731  // Instance variables to hold the values for command options.
732  FileSpec file_spec;
733  std::string file_name;
734  std::string symbol_name;
735  lldb::addr_t address;
736  uint32_t start_line;
737  uint32_t num_lines;
738  STLStringArray modules;
739  bool show_bp_locs;
740  bool reverse;
741  };
742 
743 public:
745  : CommandObjectParsed(interpreter, "source list",
746  "Display source code for the current target "
747  "process as specified by options.",
748  nullptr, eCommandRequiresTarget),
749  m_options() {}
750 
751  ~CommandObjectSourceList() override = default;
752 
753  Options *GetOptions() override { return &m_options; }
754 
755  const char *GetRepeatCommand(Args &current_command_args,
756  uint32_t index) override {
757  // This is kind of gross, but the command hasn't been parsed yet so we
758  // can't look at the option values for this invocation... I have to scan
759  // the arguments directly.
760  auto iter =
761  llvm::find_if(current_command_args, [](const Args::ArgEntry &e) {
762  return e.ref == "-r" || e.ref == "--reverse";
763  });
764  if (iter == current_command_args.end())
765  return m_cmd_name.c_str();
766 
767  if (m_reverse_name.empty()) {
768  m_reverse_name = m_cmd_name;
769  m_reverse_name.append(" -r");
770  }
771  return m_reverse_name.c_str();
772  }
773 
774 protected:
775  struct SourceInfo {
776  ConstString function;
778 
779  SourceInfo(ConstString name, const LineEntry &line_entry)
780  : function(name), line_entry(line_entry) {}
781 
782  SourceInfo() : function(), line_entry() {}
783 
784  bool IsValid() const { return (bool)function && line_entry.IsValid(); }
785 
786  bool operator==(const SourceInfo &rhs) const {
787  return function == rhs.function &&
788  line_entry.original_file == rhs.line_entry.original_file &&
789  line_entry.line == rhs.line_entry.line;
790  }
791 
792  bool operator!=(const SourceInfo &rhs) const {
793  return function != rhs.function ||
794  line_entry.original_file != rhs.line_entry.original_file ||
795  line_entry.line != rhs.line_entry.line;
796  }
797 
798  bool operator<(const SourceInfo &rhs) const {
799  if (function.GetCString() < rhs.function.GetCString())
800  return true;
801  if (line_entry.file.GetDirectory().GetCString() <
803  return true;
804  if (line_entry.file.GetFilename().GetCString() <
806  return true;
807  if (line_entry.line < rhs.line_entry.line)
808  return true;
809  return false;
810  }
811  };
812 
813  size_t DisplayFunctionSource(const SymbolContext &sc, SourceInfo &source_info,
814  CommandReturnObject &result) {
815  if (!source_info.IsValid()) {
816  source_info.function = sc.GetFunctionName();
817  source_info.line_entry = sc.GetFunctionStartLineEntry();
818  }
819 
820  if (sc.function) {
821  Target *target = m_exe_ctx.GetTargetPtr();
822 
823  FileSpec start_file;
824  uint32_t start_line;
825  uint32_t end_line;
826  FileSpec end_file;
827 
828  if (sc.block == nullptr) {
829  // Not an inlined function
830  sc.function->GetStartLineSourceInfo(start_file, start_line);
831  if (start_line == 0) {
832  result.AppendErrorWithFormat("Could not find line information for "
833  "start of function: \"%s\".\n",
834  source_info.function.GetCString());
836  return 0;
837  }
838  sc.function->GetEndLineSourceInfo(end_file, end_line);
839  } else {
840  // We have an inlined function
841  start_file = source_info.line_entry.file;
842  start_line = source_info.line_entry.line;
843  end_line = start_line + m_options.num_lines;
844  }
845 
846  // This is a little hacky, but the first line table entry for a function
847  // points to the "{" that starts the function block. It would be nice to
848  // actually get the function declaration in there too. So back up a bit,
849  // but not further than what you're going to display.
850  uint32_t extra_lines;
851  if (m_options.num_lines >= 10)
852  extra_lines = 5;
853  else
854  extra_lines = m_options.num_lines / 2;
855  uint32_t line_no;
856  if (start_line <= extra_lines)
857  line_no = 1;
858  else
859  line_no = start_line - extra_lines;
860 
861  // For fun, if the function is shorter than the number of lines we're
862  // supposed to display, only display the function...
863  if (end_line != 0) {
864  if (m_options.num_lines > end_line - line_no)
865  m_options.num_lines = end_line - line_no + extra_lines;
866  }
867 
868  m_breakpoint_locations.Clear();
869 
870  if (m_options.show_bp_locs) {
871  const bool show_inlines = true;
872  m_breakpoint_locations.Reset(start_file, 0, show_inlines);
873  SearchFilterForUnconstrainedSearches target_search_filter(
874  m_exe_ctx.GetTargetSP());
875  target_search_filter.Search(m_breakpoint_locations);
876  }
877 
878  result.AppendMessageWithFormat("File: %s\n",
879  start_file.GetPath().c_str());
880  // We don't care about the column here.
881  const uint32_t column = 0;
883  start_file, line_no, column, 0, m_options.num_lines, "",
884  &result.GetOutputStream(), GetBreakpointLocations());
885  } else {
886  result.AppendErrorWithFormat(
887  "Could not find function info for: \"%s\".\n",
888  m_options.symbol_name.c_str());
889  }
890  return 0;
891  }
892 
893  // From Jim: The FindMatchingFunctions / FindMatchingFunctionSymbols
894  // functions "take a possibly empty vector of strings which are names of
895  // modules, and run the two search functions on the subset of the full module
896  // list that matches the strings in the input vector". If we wanted to put
897  // these somewhere, there should probably be a module-filter-list that can be
898  // passed to the various ModuleList::Find* calls, which would either be a
899  // vector of string names or a ModuleSpecList.
901  SymbolContextList &sc_list) {
902  // Displaying the source for a symbol:
903  bool include_inlines = true;
904  bool append = true;
905  bool include_symbols = false;
906  size_t num_matches = 0;
907 
908  if (m_options.num_lines == 0)
909  m_options.num_lines = 10;
910 
911  const size_t num_modules = m_options.modules.size();
912  if (num_modules > 0) {
913  ModuleList matching_modules;
914  for (size_t i = 0; i < num_modules; ++i) {
915  FileSpec module_file_spec(m_options.modules[i]);
916  if (module_file_spec) {
917  ModuleSpec module_spec(module_file_spec);
918  matching_modules.Clear();
919  target->GetImages().FindModules(module_spec, matching_modules);
920  num_matches += matching_modules.FindFunctions(
921  name, eFunctionNameTypeAuto, include_symbols, include_inlines,
922  append, sc_list);
923  }
924  }
925  } else {
926  num_matches = target->GetImages().FindFunctions(
927  name, eFunctionNameTypeAuto, include_symbols, include_inlines, append,
928  sc_list);
929  }
930  return num_matches;
931  }
932 
934  SymbolContextList &sc_list) {
935  size_t num_matches = 0;
936  const size_t num_modules = m_options.modules.size();
937  if (num_modules > 0) {
938  ModuleList matching_modules;
939  for (size_t i = 0; i < num_modules; ++i) {
940  FileSpec module_file_spec(m_options.modules[i]);
941  if (module_file_spec) {
942  ModuleSpec module_spec(module_file_spec);
943  matching_modules.Clear();
944  target->GetImages().FindModules(module_spec, matching_modules);
945  num_matches += matching_modules.FindFunctionSymbols(
946  name, eFunctionNameTypeAuto, sc_list);
947  }
948  }
949  } else {
950  num_matches = target->GetImages().FindFunctionSymbols(
951  name, eFunctionNameTypeAuto, sc_list);
952  }
953  return num_matches;
954  }
955 
956  bool DoExecute(Args &command, CommandReturnObject &result) override {
957  const size_t argc = command.GetArgumentCount();
958 
959  if (argc != 0) {
960  result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n",
961  GetCommandName().str().c_str());
963  return false;
964  }
965 
966  Target *target = m_exe_ctx.GetTargetPtr();
967 
968  if (!m_options.symbol_name.empty()) {
969  SymbolContextList sc_list;
970  ConstString name(m_options.symbol_name.c_str());
971 
972  // Displaying the source for a symbol. Search for function named name.
973  size_t num_matches = FindMatchingFunctions(target, name, sc_list);
974  if (!num_matches) {
975  // If we didn't find any functions with that name, try searching for
976  // symbols that line up exactly with function addresses.
977  SymbolContextList sc_list_symbols;
978  size_t num_symbol_matches =
979  FindMatchingFunctionSymbols(target, name, sc_list_symbols);
980  for (size_t i = 0; i < num_symbol_matches; i++) {
981  SymbolContext sc;
982  sc_list_symbols.GetContextAtIndex(i, sc);
983  if (sc.symbol && sc.symbol->ValueIsAddress()) {
984  const Address &base_address = sc.symbol->GetAddressRef();
985  Function *function = base_address.CalculateSymbolContextFunction();
986  if (function) {
987  sc_list.Append(SymbolContext(function));
988  num_matches++;
989  break;
990  }
991  }
992  }
993  }
994 
995  if (num_matches == 0) {
996  result.AppendErrorWithFormat("Could not find function named: \"%s\".\n",
997  m_options.symbol_name.c_str());
999  return false;
1000  }
1001 
1002  if (num_matches > 1) {
1003  std::set<SourceInfo> source_match_set;
1004 
1005  bool displayed_something = false;
1006  for (size_t i = 0; i < num_matches; i++) {
1007  SymbolContext sc;
1008  sc_list.GetContextAtIndex(i, sc);
1009  SourceInfo source_info(sc.GetFunctionName(),
1011 
1012  if (source_info.IsValid()) {
1013  if (source_match_set.find(source_info) == source_match_set.end()) {
1014  source_match_set.insert(source_info);
1015  if (DisplayFunctionSource(sc, source_info, result))
1016  displayed_something = true;
1017  }
1018  }
1019  }
1020 
1021  if (displayed_something)
1023  else
1025  } else {
1026  SymbolContext sc;
1027  sc_list.GetContextAtIndex(0, sc);
1028  SourceInfo source_info;
1029 
1030  if (DisplayFunctionSource(sc, source_info, result)) {
1032  } else {
1034  }
1035  }
1036  return result.Succeeded();
1037  } else if (m_options.address != LLDB_INVALID_ADDRESS) {
1038  Address so_addr;
1039  StreamString error_strm;
1040  SymbolContextList sc_list;
1041 
1042  if (target->GetSectionLoadList().IsEmpty()) {
1043  // The target isn't loaded yet, we need to lookup the file address in
1044  // all modules
1045  const ModuleList &module_list = target->GetImages();
1046  const size_t num_modules = module_list.GetSize();
1047  for (size_t i = 0; i < num_modules; ++i) {
1048  ModuleSP module_sp(module_list.GetModuleAtIndex(i));
1049  if (module_sp &&
1050  module_sp->ResolveFileAddress(m_options.address, so_addr)) {
1051  SymbolContext sc;
1052  sc.Clear(true);
1053  if (module_sp->ResolveSymbolContextForAddress(
1054  so_addr, eSymbolContextEverything, sc) &
1055  eSymbolContextLineEntry)
1056  sc_list.Append(sc);
1057  }
1058  }
1059 
1060  if (sc_list.GetSize() == 0) {
1061  result.AppendErrorWithFormat(
1062  "no modules have source information for file address 0x%" PRIx64
1063  ".\n",
1064  m_options.address);
1066  return false;
1067  }
1068  } else {
1069  // The target has some things loaded, resolve this address to a compile
1070  // unit + file + line and display
1071  if (target->GetSectionLoadList().ResolveLoadAddress(m_options.address,
1072  so_addr)) {
1073  ModuleSP module_sp(so_addr.GetModule());
1074  if (module_sp) {
1075  SymbolContext sc;
1076  sc.Clear(true);
1077  if (module_sp->ResolveSymbolContextForAddress(
1078  so_addr, eSymbolContextEverything, sc) &
1079  eSymbolContextLineEntry) {
1080  sc_list.Append(sc);
1081  } else {
1082  so_addr.Dump(&error_strm, nullptr,
1083  Address::DumpStyleModuleWithFileAddress);
1084  result.AppendErrorWithFormat("address resolves to %s, but there "
1085  "is no line table information "
1086  "available for this address.\n",
1087  error_strm.GetData());
1089  return false;
1090  }
1091  }
1092  }
1093 
1094  if (sc_list.GetSize() == 0) {
1095  result.AppendErrorWithFormat(
1096  "no modules contain load address 0x%" PRIx64 ".\n",
1097  m_options.address);
1099  return false;
1100  }
1101  }
1102  uint32_t num_matches = sc_list.GetSize();
1103  for (uint32_t i = 0; i < num_matches; ++i) {
1104  SymbolContext sc;
1105  sc_list.GetContextAtIndex(i, sc);
1106  if (sc.comp_unit) {
1107  if (m_options.show_bp_locs) {
1108  m_breakpoint_locations.Clear();
1109  const bool show_inlines = true;
1110  m_breakpoint_locations.Reset(*sc.comp_unit, 0, show_inlines);
1111  SearchFilterForUnconstrainedSearches target_search_filter(
1112  target->shared_from_this());
1113  target_search_filter.Search(m_breakpoint_locations);
1114  }
1115 
1116  bool show_fullpaths = true;
1117  bool show_module = true;
1118  bool show_inlined_frames = true;
1119  const bool show_function_arguments = true;
1120  const bool show_function_name = true;
1121  sc.DumpStopContext(&result.GetOutputStream(),
1122  m_exe_ctx.GetBestExecutionContextScope(),
1124  show_fullpaths, show_module, show_inlined_frames,
1125  show_function_arguments, show_function_name);
1126  result.GetOutputStream().EOL();
1127 
1128  if (m_options.num_lines == 0)
1129  m_options.num_lines = 10;
1130 
1131  size_t lines_to_back_up =
1132  m_options.num_lines >= 10 ? 5 : m_options.num_lines / 2;
1133 
1134  const uint32_t column =
1135  (GetDebugger().GetStopShowColumn() != eStopShowColumnNone)
1136  ? sc.line_entry.column
1137  : 0;
1139  sc.comp_unit, sc.line_entry.line, column, lines_to_back_up,
1140  m_options.num_lines - lines_to_back_up, "->",
1141  &result.GetOutputStream(), GetBreakpointLocations());
1143  }
1144  }
1145  } else if (m_options.file_name.empty()) {
1146  // Last valid source manager context, or the current frame if no valid
1147  // last context in source manager. One little trick here, if you type the
1148  // exact same list command twice in a row, it is more likely because you
1149  // typed it once, then typed it again
1150  if (m_options.start_line == 0) {
1152  &result.GetOutputStream(), m_options.num_lines,
1153  m_options.reverse, GetBreakpointLocations())) {
1155  }
1156  } else {
1157  if (m_options.num_lines == 0)
1158  m_options.num_lines = 10;
1159 
1160  if (m_options.show_bp_locs) {
1161  SourceManager::FileSP last_file_sp(
1162  target->GetSourceManager().GetLastFile());
1163  if (last_file_sp) {
1164  const bool show_inlines = true;
1165  m_breakpoint_locations.Reset(last_file_sp->GetFileSpec(), 0,
1166  show_inlines);
1167  SearchFilterForUnconstrainedSearches target_search_filter(
1168  target->shared_from_this());
1169  target_search_filter.Search(m_breakpoint_locations);
1170  }
1171  } else
1172  m_breakpoint_locations.Clear();
1173 
1174  const uint32_t column = 0;
1175  if (target->GetSourceManager()
1177  m_options.start_line, // Line to display
1178  m_options.num_lines, // Lines after line to
1179  UINT32_MAX, // Don't mark "line"
1180  column,
1181  "", // Don't mark "line"
1182  &result.GetOutputStream(), GetBreakpointLocations())) {
1184  }
1185  }
1186  } else {
1187  const char *filename = m_options.file_name.c_str();
1188 
1189  bool check_inlines = false;
1190  SymbolContextList sc_list;
1191  size_t num_matches = 0;
1192 
1193  if (!m_options.modules.empty()) {
1194  ModuleList matching_modules;
1195  for (size_t i = 0, e = m_options.modules.size(); i < e; ++i) {
1196  FileSpec module_file_spec(m_options.modules[i]);
1197  if (module_file_spec) {
1198  ModuleSpec module_spec(module_file_spec);
1199  matching_modules.Clear();
1200  target->GetImages().FindModules(module_spec, matching_modules);
1201  num_matches += matching_modules.ResolveSymbolContextForFilePath(
1202  filename, 0, check_inlines,
1203  SymbolContextItem(eSymbolContextModule |
1204  eSymbolContextCompUnit),
1205  sc_list);
1206  }
1207  }
1208  } else {
1209  num_matches = target->GetImages().ResolveSymbolContextForFilePath(
1210  filename, 0, check_inlines,
1211  eSymbolContextModule | eSymbolContextCompUnit, sc_list);
1212  }
1213 
1214  if (num_matches == 0) {
1215  result.AppendErrorWithFormat("Could not find source file \"%s\".\n",
1216  m_options.file_name.c_str());
1218  return false;
1219  }
1220 
1221  if (num_matches > 1) {
1222  bool got_multiple = false;
1223  FileSpec *test_cu_spec = nullptr;
1224 
1225  for (unsigned i = 0; i < num_matches; i++) {
1226  SymbolContext sc;
1227  sc_list.GetContextAtIndex(i, sc);
1228  if (sc.comp_unit) {
1229  if (test_cu_spec) {
1230  if (test_cu_spec != static_cast<FileSpec *>(sc.comp_unit))
1231  got_multiple = true;
1232  break;
1233  } else
1234  test_cu_spec = sc.comp_unit;
1235  }
1236  }
1237  if (got_multiple) {
1238  result.AppendErrorWithFormat(
1239  "Multiple source files found matching: \"%s.\"\n",
1240  m_options.file_name.c_str());
1242  return false;
1243  }
1244  }
1245 
1246  SymbolContext sc;
1247  if (sc_list.GetContextAtIndex(0, sc)) {
1248  if (sc.comp_unit) {
1249  if (m_options.show_bp_locs) {
1250  const bool show_inlines = true;
1251  m_breakpoint_locations.Reset(*sc.comp_unit, 0, show_inlines);
1252  SearchFilterForUnconstrainedSearches target_search_filter(
1253  target->shared_from_this());
1254  target_search_filter.Search(m_breakpoint_locations);
1255  } else
1256  m_breakpoint_locations.Clear();
1257 
1258  if (m_options.num_lines == 0)
1259  m_options.num_lines = 10;
1260  const uint32_t column = 0;
1262  sc.comp_unit, m_options.start_line, column,
1263  0, m_options.num_lines,
1264  "", &result.GetOutputStream(), GetBreakpointLocations());
1265 
1267  } else {
1268  result.AppendErrorWithFormat("No comp unit found for: \"%s.\"\n",
1269  m_options.file_name.c_str());
1271  return false;
1272  }
1273  }
1274  }
1275  return result.Succeeded();
1276  }
1277 
1279  if (m_breakpoint_locations.GetFileLineMatches().GetSize() > 0)
1280  return &m_breakpoint_locations.GetFileLineMatches();
1281  return nullptr;
1282  }
1283 
1284  CommandOptions m_options;
1286  std::string m_reverse_name;
1287 };
1288 
1289 #pragma mark CommandObjectMultiwordSource
1290 // CommandObjectMultiwordSource
1291 
1292 CommandObjectMultiwordSource::CommandObjectMultiwordSource(
1293  CommandInterpreter &interpreter)
1294  : CommandObjectMultiword(interpreter, "source", "Commands for examining "
1295  "source code described by "
1296  "debug information for the "
1297  "current target process.",
1298  "source <subcommand> [<subcommand-options>]") {
1299  LoadSubCommand("info",
1300  CommandObjectSP(new CommandObjectSourceInfo(interpreter)));
1301  LoadSubCommand("list",
1302  CommandObjectSP(new CommandObjectSourceList(interpreter)));
1303 }
1304 
Address & GetAddressRef()
Definition: Symbol.h:56
uint32_t FindLineEntry(uint32_t start_idx, uint32_t line, const FileSpec *file_spec_ptr, bool exact, LineEntry *line_entry)
Find the line entry by line and optional inlined file spec.
ConstString & GetFilename()
Filename string get accessor.
Definition: FileSpec.cpp:369
A line table entry class.
Definition: LineEntry.h:20
CommandObjectSourceInfo(CommandInterpreter &interpreter)
A command line argument class.
Definition: Args.h:32
ConstString GetFunctionName(Mangled::NamePreference preference=Mangled::ePreferDemangled) const
Find a name of the innermost function for the symbol context.
Function * CalculateSymbolContextFunction() const
Definition: Address.cpp:822
Defines a list of symbol context objects.
void GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no)
Find the file and line number of the source location of the end of the function.
Definition: Function.cpp:222
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function)
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
Definition: AddressRange.h:232
bool DumpLinesForFile(CommandReturnObject &result)
const ArchSpec & GetArchitecture() const
Definition: Target.h:941
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:224
void Clear()
Clear the object&#39;s state.
Definition: ModuleList.cpp:304
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t GetSymbolContextsForAddress(const ModuleList &module_list, lldb::addr_t addr, SymbolContextList &sc_list, StreamString &error_strm)
FileSpec original_file
The original source file, from debug info.
Definition: LineEntry.h:153
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition: Module.h:531
bool DumpLinesForAddress(CommandReturnObject &result)
void SetAddressByteSize(uint32_t addr_size)
Set the address size in bytes.
Definition: Stream.cpp:232
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
size_t FindMatchingFunctionSymbols(Target *target, ConstString name, SymbolContextList &sc_list)
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:742
size_t FindMatchingFunctions(Target *target, ConstString name, SymbolContextList &sc_list)
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
const_iterator end() const
Definition: Args.h:129
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:292
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
bool IsValid() const
Check if a line entry object is valid.
Definition: LineEntry.cpp:47
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition: Args.cpp:254
bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr, bool show_fullpaths, bool show_module, bool show_inlined_frames, bool show_function_arguments, bool show_function_name) const
Dump the stop context in this object to a Stream.
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX) const
Dump a description of this object to a Stream.
Definition: Address.cpp:374
A file utility class.
Definition: FileSpec.h:55
A class that describes a function.
Definition: Function.h:323
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:272
CompileUnit * comp_unit
The CompileUnit for a given query.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
llvm::StringRef ref
Definition: Args.h:45
size_t GetIndexForModule(const Module *module) const
Definition: ModuleList.cpp:706
const char * GetData() const
Definition: StreamString.h:43
Symbol * symbol
The Symbol for a given query.
A class that describes a compilation unit.
Definition: CompileUnit.h:35
"lldb/Core/SearchFilter.h" This is a SearchFilter that searches through all modules.
Definition: SearchFilter.h:301
uint32_t GetSize() const
Get accessor for a symbol context list size.
bool operator!=(const SourceInfo &rhs) const
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame&#39;s current pc value.
Definition: StackFrame.cpp:267
SourceInfo(ConstString name, const LineEntry &line_entry)
#define LLDB_OPT_SET_3
Definition: lldb-defines.h:113
Function * function
The Function for a given query.
uint32_t DumpFileLinesInModule(Stream &strm, Module *module, const FileSpec &file_spec)
#define UINT32_MAX
Definition: lldb-defines.h:31
SourceManager & GetSourceManager()
Definition: Target.cpp:2482
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:86
Options * GetOptions() override
uint32_t DumpFileLinesInCompUnit(Stream &strm, Module *module, CompileUnit *cu, const FileSpec &file_spec)
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
Definition: ModuleList.cpp:326
FileLineResolver m_breakpoint_locations
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectSourceList(CommandInterpreter &interpreter)
void Clear(bool clear_target)
Clear the object&#39;s state.
A collection class for Module objects.
Definition: ModuleList.h:91
uint16_t column
The column number of the source line, or zero if there is no column information.
Definition: LineEntry.h:156
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:127
SectionLoadList & GetSectionLoadList()
Definition: Target.h:1012
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:109
virtual void Search(Searcher &searcher)
Call this method to do the search using the Searcher.
void GetStartLineSourceInfo(FileSpec &source_file, uint32_t &line_no)
Find the file and line number of the source location of the start of the function.
Definition: Function.cpp:194
void Clear()
Clear the object state.
Definition: Status.cpp:167
void AppendMessageWithFormat(const char *format,...) __attribute__((format(printf
LineEntry GetFunctionStartLineEntry() const
Get the line entry that corresponds to the function.
bool DumpLinesInFunctions(CommandReturnObject &result)
static constexpr OptionDefinition g_source_list_options[]
size_t DisplaySourceLinesWithLineNumbers(const FileSpec &file, uint32_t line, uint32_t column, uint32_t context_before, uint32_t context_after, const char *current_line_cstr, Stream *s, const SymbolContextList *bp_locs=nullptr)
static constexpr OptionDefinition g_source_info_options[]
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, bool allow_section_end=false) const
FileSpec file
The source file, possibly mapped by the target.source-map setting.
Definition: LineEntry.h:151
uint32_t ResolveSymbolContextForFilePath(const char *file_path, uint32_t line, bool check_inlines, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const
Resolve items in the symbol context for a given file and line. (const char
Definition: ModuleList.cpp:685
uint32_t line
The source line number, or zero if there is no line number information.
Definition: LineEntry.h:154
bool ValueIsAddress() const
Definition: Symbol.cpp:114
FileSpecList & GetSupportFiles()
Get the compile unit&#39;s support file list.
#define LLDB_OPT_SET_4
Definition: lldb-defines.h:114
size_t DisplayMoreWithLineNumbers(Stream *s, uint32_t count, bool reverse, const SymbolContextList *bp_locs=nullptr)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
size_t FindFunctionSymbols(ConstString name, lldb::FunctionNameType name_type_mask, SymbolContextList &sc_list)
Definition: ModuleList.cpp:374
A section + offset based address class.
Definition: Address.h:80
std::vector< std::string > STLStringArray
Definition: STLUtils.h:71
size_t DisplaySourceLinesWithLineNumbersUsingLastFile(uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column, const char *current_line_cstr, Stream *s, const SymbolContextList *bp_locs=nullptr)
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
#define LLDB_OPT_SET_2
Definition: lldb-defines.h:112
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:899
A command line option parsing protocol class.
Definition: Options.h:62
ConstString & GetDirectory()
Directory string get accessor.
Definition: FileSpec.cpp:363
void void AppendError(llvm::StringRef in_string)
uint64_t addr_t
Definition: lldb-types.h:83
size_t GetSize() const
Gets the size of the module list.
Definition: ModuleList.cpp:611
A uniqued constant string class.
Definition: ConstString.h:38
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition: Address.cpp:264
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:247
This class finds address for source file and line.
Options * GetOptions() override
bool DumpLinesForFrame(CommandReturnObject &result)
static bool Equal(const FileSpec &a, const FileSpec &b, bool full)
Definition: FileSpec.cpp:319
lldb::ModuleSP module_sp
The Module for a given query.
LineEntry line_entry
The LineEntry for a given query.
Definition: SBAddress.h:15
std::shared_ptr< File > FileSP
bool operator<(const SourceInfo &rhs) const
size_t DisplayFunctionSource(const SymbolContext &sc, SourceInfo &source_info, CommandReturnObject &result)
bool GetAddressRange(uint32_t scope, uint32_t range_idx, bool use_inline_block_range, AddressRange &range) const
Get the address range contained within a symbol context.
uint32_t DumpLinesInSymbolContexts(Stream &strm, const SymbolContextList &sc_list, const ModuleList &module_list, const FileSpec &file_spec)
bool DoExecute(Args &command, CommandReturnObject &result) override
#define LLDB_OPT_SET_ALL
Definition: lldb-defines.h:110
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:220
const char * GetRepeatCommand(Args &current_command_args, uint32_t index) override
Get the command that appropriate for a "repeat" of the current command.
Module * GetModulePointerAtIndex(size_t idx) const
Get the module pointer for the module at index idx.
Definition: ModuleList.cpp:315
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
size_t FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask, bool include_symbols, bool include_inlines, bool append, SymbolContextList &sc_list) const
size_t FindModules(const ModuleSpec &module_spec, ModuleList &matching_module_list) const
Finds the first module whose file specification matches file_spec.
Definition: ModuleList.cpp:486
bool HasDebugInformation()
Determine whether this StackFrame has debug information available or not.
#define LLDB_OPT_SET_1
Definition: lldb-defines.h:111
void AppendWarningWithFormat(const char *format,...) __attribute__((format(printf
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:376
Block * block
The Block for a given query.
A section + offset based address range class.
Definition: AddressRange.h:32
lldb::CompUnitSP GetCompileUnitAtIndex(size_t idx)
Definition: Module.cpp:413
void SetStatus(lldb::ReturnStatus status)
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
const SymbolContextList * GetBreakpointLocations()
AddressRange range
The section offset address range for this line entry.
Definition: LineEntry.h:150
bool GetDescription(Stream *s, lldb::DescriptionLevel level, CompileUnit *cu, Target *target, bool show_address_only) const
Definition: LineEntry.cpp:106
bool operator==(const SourceInfo &rhs) const
An error handling class.
Definition: Status.h:44
size_t GetNumCompileUnits()
Get the number of compile units for this module.
Definition: Module.cpp:402