Wrapped up the work I am going to do for now for the "add-dsym" or "target symfile add" command.
We can now do:
Specify a path to a debug symbols file:
(lldb) add-dsym <path-to-dsym>
Go and download the dSYM file for the "libunc.dylib" module in your target:
(lldb) add-dsym --shlib libunc.dylib
Go and download the dSYM given a UUID:
(lldb) add-dsym --uuid <UUID>
Go and download the dSYM file for the current frame:
(lldb) add-dsym --frame
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@164806 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index c1e6486..226c00f 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -451,7 +451,7 @@
NULL,
0),
m_option_group (interpreter),
- m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', 0, eArgTypeNone, "Perform extra cleanup to minimize memory consumption after deleting the target.", false)
+ m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', "Perform extra cleanup to minimize memory consumption after deleting the target.", false, false)
{
m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Finalize();
@@ -3984,9 +3984,17 @@
CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"target symbols add",
- "Add a debug symbol file to one of the target's current modules.",
- "target symbols add [<symfile>]")
+ "Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for.",
+ "target symbols add [<symfile>]"),
+ m_option_group (interpreter),
+ m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
+ m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
+
{
+ m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
+ m_option_group.Finalize();
}
virtual
@@ -4018,152 +4026,260 @@
return matches.GetSize();
}
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_option_group;
+ }
+
+
protected:
+
+ bool
+ AddModuleSymbols (Target *target,
+ const FileSpec &symfile_spec,
+ bool &flush,
+ CommandReturnObject &result)
+ {
+ ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture()));
+ const UUID &symfile_uuid = symfile_module_sp->GetUUID();
+ StreamString ss_symfile_uuid;
+ symfile_uuid.Dump(&ss_symfile_uuid);
+
+ if (symfile_module_sp)
+ {
+ char symfile_path[PATH_MAX];
+ symfile_spec.GetPath (symfile_path, sizeof(symfile_path));
+ // We now have a module that represents a symbol file
+ // that can be used for a module that might exist in the
+ // current target, so we need to find that module in the
+ // target
+
+ ModuleSP old_module_sp (target->GetImages().FindModule (symfile_uuid));
+ if (old_module_sp)
+ {
+ // The module has not yet created its symbol vendor, we can just
+ // give the existing target module the symfile path to use for
+ // when it decides to create it!
+ old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec());
+
+ // Provide feedback that the symfile has been successfully added.
+ const FileSpec &module_fs = old_module_sp->GetFileSpec();
+ result.AppendMessageWithFormat("symbol file '%s' with UUID %s has been successfully added to the '%s/%s' module\n",
+ symfile_path, ss_symfile_uuid.GetData(),
+ module_fs.GetDirectory().AsCString(), module_fs.GetFilename().AsCString());
+
+ // Let clients know something changed in the module
+ // if it is currently loaded
+ ModuleList module_list;
+ module_list.Append (old_module_sp);
+ target->ModulesDidLoad (module_list);
+ flush = true;
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("symbol file '%s' with UUID %s does not match any existing module%s\n",
+ symfile_path, ss_symfile_uuid.GetData(),
+ (symfile_spec.GetFileType() != FileSpec::eFileTypeRegular)
+ ? "\n please specify the full path to the symbol file"
+ : "");
+ return false;
+ }
+ }
+ else
+ {
+ result.AppendError ("one or more executable image paths must be specified");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ return true;
+ }
+
virtual bool
DoExecute (Args& args,
CommandReturnObject &result)
{
ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
Target *target = exe_ctx.GetTargetPtr();
+ result.SetStatus (eReturnStatusFailed);
if (target == NULL)
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
}
else
{
bool flush = false;
+ ModuleSpec sym_spec;
+ const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
+ const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
+ const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
+
const size_t argc = args.GetArgumentCount();
if (argc == 0)
{
- result.AppendError ("one or more symbol file paths must be specified");
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- PlatformSP platform_sp (target->GetPlatform());
-
- for (size_t i=0; i<argc; ++i)
+ if (uuid_option_set || file_option_set || frame_option_set)
{
- const char *symfile_path = args.GetArgumentAtIndex(i);
- if (symfile_path)
+ bool success = false;
+ bool error_set = false;
+ if (frame_option_set)
{
- ModuleSpec sym_spec;
- FileSpec symfile_spec;
- sym_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
- if (platform_sp)
- platform_sp->ResolveSymbolFile(*target, sym_spec, symfile_spec);
- else
- symfile_spec.SetFile(symfile_path, true);
-
- ArchSpec arch;
- bool symfile_exists = symfile_spec.Exists();
- // The code below was testing the new "Symbols::DownloadObjectAndSymbolFile"
- // functionality. Now that it works on MacOSX, it will be enabled soon with
- // option values (like "--uuid <UUID>" or "--file <module>", or "--frame"
- // for the current stack frame's module). So it is commented out for now.
-// if (!symfile_exists)
-// {
-// if (sym_spec.GetUUID().SetfromCString(symfile_path))
-// {
-// // A UUID was specified, look it up via UUID
-// if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
-// {
-//// printf ("UUID: %s\n", symfile_path);
-//// printf ("objfile_spec: %s/%s\n",
-//// sym_spec.GetFileSpec().GetDirectory().GetCString(),
-//// sym_spec.GetFileSpec().GetFilename().GetCString());
-//// printf ("symfile_spec: %s/%s\n",
-//// sym_spec.GetSymbolFileSpec().GetDirectory().GetCString(),
-//// sym_spec.GetSymbolFileSpec().GetFilename().GetCString());
-// symfile_spec = sym_spec.GetSymbolFileSpec();
-// symfile_exists = symfile_spec.Exists();
-// }
-// }
-// }
-
- if (symfile_exists)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process)
{
- ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture()));
- const UUID &symfile_uuid = symfile_module_sp->GetUUID();
- StreamString ss_symfile_uuid;
- symfile_uuid.Dump(&ss_symfile_uuid);
-
- if (symfile_module_sp)
+ const StateType process_state = process->GetState();
+ if (StateIsStoppedState (process_state, true))
{
- // We now have a module that represents a symbol file
- // that can be used for a module that might exist in the
- // current target, so we need to find that module in the
- // target
-
- ModuleSP old_module_sp (target->GetImages().FindModule (symfile_uuid));
- if (old_module_sp)
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (frame)
{
- // The module has not yet created its symbol vendor, we can just
- // give the existing target module the symfile path to use for
- // when it decides to create it!
- old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec());
-
- // Provide feedback that the symfile has been successfully added.
- const FileSpec &module_fs = old_module_sp->GetFileSpec();
- result.AppendMessageWithFormat("symbol file '%s' with UUID %s has been successfully added to the '%s/%s' module\n",
- symfile_path, ss_symfile_uuid.GetData(),
- module_fs.GetDirectory().AsCString(), module_fs.GetFilename().AsCString());
-
- // Let clients know something changed in the module
- // if it is currently loaded
- ModuleList module_list;
- module_list.Append (old_module_sp);
- target->ModulesDidLoad (module_list);
- flush = true;
+ ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
+ if (frame_module_sp)
+ {
+ if (frame_module_sp->GetPlatformFileSpec().Exists())
+ {
+ sym_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
+ sym_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
+ }
+ sym_spec.GetUUID() = frame_module_sp->GetUUID();
+ success = sym_spec.GetUUID().IsValid() || sym_spec.GetFileSpec();
+ }
+ else
+ {
+ result.AppendError ("frame has no module");
+ error_set = true;
+ }
}
else
{
- result.AppendErrorWithFormat ("symbol file '%s' with UUID %s does not match any existing module%s\n",
- symfile_path, ss_symfile_uuid.GetData(),
- (symfile_spec.GetFileType() != FileSpec::eFileTypeRegular)
- ? "\n please specify the full path to the symbol file"
- : "");
- break;
+ result.AppendError ("invalid current frame");
+ error_set = true;
}
}
else
{
- result.AppendError ("one or more executable image paths must be specified");
- result.SetStatus (eReturnStatusFailed);
- break;
+ result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
+ error_set = true;
}
- result.SetStatus (eReturnStatusSuccessFinishResult);
}
else
{
-// sym_spec.GetSymbolFileSpec().Clear();
-// if (sym_spec.GetUUID().SetfromCString(symfile_path))
-// {
-// if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
-// {
-// printf ("UUID: %s\n", symfile_path);
-// printf ("objfile_spec: %s/%s\n",
-// sym_spec.GetFileSpec().GetDirectory().GetCString(),
-// sym_spec.GetFileSpec().GetFilename().GetCString());
-// printf ("symfile_spec: %s/%s\n",
-// sym_spec.GetSymbolFileSpec().GetDirectory().GetCString(),
-// sym_spec.GetSymbolFileSpec().GetFilename().GetCString());
-// }
-// }
-
- char resolved_symfile_path[PATH_MAX];
- result.SetStatus (eReturnStatusFailed);
- if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
+ result.AppendError ("a process must exist in order to use the --frame option");
+ error_set = true;
+ }
+ }
+ else
+ {
+ if (uuid_option_set)
+ {
+ sym_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
+ success |= sym_spec.GetUUID().IsValid();
+ }
+ else if (file_option_set)
+ {
+ sym_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
+ ModuleSP module_sp (target->GetImages().FindFirstModule(sym_spec));
+ if (module_sp)
{
- if (strcmp (resolved_symfile_path, symfile_path) != 0)
- {
- result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
- break;
- }
+ sym_spec.GetFileSpec() = module_sp->GetFileSpec();
+ sym_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
+ sym_spec.GetUUID() = module_sp->GetUUID();
+ sym_spec.GetArchitecture() = module_sp->GetArchitecture();
}
- result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
- break;
+ else
+ {
+ sym_spec.GetArchitecture() = target->GetArchitecture();
+ }
+ success |= sym_spec.GetFileSpec().Exists();
+ }
+ }
+
+ if (success)
+ {
+ if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
+ {
+ if (sym_spec.GetSymbolFileSpec())
+ success = AddModuleSymbols (target, sym_spec.GetSymbolFileSpec(), flush, result);
+ }
+ }
+
+ if (!success && !error_set)
+ {
+ StreamString error_strm;
+ if (uuid_option_set)
+ {
+ error_strm.PutCString("unable to find debug symbols for UUID ");
+ sym_spec.GetUUID().Dump (&error_strm);
+ }
+ else if (file_option_set)
+ {
+ error_strm.PutCString("unable to find debug symbols for the executable file ");
+ error_strm << sym_spec.GetFileSpec();
+ }
+ else if (frame_option_set)
+ {
+ error_strm.PutCString("unable to find debug symbols for the current frame");
+ }
+ result.AppendError (error_strm.GetData());
+ }
+ }
+ else
+ {
+ result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
+ }
+ }
+ else
+ {
+ if (uuid_option_set)
+ {
+ result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
+ }
+ else if (file_option_set)
+ {
+ result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
+ }
+ else if (frame_option_set)
+ {
+ result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
+ }
+ else
+ {
+ PlatformSP platform_sp (target->GetPlatform());
+
+ for (size_t i=0; i<argc; ++i)
+ {
+ const char *symfile_path = args.GetArgumentAtIndex(i);
+ if (symfile_path)
+ {
+ FileSpec symfile_spec;
+ sym_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
+ if (platform_sp)
+ platform_sp->ResolveSymbolFile(*target, sym_spec, symfile_spec);
+ else
+ symfile_spec.SetFile(symfile_path, true);
+
+ ArchSpec arch;
+ bool symfile_exists = symfile_spec.Exists();
+
+ if (symfile_exists)
+ {
+ if (!AddModuleSymbols (target, symfile_spec, flush, result))
+ break;
+ }
+ else
+ {
+ char resolved_symfile_path[PATH_MAX];
+ if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
+ {
+ if (strcmp (resolved_symfile_path, symfile_path) != 0)
+ {
+ result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
+ break;
+ }
+ }
+ result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
+ break;
+ }
}
}
}
@@ -4179,6 +4295,12 @@
return result.Succeeded();
}
+ OptionGroupOptions m_option_group;
+ OptionGroupUUID m_uuid_option_group;
+ OptionGroupFile m_file_option;
+ OptionGroupBoolean m_current_frame_option;
+
+
};