summaryrefslogtreecommitdiffstats
path: root/lldb/source/Commands
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2010-08-20 01:17:07 +0000
committerJim Ingham <jingham@apple.com>2010-08-20 01:17:07 +0000
commit5466e751f0c911815fe62684164667bd659f60d2 (patch)
treecef37c06f9a2dcb35182f7498b6ae7ebe06b623d /lldb/source/Commands
parent64b931c1e1490e6cca2b3020c1c97f4ec622df0e (diff)
downloadbcm5719-llvm-5466e751f0c911815fe62684164667bd659f60d2.tar.gz
bcm5719-llvm-5466e751f0c911815fe62684164667bd659f60d2.zip
Added "source list -n" so you can list by symbol name. Moved "--count" from "-n" to "-c". Added a -s option so you can restrict the source listing to a particular shared library.
llvm-svn: 111608
Diffstat (limited to 'lldb/source/Commands')
-rw-r--r--lldb/source/Commands/CommandObjectSource.cpp269
1 files changed, 247 insertions, 22 deletions
diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp
index 2fd0f9c7b28..d905bcb0756 100644
--- a/lldb/source/Commands/CommandObjectSource.cpp
+++ b/lldb/source/Commands/CommandObjectSource.cpp
@@ -172,7 +172,7 @@ class CommandObjectSourceList : public CommandObject
error.SetErrorStringWithFormat("Invalid line number: '%s'.\n", option_arg);
break;
- case 'n':
+ case 'c':
num_lines = Args::StringToUInt32 (option_arg, 0);
if (num_lines == 0)
error.SetErrorStringWithFormat("Invalid line count: '%s'.\n", option_arg);
@@ -181,7 +181,14 @@ class CommandObjectSourceList : public CommandObject
case 'f':
file_name = option_arg;
break;
+
+ case 'n':
+ symbol_name = option_arg;
+ break;
+ case 's':
+ m_modules.push_back (std::string (option_arg));
+ break;
default:
error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option);
break;
@@ -197,8 +204,10 @@ class CommandObjectSourceList : public CommandObject
file_spec.Clear();
file_name.clear();
+ symbol_name.clear();
start_line = 0;
num_lines = 10;
+ m_modules.clear();
}
const lldb::OptionDefinition*
@@ -211,9 +220,10 @@ class CommandObjectSourceList : public CommandObject
// Instance variables to hold the values for command options.
FileSpec file_spec;
std::string file_name;
+ std::string symbol_name;
uint32_t start_line;
uint32_t num_lines;
-
+ STLStringArray m_modules;
};
public:
@@ -253,7 +263,155 @@ public:
}
ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
- if (m_options.file_name.empty())
+
+ if (!m_options.symbol_name.empty())
+ {
+ // Displaying the source for a symbol:
+ Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
+ if (target == NULL)
+ {
+ result.AppendError ("invalid target, set executable file using 'file' command");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ SymbolContextList sc_list;
+ ConstString name(m_options.symbol_name.c_str());
+ bool append = true;
+ size_t num_matches = 0;
+
+ if (m_options.m_modules.size() > 0)
+ {
+ ModuleList matching_modules;
+ for (int i = 0; i < m_options.m_modules.size(); i++)
+ {
+ FileSpec module_spec(m_options.m_modules[i].c_str());
+ if (module_spec)
+ {
+ matching_modules.Clear();
+ target->GetImages().FindModules (&module_spec, NULL, NULL, NULL, matching_modules);
+ num_matches += matching_modules.FindFunctions (name, eFunctionNameTypeBase, append, sc_list);
+ }
+ }
+ }
+ else
+ {
+ num_matches = target->GetImages().FindFunctions (name, eFunctionNameTypeBase, append, sc_list);
+ }
+
+ SymbolContext sc;
+
+ if (num_matches == 0)
+ {
+ result.AppendErrorWithFormat("Could not find function named: \"%s\".\n", m_options.symbol_name.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ sc_list.GetContextAtIndex (0, sc);
+ FileSpec start_file;
+ uint32_t start_line;
+ uint32_t end_line;
+ FileSpec end_file;
+ if (sc.function != NULL)
+ {
+ sc.function->GetStartLineSourceInfo (start_file, start_line);
+ if (start_line == 0)
+ {
+ result.AppendErrorWithFormat("Could not find line information for start of function: \"%s\".\n", m_options.symbol_name.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ sc.function->GetEndLineSourceInfo (end_file, end_line);
+ }
+ else
+ {
+ result.AppendErrorWithFormat("Could not find function info for: \"%s\".\n", m_options.symbol_name.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ if (num_matches > 1)
+ {
+ // This could either be because there are multiple functions of this name, in which case
+ // we'll have to specify this further... Or it could be because there are multiple inlined instances
+ // of one function. So run through the matches and if they all have the same file & line then we can just
+ // list one.
+
+ bool found_multiple = false;
+
+ for (size_t i = 1; i < num_matches; i++)
+ {
+ SymbolContext scratch_sc;
+ sc_list.GetContextAtIndex (i, scratch_sc);
+ if (scratch_sc.function != NULL)
+ {
+ FileSpec scratch_file;
+ uint32_t scratch_line;
+ scratch_sc.function->GetStartLineSourceInfo (scratch_file, scratch_line);
+ if (scratch_file != start_file
+ || scratch_line != start_line)
+ {
+ found_multiple = true;
+ break;
+ }
+ }
+ }
+ if (found_multiple)
+ {
+ StreamString s;
+ for (size_t i = 0; i < num_matches; i++)
+ {
+ SymbolContext scratch_sc;
+ sc_list.GetContextAtIndex (i, scratch_sc);
+ if (scratch_sc.function != NULL)
+ {
+ s.Printf("\n%d: ", i);
+ scratch_sc.function->Dump (&s, true);
+ }
+ }
+ result.AppendErrorWithFormat("Multiple functions found matching: %s: \n%s\n",
+ m_options.symbol_name.c_str(),
+ s.GetData());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+
+
+ // This is a little hacky, but the first line table entry for a function points to the "{" that
+ // starts the function block. It would be nice to actually get the function
+ // declaration in there too. So back up a bit, but not further than what you're going to display.
+ size_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2;
+ uint32_t line_no;
+ if (start_line <= lines_to_back_up)
+ line_no = 1;
+ else
+ line_no = start_line - lines_to_back_up;
+
+ // For fun, if the function is shorter than the number of lines we're supposed to display,
+ // only display the function...
+ if (end_line != 0)
+ {
+ if (m_options.num_lines > end_line - line_no)
+ m_options.num_lines = end_line - line_no;
+ }
+
+ char path_buf[PATH_MAX+1];
+ start_file.GetPath(path_buf, PATH_MAX);
+ result.AppendMessageWithFormat("File: %s.\n", path_buf);
+ interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (start_file,
+ line_no,
+ 0,
+ m_options.num_lines,
+ "",
+ &result.GetOutputStream());
+
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ return true;
+
+ }
+ else if (m_options.file_name.empty())
{
// Last valid source manager context, or the current frame if no
// valid last context in source manager.
@@ -294,32 +452,96 @@ public:
bool check_inlines = false;
SymbolContextList sc_list;
- size_t num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename,
- 0,
- check_inlines,
- eSymbolContextModule | eSymbolContextCompUnit,
- sc_list);
- if (num_matches > 0)
+ size_t num_matches = 0;
+
+ if (m_options.m_modules.size() > 0)
+ {
+ ModuleList matching_modules;
+ for (int i = 0; i < m_options.m_modules.size(); i++)
+ {
+ FileSpec module_spec(m_options.m_modules[i].c_str());
+ if (module_spec)
+ {
+ matching_modules.Clear();
+ target->GetImages().FindModules (&module_spec, NULL, NULL, NULL, matching_modules);
+ num_matches += matching_modules.ResolveSymbolContextForFilePath (filename,
+ 0,
+ check_inlines,
+ eSymbolContextModule | eSymbolContextCompUnit,
+ sc_list);
+ }
+ }
+ }
+ else
+ {
+ num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename,
+ 0,
+ check_inlines,
+ eSymbolContextModule | eSymbolContextCompUnit,
+ sc_list);
+ }
+
+ if (num_matches == 0)
+ {
+ result.AppendErrorWithFormat("Could not find source file \"%s\".\n",
+ m_options.file_name.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ if (num_matches > 1)
{
SymbolContext sc;
- if (sc_list.GetContextAtIndex(0, sc))
+ bool got_multiple = false;
+ FileSpec *test_cu_spec = NULL;
+
+ for (int i = 0; i < num_matches; i++)
{
+ sc_list.GetContextAtIndex(i, sc);
if (sc.comp_unit)
{
- interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
- m_options.start_line, // Line to display
- 0, // Lines before line to display
- m_options.num_lines, // Lines after line to display
- "", // Don't mark "line"
- &result.GetOutputStream());
-
- result.SetStatus (eReturnStatusSuccessFinishResult);
-
+ if (test_cu_spec)
+ {
+ if (test_cu_spec != static_cast<FileSpec *> (sc.comp_unit))
+ got_multiple = true;
+ break;
+ }
+ else
+ test_cu_spec = sc.comp_unit;
}
}
+ if (got_multiple)
+ {
+ result.AppendErrorWithFormat("Multiple source files found matching: \"%s.\"\n",
+ m_options.file_name.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(0, sc))
+ {
+ if (sc.comp_unit)
+ {
+ interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
+ m_options.start_line,
+ 0,
+ m_options.num_lines,
+ "",
+ &result.GetOutputStream());
+
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ result.AppendErrorWithFormat("No comp unit found for: \"%s.\"\n",
+ m_options.file_name.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
}
}
-
return result.Succeeded();
}
@@ -336,9 +558,12 @@ protected:
lldb::OptionDefinition
CommandObjectSourceList::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, "<line>", "The line number at which to start the display source."},
+{ LLDB_OPT_SET_ALL, false, "count", 'c', required_argument, NULL, 0, "<count>", "The number of source lines to display."},
+{ LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
+ "Look up the source file in the given shared library."},
{ LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<file>", "The file from which to display source."},
-{ LLDB_OPT_SET_1, false, "count", 'n', required_argument, NULL, 0, "<count>", "The number of source lines to display."},
+{ LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, "<line>", "The line number at which to start the display source."},
+{ LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<symbol>", "The name of a function whose source to display."},
{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
};
OpenPOWER on IntegriCloud